From 6ae4d0971e8d001e42ef4424b77a414562bac001 Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Fri, 20 Jan 2017 14:27:35 -0800 Subject: [PATCH 1/3] emit onchange with null when date is empty --- packages/datetime/src/dateInput.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/datetime/src/dateInput.tsx b/packages/datetime/src/dateInput.tsx index c55c82d8d1..ca141a7f8e 100644 --- a/packages/datetime/src/dateInput.tsx +++ b/packages/datetime/src/dateInput.tsx @@ -246,7 +246,7 @@ export class DateInput extends AbstractComponent) => { @@ -291,6 +291,9 @@ export class DateInput extends AbstractComponent Date: Fri, 20 Jan 2017 15:33:00 -0800 Subject: [PATCH 2/3] add and modify tests --- packages/datetime/test/dateInputTests.tsx | 78 +++++++++++++++++++---- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/packages/datetime/test/dateInputTests.tsx b/packages/datetime/test/dateInputTests.tsx index 673d34cfcd..533d5d9428 100644 --- a/packages/datetime/test/dateInputTests.tsx +++ b/packages/datetime/test/dateInputTests.tsx @@ -10,6 +10,7 @@ import { mount } from "enzyme"; import * as React from "react"; import { Button, InputGroup, Popover } from "@blueprintjs/core"; +import { Months } from "../src/common/months"; import { padWithZeroes } from "../src/common/utils"; import { Classes, DateInput } from "../src/index"; @@ -64,6 +65,28 @@ describe("", () => { assert.notEqual(wrapper.find(InputGroup).prop("value"), ""); }); + it("Clearing the date in the DatePicker clears the input, and invokes onChange with null", () => { + const onChange = sinon.spy(); + const { root, getDay } = wrap( + , + ); + root.setState({ isOpen: true }); + getDay(22).simulate("click"); + assert.equal(root.find(InputGroup).prop("value"), ""); + assert.isTrue(onChange.calledWith(null)); + }); + + it("Clearing the date in the input clears the selection and invokes onChange with null", () => { + const onChange = sinon.spy(); + const { root, getDay, getSelectedDays } = wrap( + , + ); + root.find("input").simulate("change", { target: { value: "" }}); + + assert.lengthOf(getSelectedDays(), 0); + assert.isTrue(onChange.calledWith(null)); + }); + it("The popover stays open on date click if closeOnSelection=false", () => { const wrapper = mount().setState({ isOpen: true }); wrapper.find(`.${Classes.DATEPICKER_DAY}`).first().simulate("click"); @@ -71,7 +94,7 @@ describe("", () => { }); it("Clicking a date in a different month sets input value but keeps popover open", () => { - const date = new Date(2016, 3, 3); + const date = new Date(2016, Months.APRIL, 3); const wrapper = mount().setState({ isOpen: true }); assert.equal(wrapper.find(InputGroup).prop("value"), "2016-04-03"); @@ -98,8 +121,8 @@ describe("", () => { const rangeMessage = "RANGE ERROR"; const onError = sinon.spy(); const wrapper = mount(); @@ -118,7 +141,7 @@ describe("", () => { const invalidDateMessage = "INVALID DATE"; const onError = sinon.spy(); const wrapper = mount(); @@ -135,20 +158,30 @@ describe("", () => { }); describe("when controlled", () => { - const DATE = new Date(2016, 3, 4); + const DATE = new Date(2016, Months.APRIL, 4); const DATE_STR = "2016-04-04"; - const DATE2 = new Date(2015, 1, 1); + const DATE2 = new Date(2015, Months.FEBRUARY, 1); const DATE2_STR = "2015-02-01"; it("Clicking a date invokes onChange callback with that date", () => { const onChange = sinon.spy(); - mount() - .setState({ isOpen: true }) - .find(`.${Classes.DATEPICKER_DAY}`).first() - .simulate("click"); + const { getDay, root } = wrap(); + root.setState({ isOpen: true }) + getDay(27).simulate("click"); assert.isTrue(onChange.calledOnce); - assertDateEquals(onChange.args[0][0], "2016-03-27"); + assertDateEquals(onChange.args[0][0], "2016-04-27"); + }); + + it("Clearing the date in the DatePicker invokes onChange with null but doesn't change UI", () => { + const onChange = sinon.spy(); + const { root, getDay } = wrap( + , + ); + root.setState({ isOpen: true }); + getDay(4).simulate("click"); + assert.equal(root.find(InputGroup).prop("value"), "2016-04-04"); + assert.isTrue(onChange.calledWith(null)); }); it("Updating value updates the text box", () => { @@ -165,6 +198,15 @@ describe("", () => { assert.isTrue(onChange.calledOnce); assertDateEquals(onChange.args[0][0], DATE2_STR); }); + + it("Clearing the date in the input invokes onChange with null", () => { + const onChange = sinon.spy(); + const { root, getDay, getSelectedDays } = wrap( + , + ); + root.find("input").simulate("change", { target: { value: "" }}); + assert.isTrue(onChange.calledWith(null)); + }); }); /* Assert Date equals YYYY-MM-DD string. */ @@ -176,4 +218,18 @@ describe("", () => { ].join("-"); assert.strictEqual(actualString, expected); } + + function wrap(dateInput: JSX.Element) { + const wrapper = mount(dateInput); + return { + getDay: (dayNumber = 1) => { + return wrapper + .find(`.${Classes.DATEPICKER_DAY}`) + .filterWhere((day) => day.text() === "" + dayNumber && + !day.hasClass(Classes.DATEPICKER_DAY_OUTSIDE)); + }, + getSelectedDays: () => wrapper.find(`.${Classes.DATEPICKER_DAY_SELECTED}`), + root: wrapper, + }; + } }); From ff75b3d65cdedc6cc9075f496ed5a5f5e44349ca Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Sat, 21 Jan 2017 17:02:57 -0800 Subject: [PATCH 3/3] fix linting --- packages/datetime/test/dateInputTests.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/datetime/test/dateInputTests.tsx b/packages/datetime/test/dateInputTests.tsx index 533d5d9428..4362b1318c 100644 --- a/packages/datetime/test/dateInputTests.tsx +++ b/packages/datetime/test/dateInputTests.tsx @@ -166,7 +166,7 @@ describe("", () => { it("Clicking a date invokes onChange callback with that date", () => { const onChange = sinon.spy(); const { getDay, root } = wrap(); - root.setState({ isOpen: true }) + root.setState({ isOpen: true }); getDay(27).simulate("click"); assert.isTrue(onChange.calledOnce);