Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datepicker: Allow null value for currentDate on mounting #12963

Merged

Conversation

psealock
Copy link
Contributor

@psealock psealock commented Dec 18, 2018

Description

When a null value is passed to <DatePicker >, don't set the date to current date. Instead, allow the value to remain null such that no selection is visible on the calendar.

undefined values for currentDate behave as they did previously, which is to fall back to the today's date.

Testing

  1. Confirm that a dependency on setting currentDate to todays date by default does not exist by pulling down the branch and seeing that nothing breaks.
  2. Force a null value for the currentDate prop on <DatePicker > to ensure nothing breaks and no date is selected.
  3. Remove the currentDate prop and see the date picker default to today's date.

<DatePicker
currentDate={ currentDate }
onChange={ onChange }
/>

Screenshots

screen shot 2018-12-18 at 2 33 12 pm

Types of changes

New feature: Allow null value of date selection to persist such that no date is selected on the calendar.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.

@designsimply designsimply added [Priority] High Used to indicate top priority items that need quick attention [Package] Date /packages/date labels Jan 17, 2019
@designsimply designsimply added this to the 4.9 (Gutenberg) milestone Jan 17, 2019
@designsimply designsimply requested a review from a team January 17, 2019 21:42
@psealock psealock force-pushed the update/datepicker-allow-null-on-mount branch from cb3507b to 6535d09 Compare January 20, 2019 19:49
@psealock psealock force-pushed the update/datepicker-allow-null-on-mount branch 2 times, most recently from 96eab9a to 477b060 Compare January 23, 2019 20:04
@aduth
Copy link
Member

aduth commented Jan 24, 2019

Wouldn't this be considered a breaking change for someone who might have relied on the current behavior?

Is a middle-ground option that we allow for an explicit null value to signify "unselected", allowing undefined to continue to represent the current-date defaulting?

@psealock
Copy link
Contributor Author

Great feedback here, thank you @aduth !

I've added a method getMomentDate to explicitly check for null such that undefined values for currentDate have the same experience as before.

@@ -25,7 +25,7 @@ class DatePicker extends Component {
onChangeMoment( newDate ) {
const { currentDate, onChange } = this.props;

const momentDate = currentDate ? moment( currentDate ) : moment();
const momentDate = this.getMomentDate( currentDate );
const momentTime = {
hours: momentDate.hours(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getMomentDate can return null, at which point this would throw an error.

It would be good to document any function we introduce, as it may make this sort of thing easier to catch, when recognizing that the return value of the function is nullable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests, as well, would be good to capture this sort of issue and the expected behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eesh, good call. I've gone back to the original implementation here and included a comment about to explain why moment() is used if currentDate is undefined or null.

Unit tests added. Thanks

@psealock psealock force-pushed the update/datepicker-allow-null-on-mount branch from a81e205 to 79ff4a3 Compare January 27, 2019 23:17
packages/components/src/date-time/date.js Outdated Show resolved Hide resolved
packages/components/src/date-time/date.js Outdated Show resolved Hide resolved
*/
import DatePicker from '../date';

describe( 'DatePicker', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad to see tests, but for what it's worth these tests as written would not have caught the error described in my previous review, since there is zero coverage for onChangeMoment.

@psealock
Copy link
Contributor Author

Thanks for the edits to the jsDoc @aduth.

I added testing to onChangeMoment also.

@psealock psealock force-pushed the update/datepicker-allow-null-on-mount branch from eb11780 to 08578e8 Compare January 30, 2019 00:50
@psealock psealock force-pushed the update/datepicker-allow-null-on-mount branch from 08578e8 to 2e40cf6 Compare January 30, 2019 01:22
const onChangeSpy = jest.fn();
const wrapper = shallow( <DatePicker onChange={ onChangeSpy } /> );
const newDate = moment( '1986-10-18T11:00:00' );
const current = moment();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This worries me a bit; I feel like it will be prone to test fragility, where the time required to execute the test is such that moment() called here will produce a different time than moment() called within the implementation of onChangeMoment. Usually this should take a mere fraction of a second, but I've witnessed in the past where it's enough time to tick into the next second and cause an uenxpected test failure.

I think our options would be:

  • Find a way to provide or otherwise control the current time as referenced within onChangeMoment
  • Mock moment to have full control over what it returns†
  • Provide some flexibility in the assertion (i.e. within a +/- allowable timeframe)
  • Don't test it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets go with Provide some flexibility in the assertion (i.e. within a +/- allowable timeframe) for $1000 please, Alex.

I figured comparison on basis of seconds was enough to overcome differences in execution time, but in an effort to prevent future headaches, a change is a good idea.

I changed the tests to save the argument passed to onChange for later comparison using moment's isSame function. Then I compare with a granularity of minute, which would preclude all but the rarest of circumstances where a pause in execution time ticks into the next second AND minute.

@psealock
Copy link
Contributor Author

psealock commented Feb 7, 2019

Hi @aduth, would you have a moment to give this another look?

I changed the tests to save the argument passed to onChange for later comparison using moment's isSame function. Then I compare with a granularity of minute, which would preclude all but the rarest of circumstances where a pause in execution time ticks into the next second AND minute.

Many thanks!

Copy link
Member

@aduth aduth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it comes to intermittent test failures, I'd prefer "impossible" over "rare", but I'll take what I can get.

Thanks for your patience 👍

@aduth aduth merged commit a59aaf2 into WordPress:master Feb 8, 2019
@aduth aduth added [Feature] UI Components Impacts or related to the UI component system [Package] Components /packages/components labels Feb 8, 2019
@aduth aduth removed [Priority] High Used to indicate top priority items that need quick attention [Package] Date /packages/date labels Feb 8, 2019
@psealock psealock deleted the update/datepicker-allow-null-on-mount branch February 10, 2019 17:53
@aduth
Copy link
Member

aduth commented Feb 26, 2019

When it comes to intermittent test failures, I'd prefer "impossible" over "rare", but I'll take what I can get.

Encountered my first failure today:

image

@psealock
Copy link
Contributor Author

Yikes, thanks for the heads up. I'll look into this to evaluate other solutions

@psealock
Copy link
Contributor Author

psealock commented Mar 5, 2019

@aduth Here is a PR to fix the intermittent failures, #14230

youknowriad pushed a commit that referenced this pull request Mar 6, 2019
* Datepicker: Allow null value for currentDate on mounting

* flexible assertion, FTW
youknowriad pushed a commit that referenced this pull request Mar 6, 2019
* Datepicker: Allow null value for currentDate on mounting

* flexible assertion, FTW
This was referenced Apr 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] UI Components Impacts or related to the UI component system [Package] Components /packages/components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants