Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

resolve #158 #159

Merged
merged 1 commit into from
May 18, 2017
Merged

resolve #158 #159

merged 1 commit into from
May 18, 2017

Conversation

jackdpeterson
Copy link
Contributor

@jackdpeterson jackdpeterson commented Apr 27, 2017

Throws an InvalidArgumentException when one attempts to create a DateTime element with a string for min or max that does not conform to the expected \DateTime format.

@jackdpeterson
Copy link
Contributor Author

Looks like the unit tests need to be updated now to expect the element to barf when it gets garbage rather than allowing junk in that magically and mysteriously fails.

@jackdpeterson jackdpeterson force-pushed the 158 branch 2 times, most recently from fc3e5ff to b520f1a Compare April 28, 2017 18:38
@@ -53,7 +54,6 @@ class DateTime extends Element implements InputProviderInterface
public function setOptions($options)
{
parent::setOptions($options);

Copy link
Member

Choose a reason for hiding this comment

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

Please undo all code formatting changes.

@@ -81,6 +81,7 @@ public function getValue($returnFormattedValue = true)
return $value;
}
$format = $this->getFormat();

Copy link
Member

Choose a reason for hiding this comment

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

Please undo all code formatting changes.

@@ -92,7 +93,8 @@ public function getValue($returnFormattedValue = true)
*/
public function setFormat($format)
{
$this->format = (string) $format;
$this->format = (string)$format;
Copy link
Member

Choose a reason for hiding this comment

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

Please undo all code formatting changes.

'inclusive' => true,
]);
if (isset($this->attributes['min']) &&
\DateTime::createFromFormat(
Copy link
Member

Choose a reason for hiding this comment

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

createFromFormat here…

Copy link
Contributor Author

@jackdpeterson jackdpeterson May 1, 2017

Choose a reason for hiding this comment

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

This logic is correct and intended to be this way. No further simplifications are necessary. Are you proposing creating and referencing unnecessary variables simply for the sake of reducing the length of the evaluation?

Copy link
Member

Choose a reason for hiding this comment

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

You can remove the DateTime::createFromFormat() from the condition and the elseif can be eliminated.

At the moment the entire block is hard to read.

Copy link
Member

Choose a reason for hiding this comment

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

Please simplify the if statements.

Copy link
Member

Choose a reason for hiding this comment

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

Honestly, I agree with @froschdesign here. The same multiline statement is used in multiple conditions, making those conditions really hard to read. Capturing to a variable makes the conditions easier to read.

I can do that on merge.

]
);
} elseif (isset($this->attributes['min']) &&
! \DateTime::createFromFormat(
Copy link
Member

Choose a reason for hiding this comment

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

…and createFromFormat here.

Please simplify these if statements.

Copy link
Contributor Author

@jackdpeterson jackdpeterson May 1, 2017

Choose a reason for hiding this comment

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

This logic is correct and intended to be this way. No further simplifications are necessary. Are you proposing creating and referencing unnecessary variables simply for the sake of reducing the length of the evaluation?

'max' => $this->attributes['max'],

if (isset($this->attributes['max']) &&
\DateTime::createFromFormat(
Copy link
Member

Choose a reason for hiding this comment

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

The same here…

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same response as above -- this logic is intended to be this way and has backing unit tests added.

]
);
} elseif (isset($this->attributes['max']) &&
! \DateTime::createFromFormat(
Copy link
Member

Choose a reason for hiding this comment

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

…and here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See other responses. Again, intentional :-P

*/
protected function getStepValidator()
{
$format = $this->getFormat();
$format = $this->getFormat();
Copy link
Member

Choose a reason for hiding this comment

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

Please undo all code formatting changes.

@@ -124,8 +124,8 @@ public function testCorrectFormatPassedToDateValidator()
{
$element = new DateElement('foo');
$element->setAttributes([
'min' => '2012-01-01',
'max' => '2012-12-31',
'min' => '01-01-2012',
Copy link
Member

Choose a reason for hiding this comment

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

The first rule: Do not change existing unit tests! Changing a unit tests always means a change in behavior.

Can you explain the differences in the values?

Copy link
Contributor Author

@jackdpeterson jackdpeterson Apr 29, 2017

Choose a reason for hiding this comment

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

The change here is that right below this section is a setFormat(d-m-Y) ... which means that the previous behavior here would yield a broken scenario with values provided that do not properly construct a valid DateTime object -- something I didn't directly test with the Date element; however, since Date extends from DateTime element and uses the parent's methods this test is impacted. This is the behavior that was previously unhandled and the whole point of this PR -- the element expects a very specific format and when it doesn't get that format it fails silently rather than throwing exceptional conditions when handed garbage. If I'm going to keep this unit test mostly the same then I would make this test have an expectedException and create an additional test where the right date is provided and input is properly validated.

@@ -19,8 +19,8 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
$element = new DateTimeLocalElement('foo');
$element->setAttributes([
'inclusive' => true,
'min' => '2000-01-01T00:00Z',
'max' => '2001-01-01T00:00Z',
'min' => '2000-01-01T00:00',
Copy link
Member

Choose a reason for hiding this comment

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

The same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same story -- this is the format that the createFromFormat expects.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test was updated to be consistent w/ the documentation. Additional test added when an invalid min/max specification like the one above is added that would result in an InvalidArgumentException.

@@ -40,11 +40,11 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
switch ($class) {
case 'Zend\Validator\GreaterThan':
$this->assertTrue($validator->getInclusive());
$this->assertEquals('2000-01-01T00:00Z', $validator->getMin());
$this->assertEquals('2000-01-01T00:00', $validator->getMin());
Copy link
Member

Choose a reason for hiding this comment

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

The same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the format used in both the documentation and what conforms to the requested \DateTime::createFromFormat string.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test was updated to be consistent w/ the documentation. Additional test added when an invalid min/max specification like the one above is added that would result in an InvalidArgumentException.

Copy link
Member

Choose a reason for hiding this comment

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

I think the test changes make sense. The originals were based on an invalid assumption.

@@ -24,6 +24,8 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
'step' => '1',
]);

$element->setFormat('Y-m');
Copy link
Member

Choose a reason for hiding this comment

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

Why is this needed?

@@ -24,6 +25,8 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
'step' => '1',
]);

$element->setFormat('Y-\WW');
Copy link
Member

Choose a reason for hiding this comment

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

Why is this needed?

@jackdpeterson
Copy link
Contributor Author

I suppose there's also a broader conversation to be had about the changes that I'm implementing here. In the case of the setFormat() bits, I'm assuming that the min and max validation are to be ran off of the same format as the actual input format. This may be an incorrect approach. Rather, I think I'm going to modify this a little bit where the min and max MUST follow the convention for self::DATETIME_FORMAT = 'Y-m-d\TH:iP'; as was the case with my first pass prior to squashing in various other changes. The benefit of this approach would be that the date is always specified in a consistent manner rather than evaluated based on the then-current format.

Either way, the current implementation has problems and I think the above should be discussed. Locking down to one format for the min / max seems to be the most appropriate choice. Either way, unit tests must be modified.

@jackdpeterson jackdpeterson force-pushed the 158 branch 3 times, most recently from c871a5d to bc72ba9 Compare May 1, 2017 18:24
    DateTime, Date, Month element with 'min' or 'max' string specification(s) that does not conform
    to the expected \DateTime format for the given element rather than mysteriously fail when given
    valid data on input.
@jackdpeterson
Copy link
Contributor Author

jackdpeterson commented May 1, 2017

Branch updated w/ additional unit tests to reflect which scenarios fail. Also fixed one unit test related to the DateTimeLocalElement where an invalid specification was provided that was inconsistent w/ the documentation.

@jackdpeterson
Copy link
Contributor Author

Are there other comments on this PR or can we move this into the next minor release of Zend-Form?

@froschdesign
Copy link
Member

@jackdpeterson
Throw an exception is a new behaviour.
Can we cover the old and the new behaviour with unit tests to prevent any problems in existing applications / forms?

@jackdpeterson
Copy link
Contributor Author

@froschdesign -- see the changes for the tests folder. I also added a unit tests for specific areas where invalid specifications are provided.

@froschdesign
Copy link
Member

froschdesign commented May 8, 2017

Btw. if the documentation is wrong or a bug is included, then we must fix this. See:

$dateTimeLocal->setAttributes([
    'min'  => '2010-01-01T00:00:00',
    'max'  => '2020-01-01T00:00:00',
    'step' => '1', // minutes; default step interval is 1 min
]);
$dateTimeLocal->setOptions([
    'format' => 'Y-m-d\TH:i',
]);

https://docs.zendframework.com/zend-form/element/date-time-local/#basic-usage

'inclusive' => true,
]);
if (isset($this->attributes['min']) &&
\DateTime::createFromFormat(
Copy link
Member

Choose a reason for hiding this comment

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

Honestly, I agree with @froschdesign here. The same multiline statement is used in multiple conditions, making those conditions really hard to read. Capturing to a variable makes the conditions easier to read.

I can do that on merge.

@@ -40,11 +40,11 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
switch ($class) {
case 'Zend\Validator\GreaterThan':
$this->assertTrue($validator->getInclusive());
$this->assertEquals('2000-01-01T00:00Z', $validator->getMin());
$this->assertEquals('2000-01-01T00:00', $validator->getMin());
Copy link
Member

Choose a reason for hiding this comment

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

I think the test changes make sense. The originals were based on an invalid assumption.

@weierophinney weierophinney merged commit 22ba199 into zendframework:master May 18, 2017
weierophinney added a commit that referenced this pull request May 18, 2017
weierophinney added a commit that referenced this pull request May 18, 2017
Added a new method, `valueIsValidDateTimeFormat()`, that accepts a value
and then passes it to `DateTime::createFromFormat` with the current
instance's `DATETIME_FORMAT` in order to determine if a valid value is
returned.

The various new conditionals added in #159 are then modified to call on
this method instead of doing the calls inline. The result is less code,
and more readable conditionals.
weierophinney added a commit that referenced this pull request May 18, 2017
weierophinney added a commit that referenced this pull request May 18, 2017
weierophinney added a commit that referenced this pull request May 18, 2017
@weierophinney
Copy link
Member

Thanks, @jackdpeterson

@jackdpeterson jackdpeterson deleted the 158 branch June 2, 2017 22:46
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants