Skip to content

Commit 97b6ef9

Browse files
committed
Rebase and improve type checking by ensuring comparator is a function
1 parent 2b2aff7 commit 97b6ef9

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
@@ -2003,34 +2003,27 @@ describe('MdSelect', () => {
20032003
beforeEach(async(() => {
20042004
fixture = TestBed.createComponent(NgModelCompareWithSelect);
20052005
instance = fixture.componentInstance;
2006-
spyOn(instance, 'compareByReference').and.callThrough();
20072006
fixture.detectChanges();
20082007
}));
20092008

2010-
const testCompareByReferenceBehavior = () => {
2011-
it('should initialize with no selection despite having a value', () => {
2012-
expect(instance.selectedFood.value).toBe('pizza-1');
2013-
expect(instance.select.selected).toBeUndefined();
2014-
});
2015-
2016-
it('should not update the selection when changing the value', async(() => {
2017-
instance.options.first._selectViaInteraction();
2018-
fixture.detectChanges();
2019-
fixture.whenStable().then(() => {
2020-
expect(instance.selectedFood.value).toEqual('steak-0');
2021-
expect(instance.select.selected).toBeUndefined();
2022-
});
2023-
}));
2024-
};
2025-
2026-
it('should not use the comparator', () => {
2027-
expect(instance.compareByReference).not.toHaveBeenCalled();
2009+
it('should have a selection', () => {
2010+
const selectedOption = instance.select.selected as MdOption;
2011+
expect(selectedOption.value.value).toEqual('pizza-1');
20282012
});
20292013

2030-
testCompareByReferenceBehavior();
2014+
it('should update when making a new selection', async(() => {
2015+
instance.options.last._selectViaInteraction();
2016+
fixture.detectChanges();
2017+
fixture.whenStable().then(() => {
2018+
const selectedOption = instance.select.selected as MdOption;
2019+
expect(instance.selectedFood.value).toEqual('tacos-2');
2020+
expect(selectedOption.value.value).toEqual('tacos-2');
2021+
});
2022+
}));
20312023

20322024
describe('when comparing by reference', () => {
20332025
beforeEach(async(() => {
2026+
spyOn(instance, 'compareByReference').and.callThrough();
20342027
instance.useCompareByReference();
20352028
fixture.detectChanges();
20362029
}));
@@ -2039,30 +2032,32 @@ describe('MdSelect', () => {
20392032
expect(instance.compareByReference).toHaveBeenCalled();
20402033
});
20412034

2042-
testCompareByReferenceBehavior();
2043-
});
2044-
2045-
describe('when comparing by value', () => {
2046-
beforeEach(async(() => {
2047-
instance.useCompareByValue();
2048-
fixture.detectChanges();
2049-
}));
2050-
2051-
it('should have a selection', () => {
2052-
const selectedOption = instance.select.selected as MdOption;
2053-
expect(selectedOption.value.value).toEqual('pizza-1');
2035+
it('should initialize with no selection despite having a value', () => {
2036+
expect(instance.selectedFood.value).toBe('pizza-1');
2037+
expect(instance.select.selected).toBeUndefined();
20542038
});
20552039

2056-
it('should update when making a new selection', async(() => {
2057-
instance.options.last._selectViaInteraction();
2040+
it('should not update the selection when changing the value', async(() => {
2041+
instance.options.first._selectViaInteraction();
20582042
fixture.detectChanges();
20592043
fixture.whenStable().then(() => {
2060-
const selectedOption = instance.select.selected as MdOption;
2061-
expect(instance.selectedFood.value).toEqual('tacos-2');
2062-
expect(selectedOption.value.value).toEqual('tacos-2');
2044+
expect(instance.selectedFood.value).toEqual('steak-0');
2045+
expect(instance.select.selected).toBeUndefined();
20632046
});
20642047
}));
20652048
});
2049+
2050+
describe('when using a non-function comparator', () => {
2051+
beforeEach(() => {
2052+
instance.useNullComparator();
2053+
});
2054+
2055+
it('should throw an error', () => {
2056+
expect(() => {
2057+
fixture.detectChanges();
2058+
}).toThrowError('compareWith must be a function, but received null');
2059+
});
2060+
});
20662061
});
20672062
});
20682063

@@ -2425,7 +2420,7 @@ class NgModelCompareWithSelect {
24252420
{ value: 'tacos-2', viewValue: 'Tacos' },
24262421
];
24272422
selectedFood: {value: string, viewValue: string} = { value: 'pizza-1', viewValue: 'Pizza' };
2428-
comparator: (f1: any, f2: any) => boolean;
2423+
comparator: ((f1: any, f2: any) => boolean)|null = this.compareByValue;
24292424

24302425
@ViewChild(MdSelect) select: MdSelect;
24312426
@ViewChildren(MdOption) options: QueryList<MdOption>;
@@ -2434,6 +2429,8 @@ class NgModelCompareWithSelect {
24342429

24352430
useCompareByReference() { this.comparator = this.compareByReference; }
24362431

2432+
useNullComparator() { this.comparator = null; }
2433+
24372434
compareByValue(f1: any, f2: any) { return f1 && f2 && f1.value === f2.value; }
24382435

24392436
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
@@ -274,11 +274,15 @@ export class MdSelect implements AfterContentInit, OnDestroy, OnInit, ControlVal
274274
@Input()
275275
get compareWith() { return this._compareWith; }
276276
set compareWith(fn: (o1: any, o2: any) => boolean) {
277+
if (typeof fn !== 'function') {
278+
throw new TypeError(
279+
`compareWith must be a function, but received ${JSON.stringify(fn)}`);
280+
}
281+
this._compareWith = fn;
277282
if (this._selectionModel) {
278283
// A different comparator means the selection could change.
279284
this._initializeSelection();
280285
}
281-
this._compareWith = fn;
282286
}
283287

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

0 commit comments

Comments
 (0)