-
Notifications
You must be signed in to change notification settings - Fork 87
Conversation
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. |
fc3e5ff
to
b520f1a
Compare
src/Element/DateTime.php
Outdated
@@ -53,7 +54,6 @@ class DateTime extends Element implements InputProviderInterface | |||
public function setOptions($options) | |||
{ | |||
parent::setOptions($options); | |||
|
There was a problem hiding this comment.
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.
src/Element/DateTime.php
Outdated
@@ -81,6 +81,7 @@ public function getValue($returnFormattedValue = true) | |||
return $value; | |||
} | |||
$format = $this->getFormat(); | |||
|
There was a problem hiding this comment.
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.
src/Element/DateTime.php
Outdated
@@ -92,7 +93,8 @@ public function getValue($returnFormattedValue = true) | |||
*/ | |||
public function setFormat($format) | |||
{ | |||
$this->format = (string) $format; | |||
$this->format = (string)$format; |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createFromFormat
here…
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same here…
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…and here.
There was a problem hiding this comment.
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
src/Element/DateTime.php
Outdated
*/ | ||
protected function getStepValidator() | ||
{ | ||
$format = $this->getFormat(); | ||
$format = $this->getFormat(); |
There was a problem hiding this comment.
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.
test/Element/DateTest.php
Outdated
@@ -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', |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same here.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same here.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
test/Element/MonthTest.php
Outdated
@@ -24,6 +24,8 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri | |||
'step' => '1', | |||
]); | |||
|
|||
$element->setFormat('Y-m'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed?
test/Element/WeekTest.php
Outdated
@@ -24,6 +25,8 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri | |||
'step' => '1', | |||
]); | |||
|
|||
$element->setFormat('Y-\WW'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed?
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. |
c871a5d
to
bc72ba9
Compare
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.
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. |
Are there other comments on this PR or can we move this into the next minor release of Zend-Form? |
@jackdpeterson |
@froschdesign -- see the changes for the tests folder. I also added a unit tests for specific areas where invalid specifications are provided. |
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( |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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.
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.
Thanks, @jackdpeterson |
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.