Skip to content

Commit

Permalink
add error for multiple missing when; add basic test back in for lib/t…
Browse files Browse the repository at this point in the history
…able
  • Loading branch information
andrewseguin committed Sep 5, 2017
1 parent 77ecbe6 commit 18ef7b5
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 17 deletions.
16 changes: 16 additions & 0 deletions src/cdk/table/table-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,19 @@ export function getTableUnknownColumnError(id: string) {
export function getTableDuplicateColumnNameError(name: string) {
return Error(`cdk-table: Duplicate column definition name provided: "${name}".`);
}

/**
* Returns an error to be thrown when there are multiple rows that are missing a when function.
* @docs-private
*/
export function getTableMultipleDefaultRowDefsError() {
return Error(`cdk-table: There can only be one default row without a when predicate function.`);
}

/**
* Returns an error to be thrown when there are no matching row defs for a particular set of data.
* @docs-private
*/
export function getTableMissingMatchingRowDefError() {
return Error(`cdk-table: Could not find a matching row definition for the provided row data.`);
}
62 changes: 59 additions & 3 deletions src/cdk/table/table.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ import {Observable} from 'rxjs/Observable';
import {combineLatest} from 'rxjs/observable/combineLatest';
import {CdkTableModule} from './index';
import {map} from 'rxjs/operator/map';
import {getTableDuplicateColumnNameError, getTableUnknownColumnError} from './table-errors';
import {
getTableDuplicateColumnNameError,
getTableMissingMatchingRowDefError,
getTableMultipleDefaultRowDefsError,
getTableUnknownColumnError
} from './table-errors';

describe('CdkTable', () => {
let fixture: ComponentFixture<SimpleCdkTableApp>;
Expand All @@ -31,7 +36,8 @@ describe('CdkTable', () => {
MissingColumnDefCdkTableApp,
CrazyColumnNameCdkTableApp,
WhenRowCdkTableApp,
WhenRowWithoutDefaultCdkTableApp
WhenRowWithoutDefaultCdkTableApp,
WhenRowMultipleDefaultsCdkTableApp
],
}).compileComponents();
}));
Expand Down Expand Up @@ -206,7 +212,13 @@ describe('CdkTable', () => {
it('should error if there is row data that does not have a matching row template', () => {
let whenFixture = TestBed.createComponent(WhenRowWithoutDefaultCdkTableApp);
expect(() => whenFixture.detectChanges())
.toThrowError('Could not find a matching row definition for the provided row data');
.toThrowError(getTableMissingMatchingRowDefError().message);
});

it('should error if there are multiple rows that do not have a when function', () => {
let whenFixture = TestBed.createComponent(WhenRowMultipleDefaultsCdkTableApp);
expect(() => whenFixture.detectChanges())
.toThrowError(getTableMultipleDefaultRowDefsError().message);
});
});

Expand Down Expand Up @@ -712,6 +724,50 @@ class WhenRowWithoutDefaultCdkTableApp {
@ViewChild(CdkTable) table: CdkTable<TestData>;
}

@Component({
template: `
<cdk-table [dataSource]="dataSource">
<ng-container cdkColumnDef="column_a">
<cdk-header-cell *cdkHeaderCellDef> Column A</cdk-header-cell>
<cdk-cell *cdkCellDef="let row"> {{row.a}}</cdk-cell>
</ng-container>
<ng-container cdkColumnDef="column_b">
<cdk-header-cell *cdkHeaderCellDef> Column B</cdk-header-cell>
<cdk-cell *cdkCellDef="let row"> {{row.b}}</cdk-cell>
</ng-container>
<ng-container cdkColumnDef="column_c">
<cdk-header-cell *cdkHeaderCellDef> Column C</cdk-header-cell>
<cdk-cell *cdkCellDef="let row"> {{row.c}}</cdk-cell>
</ng-container>
<ng-container cdkColumnDef="index1Column">
<cdk-header-cell *cdkHeaderCellDef> Column C</cdk-header-cell>
<cdk-cell *cdkCellDef="let row"> index_1_special_row </cdk-cell>
</ng-container>
<ng-container cdkColumnDef="c3Column">
<cdk-header-cell *cdkHeaderCellDef> Column C</cdk-header-cell>
<cdk-cell *cdkCellDef="let row"> c3_special_row </cdk-cell>
</ng-container>
<cdk-header-row *cdkHeaderRowDef="columnsToRender"></cdk-header-row>
<cdk-row *cdkRowDef="let row; columns: columnsToRender"></cdk-row>
<cdk-row *cdkRowDef="let row; columns: ['index1Column']"></cdk-row>
<cdk-row *cdkRowDef="let row; columns: ['c3Column']; when: hasC3"></cdk-row>
</cdk-table>
`
})
class WhenRowMultipleDefaultsCdkTableApp {
dataSource: FakeDataSource = new FakeDataSource();
columnsToRender = ['column_a', 'column_b', 'column_c'];
isIndex1 = (_rowData: TestData, index: number) => index == 1;
hasC3 = (rowData: TestData) => rowData.c == 'c_3';

@ViewChild(CdkTable) table: CdkTable<TestData>;
}

