diff --git a/packages/table/src/table.tsx b/packages/table/src/table.tsx index db51f5975c..85ee7f0239 100644 --- a/packages/table/src/table.tsx +++ b/packages/table/src/table.tsx @@ -494,9 +494,6 @@ export class Table extends AbstractComponent { public constructor(props: ITableProps & { children: React.ReactNode }, context?: any) { super(props, context); - if (!CoreUtils.isNodeEnv("production")) { - this.validateProps(props); - } const { children, columnWidths, defaultRowHeight, defaultColumnWidth, numRows, rowHeights } = this.props; @@ -668,9 +665,8 @@ export class Table extends AbstractComponent { } public componentWillReceiveProps(nextProps: ITableProps & { children: React.ReactNode }) { - if (!CoreUtils.isNodeEnv("production")) { - this.validateProps(nextProps); - } + // calls validateProps + super.componentWillReceiveProps(nextProps); const { children, diff --git a/packages/table/test/editableCellTests.tsx b/packages/table/test/editableCellTests.tsx index e911ac6a44..1ee473301a 100644 --- a/packages/table/test/editableCellTests.tsx +++ b/packages/table/test/editableCellTests.tsx @@ -12,27 +12,16 @@ import * as sinon from "sinon"; import * as Classes from "../src/common/classes"; import { EditableCell } from "../src/index"; import { CellType, expectCellLoading } from "./cellTestUtils"; -import { ElementHarness, ReactHarness } from "./harness"; describe("", () => { - const harness = new ReactHarness(); - - afterEach(() => { - harness.unmount(); - }); - - after(() => { - harness.destroy(); - }); - it("renders", () => { - const elem = harness.mount(); + const elem = mount(); expect(elem.find(`.${Classes.TABLE_TRUNCATED_TEXT}`).text()).to.equal("test-value-5000"); }); it("renders loading state", () => { - const editableCellHarness = harness.mount(); - expectCellLoading(editableCellHarness.element.children[0], CellType.BODY_CELL); + const editableCellHarness = mount(); + expectCellLoading(editableCellHarness.first().getDOMNode(), CellType.BODY_CELL); }); it("renders new value if props.value changes", () => { @@ -50,61 +39,60 @@ describe("", () => { const onCancel = sinon.spy(); const onChange = sinon.spy(); const onConfirm = sinon.spy(); - const elem = harness.mount( + + const elem = mount( , ); - // double click to edit - doubleClickToEdit(elem); - const input = getInput(elem); - // TODO: throws JSON-stringify cyclic errors as of #1741; need to fix. - // expect(input.element).to.equal(document.activeElement); + // start editing + elem.setState({ isEditing: true, dirtyValue: "test-value-5000" }); + const input = elem.find(`.${Classes.TABLE_EDITABLE_TEXT} input`); + expect(input.length).to.equal(1); - // edit - input.change("my-changed-value"); + // make changes + input.simulate("change", { target: { value: "new-text" } }); expect(onChange.called).to.be.true; expect(onCancel.called).to.be.false; expect(onConfirm.called).to.be.false; - expect(elem.find(".pt-editable-content").text()).to.equal("my-changed-value"); + expect(elem.find(`.${Classes.TABLE_EDITABLE_TEXT} .pt-editable-content`).text()).to.equal("new-text"); // confirm - input.blur(); + input.simulate("blur"); expect(onCancel.called).to.be.false; - // TODO: onBlur isn't firing as of #1741; need to re-enable this test. - // expect(onConfirm.called).to.be.true; + expect(onConfirm.called).to.be.true; }); it("doesn't change edited value on non-value prop changes", () => { const onCancel = sinon.spy(); const onChange = sinon.spy(); const onConfirm = sinon.spy(); - const elem = harness.mount( + + const elem = mount( , ); - // double click to edit - doubleClickToEdit(elem); - const input = getInput(elem); - // TODO: throws JSON-stringify cyclic errors as of #1741; need to fix. - // expect(input.element).to.equal(document.activeElement); + // start editing + elem.setState({ isEditing: true, dirtyValue: "test-value-5000" }); + const input = elem.find(`.${Classes.TABLE_EDITABLE_TEXT} input`); + expect(input.length).to.equal(1); - // edit - input.change("my-changed-value"); + // make changes + input.simulate("change", { target: { value: "new-text" } }); expect(onChange.called).to.be.true; expect(onCancel.called).to.be.false; expect(onConfirm.called).to.be.false; - expect(elem.find(".pt-editable-content").text()).to.equal("my-changed-value"); + expect(elem.find(`.${Classes.TABLE_EDITABLE_TEXT} .pt-editable-content`).text()).to.equal("new-text"); - harness.mount( - , - ); - expect(elem.find(".pt-editable-content").text()).to.equal("my-changed-value"); + // set non-value prop + elem.setProps({ onChange: null }); + + // value stays the same + expect(elem.find(`.${Classes.TABLE_EDITABLE_TEXT} .pt-editable-content`).text()).to.equal("new-text"); // confirm - input.blur(); + input.simulate("blur"); expect(onCancel.called).to.be.false; - // TODO: onBlur isn't firing as of #1741; need to re-enable this test. - // expect(onConfirm.called).to.be.true; + expect(onConfirm.called).to.be.true; }); it("passes index prop to callbacks if index was provided", () => { @@ -116,7 +104,7 @@ describe("", () => { const ROW_INDEX = 17; const COLUMN_INDEX = 44; - const elem = harness.mount( + const elem = mount( ", () => { />, ); - doubleClickToEdit(elem); + // start editing + elem.setState({ isEditing: true, dirtyValue: "" }); - // edit - const input = getInput(elem); - input.change(CHANGED_VALUE); + // change value + const input = elem.find(`.${Classes.TABLE_EDITABLE_TEXT} input`); + expect(input.length).to.equal(1); + input.simulate("change", { target: { value: CHANGED_VALUE } }); expect(onChangeSpy.firstCall.args).to.deep.equal([CHANGED_VALUE, ROW_INDEX, COLUMN_INDEX]); // confirm - input.blur(); - // TODO: onBlur isn't firing as of #1741; need to re-enable this test. - // expect(onConfirmSpy.firstCall.args).to.deep.equal([CHANGED_VALUE, ROW_INDEX, COLUMN_INDEX]); + input.simulate("blur"); + expect(onChangeSpy.firstCall.args).to.deep.equal([CHANGED_VALUE, ROW_INDEX, COLUMN_INDEX]); }); - - function doubleClickToEdit(elem: ElementHarness) { - elem - .find(`.${Classes.TABLE_TRUNCATED_TEXT}`) - .mouse("mousedown") - .mouse("mouseup") - .mouse("mousedown") - .mouse("mouseup"); - } - - function getInput(elem: ElementHarness) { - return elem.find(".pt-editable-input"); - } }); diff --git a/packages/table/test/editableNameTests.tsx b/packages/table/test/editableNameTests.tsx index 7fff2cb7ee..590fdf3042 100644 --- a/packages/table/test/editableNameTests.tsx +++ b/packages/table/test/editableNameTests.tsx @@ -5,25 +5,15 @@ */ import { expect } from "chai"; +import { mount } from "enzyme"; import * as React from "react"; import * as sinon from "sinon"; import { EditableName } from "../src/index"; -import { ReactHarness } from "./harness"; describe("", () => { - const harness = new ReactHarness(); - - afterEach(() => { - harness.unmount(); - }); - - after(() => { - harness.destroy(); - }); - it("renders", () => { - const elem = harness.mount(); + const elem = mount(); expect(elem.find(".pt-editable-content").text()).to.equal("test-name-5000"); }); @@ -31,22 +21,22 @@ describe("", () => { const onCancel = sinon.spy(); const onChange = sinon.spy(); const onConfirm = sinon.spy(); - const elem = harness.mount( + const elem = mount( , ); // focus - elem.find(".pt-editable-text").focus(); + elem.find(".pt-editable-text").simulate("focus"); // edit - const input = elem.find(".pt-editable-input").change("my-changed-name"); + const input = elem.find(".pt-editable-input").simulate("change", { target: { value: "my-changed-name" } }); expect(onChange.called).to.be.true; expect(onCancel.called).to.be.false; expect(onConfirm.called).to.be.false; expect(elem.find(".pt-editable-content").text()).to.equal("my-changed-name"); // confirm - input.blur(); + input.simulate("blur"); expect(onCancel.called).to.be.false; expect(onConfirm.called).to.be.true; }); diff --git a/packages/table/test/tableTests.tsx b/packages/table/test/tableTests.tsx index 54baaac856..05faef1549 100644 --- a/packages/table/test/tableTests.tsx +++ b/packages/table/test/tableTests.tsx @@ -5,7 +5,7 @@ */ import { expect } from "chai"; -import { mount, ReactWrapper, shallow } from "enzyme"; +import { mount, ReactWrapper } from "enzyme"; import * as React from "react"; import * as ReactDOM from "react-dom"; import * as sinon from "sinon"; @@ -389,15 +389,32 @@ describe("", () => { it("Selects and deselects column/row headers when selecting and deselecting the full table", () => { const table = mountTable(); - const columnHeader = table.find(COLUMN_HEADER_SELECTOR).at(0); - const rowHeader = table.find(`.${Classes.TABLE_ROW_HEADERS} .${Classes.TABLE_HEADER}`).at(0); + // select the full table selectFullTable(table); + let columnHeader = table + .find(COLUMN_HEADER_SELECTOR) + .hostNodes() + .first(); + let rowHeader = table + .find(`.${Classes.TABLE_ROW_HEADERS}`) + .find(`.${Classes.TABLE_HEADER}`) + .hostNodes() + .first(); expect(columnHeader.hasClass(Classes.TABLE_HEADER_SELECTED)).to.be.true; expect(rowHeader.hasClass(Classes.TABLE_HEADER_SELECTED)).to.be.true; // deselect the full table table.setProps({ selectedRegions: [] }); + columnHeader = table + .find(COLUMN_HEADER_SELECTOR) + .hostNodes() + .first(); + rowHeader = table + .find(`.${Classes.TABLE_ROW_HEADERS}`) + .find(`.${Classes.TABLE_HEADER}`) + .hostNodes() + .first(); expect(columnHeader.hasClass(Classes.TABLE_HEADER_SELECTED)).to.be.false; expect(rowHeader.hasClass(Classes.TABLE_HEADER_SELECTED)).to.be.false; }); @@ -415,6 +432,7 @@ describe("
", () => { const bottomContainer = table .find(`.${Classes.TABLE_QUADRANT_MAIN}`) .find(`.${Classes.TABLE_BOTTOM_CONTAINER}`) + .hostNodes() .getDOMNode() as HTMLElement; const { width: expectedWidth, height: expectedHeight } = bottomContainer.style; const [expectedWidthAsNumber, expectedHeightAsNumber] = [expectedWidth, expectedHeight].map(n => @@ -427,6 +445,7 @@ describe("
", () => { .find(`.${Classes.TABLE_QUADRANT_MAIN}`) .find(`.${Classes.TABLE_QUADRANT_BODY_CONTAINER}`) .find(`.${Classes.TABLE_SELECTION_REGION}`) + .hostNodes() .getDOMNode() as HTMLElement; const { width: actualWidth, height: actualHeight } = selectionOverlay.style; const [actualWidthAsNumber, actualHeightAsNumber] = [actualWidth, actualHeight].map(n => @@ -527,38 +546,38 @@ describe("
", () => { it("prints a warning and clamps out-of-bounds numFrozenColumns if > number of columns", () => { const table1 = mount(
); - expect(table1.state().numFrozenColumnsClamped).to.equal(0); + expect(table1.state("numFrozenColumnsClamped")).to.equal(0); expect(consoleWarn.callCount).to.equal(0); const table2 = mount(
); - expect(table2.state().numFrozenColumnsClamped).to.equal(0); - expect(consoleWarn.callCount).to.equal(1); + expect(table2.state("numFrozenColumnsClamped")).to.equal(0); + expect(consoleWarn.callCount).to.equal(1, "warned 1"); const table3 = mount(
, ); - expect(table3.state().numFrozenColumnsClamped).to.equal(1); - expect(consoleWarn.callCount).to.equal(2); + expect(table3.state("numFrozenColumnsClamped")).to.equal(1, "clamped"); + expect(consoleWarn.callCount).to.equal(2, "warned 2"); }); it("prints a warning and clamps out-of-bounds numFrozenRows if > numRows", () => { const table1 = mount(); - expect(table1.state().numFrozenRowsClamped).to.equal(0); + expect(table1.state("numFrozenRowsClamped")).to.equal(0); expect(consoleWarn.callCount).to.equal(0); const table2 = mount(
); - expect(table2.state().numFrozenRowsClamped).to.equal(0); - expect(consoleWarn.callCount).to.equal(1); + expect(table2.state("numFrozenRowsClamped")).to.equal(0); + expect(consoleWarn.callCount).to.equal(1, "warned 1"); const table3 = mount(
, ); - expect(table3.state().numFrozenRowsClamped).to.equal(1); - expect(consoleWarn.callCount).to.equal(2); + expect(table3.state("numFrozenRowsClamped")).to.equal(1, "clamped"); + expect(consoleWarn.callCount).to.equal(2, "warned 3"); }); const NUM_ROWS = 4; @@ -1558,153 +1577,21 @@ describe("", () => { }); it("should print a warning when numFrozenRows > numRows", () => { - shallow(
); + const table = mount(
); expect(consoleWarn.calledOnce); expect(consoleWarn.firstCall.args).to.deep.equal([Errors.TABLE_NUM_FROZEN_ROWS_BOUND_WARNING]); + table.unmount(); }); it("should print a warning when numFrozenColumns > num s", () => { - shallow( -
- -
, - ); - expect(consoleWarn.calledOnce); - expect(consoleWarn.firstCall.args).to.deep.equal([Errors.TABLE_NUM_FROZEN_COLUMNS_BOUND_WARNING]); - }); - }); - }); - - describe("on update", () => { - describe("errors", () => { - it("on numRows update, throws an error if numRows < 0", () => { - const table = shallow(); - const updateErroneously = () => table.setProps({ numRows: -1 }); - expect(updateErroneously).to.throw(Errors.TABLE_NUM_ROWS_NEGATIVE); - }); - - it("on numFrozenRows update, throws an error if numFrozenRows < 0", () => { - const table = shallow(
); - const updateErroneously = () => table.setProps({ numFrozenRows: -1 }); - expect(updateErroneously).to.throw(Errors.TABLE_NUM_FROZEN_ROWS_NEGATIVE); - }); - - it("on numFrozenColumns update, throws an error if numFrozenColumns < 0", () => { - const table = shallow(
); - const updateErroneously = () => table.setProps({ numFrozenColumns: -1 }); - expect(updateErroneously).to.throw(Errors.TABLE_NUM_FROZEN_COLUMNS_NEGATIVE); - }); - - it("on numRows update, throws an error if rowHeights.length !== numRows", () => { - const table = shallow(
); - const updateErroneously = () => table.setProps({ numRows: 4 }); - expect(updateErroneously).to.throw(Errors.TABLE_NUM_ROWS_ROW_HEIGHTS_MISMATCH); - }); - - it("on rowHeights update, throws an error if rowHeights.length !== numRows", () => { - const table = shallow(
); - const updateErroneously = () => table.setProps({ rowHeights: [1, 2, 3, 4] }); - expect(updateErroneously).to.throw(Errors.TABLE_NUM_ROWS_ROW_HEIGHTS_MISMATCH); - }); - - it("on children update, throws an error if columnWidths.length !== number of s", () => { - const table = shallow( -
- - - -
, - ); - const updateErroneously = () => table.setProps({ children: [, ] }); - expect(updateErroneously).to.throw(Errors.TABLE_NUM_COLUMNS_COLUMN_WIDTHS_MISMATCH); - }); - - it("on columnWidths update, throws an error if columnWidths.length !== number of s", () => { - const table = shallow( - - - - -
, - ); - const updateErroneously = () => table.setProps({ columnWidths: [1, 2, 3, 4] }); - expect(updateErroneously).to.throw(Errors.TABLE_NUM_COLUMNS_COLUMN_WIDTHS_MISMATCH); - }); - - it("on children update, throws an error if a non- child is provided", () => { - const table = shallow( - - -
, - ); - const updateErroneously = () => table.setProps({ children: [] }); - expect(updateErroneously).to.throw(Errors.TABLE_NON_COLUMN_CHILDREN_WARNING); - }); - }); - - describe("warnings", () => { - let consoleWarn: sinon.SinonSpy; - - before(() => { - consoleWarn = sinon.spy(console, "warn"); - }); - - afterEach(() => { - consoleWarn.reset(); - }); - - after(() => { - consoleWarn.restore(); - }); - - it("on numFrozenRows update, should print a warning when numFrozenRows > numRows", () => { - const table = shallow(); - expect(consoleWarn.called).to.be.false; - table.setProps({ numFrozenRows: 2 }); - expect(consoleWarn.calledOnce).to.be.true; - expect(consoleWarn.firstCall.args).to.deep.equal([Errors.TABLE_NUM_FROZEN_ROWS_BOUND_WARNING]); - }); - - it("on numRows update, should print a warning when numFrozenRows > numRows", () => { - const table = shallow(
); - expect(consoleWarn.called).to.be.false; - table.setProps({ numRows: 0 }); - expect(consoleWarn.calledOnce).to.be.true; - expect(consoleWarn.firstCall.args).to.deep.equal([Errors.TABLE_NUM_FROZEN_ROWS_BOUND_WARNING]); - }); - - it("on numFrozenColumns update, should print a warning when numFrozenColumns > num s", () => { - const table = shallow( -
- -
, - ); - expect(consoleWarn.called).to.be.false; - table.setProps({ numFrozenColumns: 2 }); - expect(consoleWarn.calledOnce).to.be.true; - expect(consoleWarn.firstCall.args).to.deep.equal([Errors.TABLE_NUM_FROZEN_COLUMNS_BOUND_WARNING]); - }); - - it("on children update, should print a warning when numFrozenColumns > num s", () => { - const table = shallow( - - -
, - ); - expect(consoleWarn.called).to.be.false; - table.setProps({ children: [] }); - expect(consoleWarn.calledOnce).to.be.true; - expect(consoleWarn.firstCall.args).to.deep.equal([Errors.TABLE_NUM_FROZEN_COLUMNS_BOUND_WARNING]); - }); - - it("should print a warning when numFrozenColumns > num s", () => { - shallow( + const table = mount(
, ); expect(consoleWarn.calledOnce); expect(consoleWarn.firstCall.args).to.deep.equal([Errors.TABLE_NUM_FROZEN_COLUMNS_BOUND_WARNING]); + table.unmount(); }); }); });