Skip to content

Commit db2567c

Browse files
committed
Rebase and improve type checking by ensuring comparator is a function
1 parent 95f7575 commit db2567c

File tree

2 files changed

+40
-39
lines changed

2 files changed

+40
-39
lines changed

src/lib/select/select.spec.ts

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,34 +2433,27 @@ describe('MdSelect', () => {
24332433
beforeEach(async(() => {
24342434
fixture = TestBed.createComponent(NgModelCompareWithSelect);
24352435
instance = fixture.componentInstance;
2436-
spyOn(instance, 'compareByReference').and.callThrough();
24372436
fixture.detectChanges();
24382437
}));
24392438

2440-
const testCompareByReferenceBehavior = () => {
2441-
it('should initialize with no selection despite having a value', () => {
2442-
expect(instance.selectedFood.value).toBe('pizza-1');
2443-
expect(instance.select.selected).toBeUndefined();
2444-
});
2445-
2446-
it('should not update the selection when changing the value', async(() => {
2447-
instance.options.first._selectViaInteraction();
2448-
fixture.detectChanges();
2449-
fixture.whenStable().then(() => {
2450-
expect(instance.selectedFood.value).toEqual('steak-0');
2451-
expect(instance.select.selected).toBeUndefined();
2452-
});
2453-
}));
2454-
};
2455-
2456-
it('should not use the comparator', () => {
2457-
expect(instance.compareByReference).not.toHaveBeenCalled();
2439+
it('should have a selection', () => {
2440+
const selectedOption = instance.select.selected as MdOption;
2441+
expect(selectedOption.value.value).toEqual('pizza-1');
24582442
});
24592443

2460-
testCompareByReferenceBehavior();
2444+
it('should update when making a new selection', async(() => {
2445+
instance.options.last._selectViaInteraction();
2446+
fixture.detectChanges();
2447+
fixture.whenStable().then(() => {
2448+
const selectedOption = instance.select.selected as MdOption;
2449+
expect(instance.selectedFood.value).toEqual('tacos-2');
2450+
expect(selectedOption.value.value).toEqual('tacos-2');
2451+
});
2452+
}));
24612453

24622454
describe('when comparing by reference', () => {
24632455
beforeEach(async(() => {
2456+
spyOn(instance, 'compareByReference').and.callThrough();
24642457
instance.useCompareByReference();
24652458
fixture.detectChanges();
24662459
}));
@@ -2469,30 +2462,32 @@ describe('MdSelect', () => {
24692462
expect(instance.compareByReference).toHaveBeenCalled();
24702463
});
24712464

2472-
testCompareByReferenceBehavior();
2473-
});
2474-
2475-
describe('when comparing by value', () => {
2476-
beforeEach(async(() => {
2477-
instance.useCompareByValue();
2478-
fixture.detectChanges();
2479-
}));
2480-
2481-
it('should have a selection', () => {
2482-
const selectedOption = instance.select.selected as MdOption;
2483-
expect(selectedOption.value.value).toEqual('pizza-1');
2465+
it('should initialize with no selection despite having a value', () => {
2466+
expect(instance.selectedFood.value).toBe('pizza-1');
2467+
expect(instance.select.selected).toBeUndefined();
24842468
});
24852469

2486-
it('should update when making a new selection', async(() => {
2487-
instance.options.last._selectViaInteraction();
2470+
it('should not update the selection when changing the value', async(() => {
2471+
instance.options.first._selectViaInteraction();
24882472
fixture.detectChanges();
24892473
fixture.whenStable().then(() => {
2490-
const selectedOption = instance.select.selected as MdOption;
2491-
expect(instance.selectedFood.value).toEqual('tacos-2');
2492-
expect(selectedOption.value.value).toEqual('tacos-2');
2474+
expect(instance.selectedFood.value).toEqual('steak-0');
2475+
expect(instance.select.selected).toBeUndefined();
24932476
});
24942477
}));
24952478
});
2479+
2480+
describe('when using a non-function comparator', () => {
2481+
beforeEach(() => {
2482+
instance.useNullComparator();
2483+
});
2484+
2485+
it('should throw an error', () => {
2486+
expect(() => {
2487+
fixture.detectChanges();
2488+
}).toThrowError('compareWith must be a function, but received null');
2489+
});
2490+
});
24962491
});
24972492
});
24982493

@@ -2958,7 +2953,7 @@ class NgModelCompareWithSelect {
29582953
{ value: 'tacos-2', viewValue: 'Tacos' },
29592954
];
29602955
selectedFood: {value: string, viewValue: string} = { value: 'pizza-1', viewValue: 'Pizza' };
2961-
comparator: (f1: any, f2: any) => boolean;
2956+
comparator: ((f1: any, f2: any) => boolean)|null = this.compareByValue;
29622957

29632958
@ViewChild(MdSelect) select: MdSelect;
29642959
@ViewChildren(MdOption) options: QueryList<MdOption>;
@@ -2967,6 +2962,8 @@ class NgModelCompareWithSelect {
29672962

29682963
useCompareByReference() { this.comparator = this.compareByReference; }
29692964

2965+
useNullComparator() { this.comparator = null; }
2966+
29702967
compareByValue(f1: any, f2: any) { return f1 && f2 && f1.value === f2.value; }
29712968

29722969
compareByReference(f1: any, f2: any) { return f1 === f2; }

src/lib/select/select.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,15 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
293293
@Input()
294294
get compareWith() { return this._compareWith; }
295295
set compareWith(fn: (o1: any, o2: any) => boolean) {
296+
if (typeof fn !== 'function') {
297+
throw new TypeError(
298+
`compareWith must be a function, but received ${JSON.stringify(fn)}`);
299+
}
300+
this._compareWith = fn;
296301
if (this._selectionModel) {
297302
// A different comparator means the selection could change.
298303
this._initializeSelection();
299304
}
300-
this._compareWith = fn;
301305
}
302306

303307
/** Whether to float the placeholder text. */

0 commit comments

Comments
 (0)