@Component({
template: `
<cdk-table [dataSource]="dataSource">
Expand Down
16 changes: 11 additions & 5 deletions src/cdk/table/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Subscription} from 'rxjs/Subscription';
import {Subject} from 'rxjs/Subject';
import {CdkCellDef, CdkColumnDef, CdkHeaderCellDef} from './cell';
import {getTableDuplicateColumnNameError, getTableUnknownColumnError} from './table-errors';
import {
getTableDuplicateColumnNameError, getTableMissingMatchingRowDefError,
getTableMultipleDefaultRowDefsError,
getTableUnknownColumnError
} from './table-errors';

/**
* Provides a handle for the table to grab the view container's ng-container to insert data rows.
Expand Down Expand Up @@ -175,7 +179,11 @@ export class CdkTable<T> implements CollectionViewer {

ngAfterContentChecked() {
this._renderUpdatedColumns();
this._defaultRowDef = this._rowDefs.find(def => !def.when) || null;

const defaultRowDefs = this._rowDefs.filter(def => !def.when);
if (defaultRowDefs.length > 1) { throw getTableMultipleDefaultRowDefsError(); }
this._defaultRowDef = defaultRowDefs[0];

if (this.dataSource && !this._renderChangeSubscription) {
this._observeRenderChanges();
}
Expand Down Expand Up @@ -312,9 +320,7 @@ export class CdkTable<T> implements CollectionViewer {
if (this._rowDefs.length == 1) { return this._rowDefs.first; }

let rowDef = this._rowDefs.find(def => def.when && def.when(data, i)) || this._defaultRowDef;
if (!rowDef) {
throw Error('Could not find a matching row definition for the provided row data');
}
if (!rowDef) { throw getTableMissingMatchingRowDefError(); }

return rowDef;
}
Expand Down
54 changes: 45 additions & 9 deletions src/lib/table/table.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {async, TestBed} from '@angular/core/testing';
import {Component, ViewChild} from '@angular/core';
import {DataSource} from '@angular/cdk/collections';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
Expand All @@ -7,22 +7,17 @@ import {MdTableModule} from './index';
import {MdTable} from './table';

describe('MdTable', () => {
let fixture: ComponentFixture<MdTableApp>;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MdTableModule],
declarations: [MdTableApp],
declarations: [MdTableApp, MdTableWithWhenRowApp],
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(MdTableApp);
fixture.detectChanges();
it('should be able to create a table with the right content and without when row', () => {
let fixture = TestBed.createComponent(MdTableApp);
fixture.detectChanges();
});

it('should create a table with the right content', () => {
const tableElement = fixture.nativeElement.querySelector('.mat-table');
const headerRow = tableElement.querySelectorAll('.mat-header-cell');
expectTextContent(headerRow[0], 'Column A');
Expand All @@ -42,6 +37,21 @@ describe('MdTable', () => {
// Fourth row uses a special when predicate to show a different colummn
expect(rows[3].textContent.trim()).toBe('fourth_row');
});

it('should create a table with special when row', () => {
let fixture = TestBed.createComponent(MdTableWithWhenRowApp);
fixture.detectChanges();

const tableElement = fixture.nativeElement.querySelector('.mat-table');
const headerRow = tableElement.querySelectorAll('.mat-header-cell');
expectTextContent(headerRow[0], 'Column A');

const rows = tableElement.querySelectorAll('.mat-row');
expect(rows[0].textContent.trim()).toBe('a_1');
expect(rows[1].textContent.trim()).toBe('a_2');
expect(rows[2].textContent.trim()).toBe('a_3');
expect(rows[3].textContent.trim()).toBe('fourth_row');
});
});

function expectTextContent(el, text) {
Expand Down Expand Up @@ -123,3 +133,29 @@ class MdTableApp {

@ViewChild(MdTable) table: MdTable<TestData>;
}


@Component({
template: `
<md-table [dataSource]="dataSource">
<ng-container mdColumnDef="column_a">
<md-header-cell *mdHeaderCellDef> Column A</md-header-cell>
<md-cell *mdCellDef="let row"> {{row.a}}</md-cell>
</ng-container>
<ng-container mdColumnDef="special_column">
<md-cell *mdCellDef="let row"> fourth_row </md-cell>
</ng-container>
<md-header-row *mdHeaderRowDef="['column_a']"></md-header-row>
<md-row *mdRowDef="let row; columns: ['column_a']"></md-row>
<md-row *mdRowDef="let row; columns: ['special_column']; when: isFourthRow"></md-row>
</md-table>
`
})
class MdTableWithWhenRowApp {
dataSource: FakeDataSource | null = new FakeDataSource();
isFourthRow = (_rowData: TestData, i: number) => i == 3;

@ViewChild(MdTable) table: MdTable<TestData>;
}

0 comments on commit 18ef7b5

Please sign in to comment.