[CLEANUP] Replace strlen() with === for zero length check
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Property / TypeConverter / DateTimeConverterTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
3
4 /* *
5 * This script belongs to the Extbase framework. *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License as published by the *
9 * Free Software Foundation, either version 3 of the License, or (at your *
10 * option) any later version. *
11 * *
12 * This script is distributed in the hope that it will be useful, but *
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
14 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
15 * General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with the script. *
19 * If not, see http://www.gnu.org/licenses/lgpl.html *
20 * *
21 * The TYPO3 project - inspiring people to share! *
22 * */
23
24 /**
25 * Test case
26 */
27 class DateTimeConverterTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
28
29 /**
30 * @var \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter
31 */
32 protected $converter;
33
34 public function setUp() {
35 $this->converter = new \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter();
36 }
37
38 /**
39 * @test
40 */
41 public function checkMetadata() {
42 $this->assertEquals(array('string', 'integer', 'array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
43 $this->assertEquals('DateTime', $this->converter->getSupportedTargetType(), 'Target type does not match');
44 $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
45 }
46
47
48 /** String to DateTime testcases **/
49
50 /**
51 * @test
52 */
53 public function canConvertFromReturnsFalseIfTargetTypeIsNotDateTime() {
54 $this->assertFalse($this->converter->canConvertFrom('Foo', 'SomeOtherType'));
55 }
56
57 /**
58 * @test
59 */
60 public function canConvertFromReturnsTrueIfSourceTypeIsAString() {
61 $this->assertTrue($this->converter->canConvertFrom('Foo', 'DateTime'));
62 }
63
64 /**
65 * @test
66 */
67 public function canConvertFromReturnsTrueIfSourceTypeIsAnEmptyString() {
68 $this->assertTrue($this->converter->canConvertFrom('', 'DateTime'));
69 }
70
71 /**
72 * @test
73 */
74 public function convertFromReturnsErrorIfGivenStringCantBeConverted() {
75 $error = $this->converter->convertFrom('1980-12-13', 'DateTime');
76 $this->assertInstanceOf(\TYPO3\CMS\Extbase\Error\Error::class, $error);
77 }
78
79 /**
80 * @test
81 */
82 public function convertFromProperlyConvertsStringWithDefaultDateFormat() {
83 $expectedResult = '1980-12-13T20:15:07+01:23';
84 $date = $this->converter->convertFrom($expectedResult, 'DateTime');
85 $actualResult = $date->format('Y-m-d\\TH:i:sP');
86 $this->assertSame($expectedResult, $actualResult);
87 }
88
89 /**
90 * @test
91 */
92 public function convertFromUsesDefaultDateFormatIfItIsNotConfigured() {
93 $expectedResult = '1980-12-13T20:15:07+01:23';
94 $mockMappingConfiguration = $this->getMock(\TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface::class);
95 $mockMappingConfiguration
96 ->expects($this->atLeastOnce())
97 ->method('getConfigurationValue')
98 ->with(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
99 ->will($this->returnValue(NULL));
100
101 $date = $this->converter->convertFrom($expectedResult, 'DateTime', array(), $mockMappingConfiguration);
102 $actualResult = $date->format(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT);
103 $this->assertSame($expectedResult, $actualResult);
104 }
105
106 /**
107 * @test
108 */
109 public function convertFromEmptyStringReturnsNull() {
110 $date = $this->converter->convertFrom('', 'DateTime', array(), NULL);
111 $this->assertNull($date);
112 }
113
114 /**
115 * @return array
116 * @see convertFromStringTests()
117 */
118 public function convertFromStringDataProvider() {
119 return array(
120 array('1308174051', '', FALSE),
121 array('13-12-1980', 'd.m.Y', FALSE),
122 array('1308174051', 'Y-m-d', FALSE),
123 array('12:13', 'H:i', TRUE),
124 array('13.12.1980', 'd.m.Y', TRUE),
125 array('2005-08-15T15:52:01+00:00', NULL, TRUE),
126 array('2005-08-15T15:52:01+0000', \DateTime::ISO8601, TRUE),
127 array('1308174051', 'U', TRUE),
128 );
129 }
130
131 /**
132 * @param string $source the string to be converted
133 * @param string $dateFormat the expected date format
134 * @param bool $isValid TRUE if the conversion is expected to be successful, otherwise FALSE
135 * @test
136 * @dataProvider convertFromStringDataProvider
137 */
138 public function convertFromStringTests($source, $dateFormat, $isValid) {
139 if ($dateFormat !== NULL) {
140 $mockMappingConfiguration = $this->getMock(\TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface::class);
141 $mockMappingConfiguration
142 ->expects($this->atLeastOnce())
143 ->method('getConfigurationValue')
144 ->with(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
145 ->will($this->returnValue($dateFormat));
146 } else {
147 $mockMappingConfiguration = NULL;
148 }
149 $date = $this->converter->convertFrom($source, 'DateTime', array(), $mockMappingConfiguration);
150 if ($isValid !== TRUE) {
151 $this->assertInstanceOf(\TYPO3\CMS\Extbase\Error\Error::class, $date);
152 return;
153 }
154 $this->assertInstanceOf('DateTime', $date);
155
156 if ($dateFormat === NULL) {
157 $dateFormat = \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT;
158 }
159 $this->assertSame($source, $date->format($dateFormat));
160 }
161
162 /**
163 * @return array
164 * @see convertFromIntegerOrDigitStringWithoutConfigurationTests()
165 * @see convertFromIntegerOrDigitStringInArrayWithoutConfigurationTests()
166 */
167 public function convertFromIntegerOrDigitStringsWithoutConfigurationDataProvider() {
168 return array(
169 array('1308174051'),
170 array(1308174051),
171 );
172 }
173
174 /**
175 * @test
176 * @param $source
177 * @dataProvider convertFromIntegerOrDigitStringsWithoutConfigurationDataProvider
178 */
179 public function convertFromIntegerOrDigitStringWithoutConfigurationTests($source) {
180 $date = $this->converter->convertFrom($source, 'DateTime', array(), NULL);
181 $this->assertInstanceOf('DateTime', $date);
182 $this->assertSame(strval($source), $date->format('U'));
183
184 }
185
186 /** Array to DateTime testcases **/
187
188 /**
189 * @test
190 * @param $source
191 * @dataProvider convertFromIntegerOrDigitStringsWithoutConfigurationDataProvider
192 */
193 public function convertFromIntegerOrDigitStringInArrayWithoutConfigurationTests($source) {
194 $date = $this->converter->convertFrom(array('date' => $source), 'DateTime', array(), NULL);
195 $this->assertInstanceOf('DateTime', $date);
196 $this->assertSame(strval($source), $date->format('U'));
197
198 }
199
200 /**
201 * @test
202 */
203 public function canConvertFromReturnsTrueIfSourceTypeIsAnArray() {
204 $this->assertTrue($this->converter->canConvertFrom(array(), 'DateTime'));
205 }
206
207 /**
208 * @test
209 */
210 public function convertFromReturnsErrorIfGivenArrayCantBeConverted() {
211 $error = $this->converter->convertFrom(array('date' => '1980-12-13'), 'DateTime');
212 $this->assertInstanceOf(\TYPO3\CMS\Extbase\Error\Error::class, $error);
213 }
214
215 /**
216 * @test
217 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
218 */
219 public function convertFromThrowsExceptionIfGivenArrayDoesNotSpecifyTheDate() {
220 $this->converter->convertFrom(array('hour' => '12', 'minute' => '30'), 'DateTime');
221 }
222
223 /**
224 * @test
225 */
226 public function convertFromProperlyConvertsArrayWithDefaultDateFormat() {
227 $expectedResult = '1980-12-13T20:15:07+01:23';
228 $date = $this->converter->convertFrom(array('date' => $expectedResult), 'DateTime');
229 $actualResult = $date->format('Y-m-d\\TH:i:sP');
230 $this->assertSame($expectedResult, $actualResult);
231 }
232
233 /**
234 * @return array
235 * @see convertFromThrowsExceptionIfDatePartKeysHaveInvalidValuesSpecified
236 */
237 public function invalidDatePartKeyValuesDataProvider() {
238 return array(
239 array(array('day' => '13.0', 'month' => '10', 'year' => '2010')),
240 array(array('day' => '13', 'month' => '10.0', 'year' => '2010')),
241 array(array('day' => '13', 'month' => '10', 'year' => '2010.0')),
242 array(array('day' => '-13', 'month' => '10', 'year' => '2010')),
243 array(array('day' => '13', 'month' => '-10', 'year' => '2010')),
244 array(array('day' => '13', 'month' => '10', 'year' => '-2010')),
245 );
246 }
247
248 /**
249 * @test
250 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
251 * @dataProvider invalidDatePartKeyValuesDataProvider
252 */
253 public function convertFromThrowsExceptionIfDatePartKeysHaveInvalidValuesSpecified($source) {
254 $this->converter->convertFrom($source, 'DateTime');
255 }
256
257 /**
258 * @test
259 */
260 public function convertFromProperlyConvertsArrayWithDateAsArray() {
261 $source = array('day' => '13', 'month' => '10', 'year' => '2010');
262 $mappingConfiguration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
263 $mappingConfiguration->setTypeConverterOption(
264 \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::class,
265 \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT,
266 'Y-m-d'
267 );
268
269 $date = $this->converter->convertFrom($source, 'DateTime', array(), $mappingConfiguration);
270 $actualResult = $date->format('Y-m-d');
271 $this->assertSame('2010-10-13', $actualResult);
272 }
273
274 /**
275 * @test
276 */
277 public function convertFromAllowsToOverrideTheTime() {
278 $source = array(
279 'date' => '2011-06-16',
280 'dateFormat' => 'Y-m-d',
281 'hour' => '12',
282 'minute' => '30',
283 'second' => '59',
284 );
285 $date = $this->converter->convertFrom($source, 'DateTime');
286 $this->assertSame('2011-06-16', $date->format('Y-m-d'));
287 $this->assertSame('12', $date->format('H'));
288 $this->assertSame('30', $date->format('i'));
289 $this->assertSame('59', $date->format('s'));
290 }
291
292 /**
293 * @test
294 */
295 public function convertFromAllowsToOverrideTheTimezone() {
296 $source = array(
297 'date' => '2011-06-16 12:30:59',
298 'dateFormat' => 'Y-m-d H:i:s',
299 'timezone' => 'Atlantic/Reykjavik',
300 );
301 $date = $this->converter->convertFrom($source, 'DateTime');
302 $this->assertSame('2011-06-16', $date->format('Y-m-d'));
303 $this->assertSame('12', $date->format('H'));
304 $this->assertSame('30', $date->format('i'));
305 $this->assertSame('59', $date->format('s'));
306 $this->assertSame('Atlantic/Reykjavik', $date->getTimezone()->getName());
307 }
308
309 /**
310 * @test
311 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
312 */
313 public function convertFromThrowsExceptionIfSpecifiedTimezoneIsInvalid() {
314 $source = array(
315 'date' => '2011-06-16',
316 'dateFormat' => 'Y-m-d',
317 'timezone' => 'Invalid/Timezone',
318 );
319 $this->converter->convertFrom($source, 'DateTime');
320 }
321
322 /**
323 * @test
324 * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
325 */
326 public function convertFromArrayThrowsExceptionForEmptyArray() {
327 $this->converter->convertFrom(array(), 'DateTime', array(), NULL);
328 }
329
330 /**
331 * @test
332 */
333 public function convertFromArrayReturnsNullForEmptyDate() {
334 $this->assertNull($this->converter->convertFrom(array('date' => ''), 'DateTime', array(), NULL));
335 }
336
337 /**
338 * @return array
339 * @see convertFromArrayTests()
340 */
341 public function convertFromArrayDataProvider() {
342 return array(
343 array(array('date' => '2005-08-15T15:52:01+01:00'), TRUE),
344 array(array('date' => '1308174051', 'dateFormat' => ''), FALSE),
345 array(array('date' => '13-12-1980', 'dateFormat' => 'd.m.Y'), FALSE),
346 array(array('date' => '1308174051', 'dateFormat' => 'Y-m-d'), FALSE),
347 array(array('date' => '12:13', 'dateFormat' => 'H:i'), TRUE),
348 array(array('date' => '13.12.1980', 'dateFormat' => 'd.m.Y'), TRUE),
349 array(array('date' => '2005-08-15T15:52:01+00:00', 'dateFormat' => ''), TRUE),
350 array(array('date' => '2005-08-15T15:52:01+0000', 'dateFormat' => \DateTime::ISO8601), TRUE),
351 array(array('date' => '1308174051', 'dateFormat' => 'U'), TRUE),
352 array(array('date' => 1308174051, 'dateFormat' => 'U'), TRUE),
353 );
354 }
355
356 /**
357 * @param array $source the array to be converted
358 * @param bool $isValid TRUE if the conversion is expected to be successful, otherwise FALSE
359 * @test
360 * @dataProvider convertFromArrayDataProvider
361 */
362 public function convertFromArrayTests(array $source, $isValid) {
363 $dateFormat = isset($source['dateFormat']) && $source['dateFormat'] !== '' ? $source['dateFormat'] : NULL;
364 if ($dateFormat !== NULL) {
365 $mockMappingConfiguration = $this->getMock(\TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface::class);
366 $mockMappingConfiguration
367 ->expects($this->atLeastOnce())
368 ->method('getConfigurationValue')
369 ->with(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
370 ->will($this->returnValue($dateFormat));
371 } else {
372 $mockMappingConfiguration = NULL;
373 }
374 $date = $this->converter->convertFrom($source, 'DateTime', array(), $mockMappingConfiguration);
375
376 if ($isValid !== TRUE) {
377 $this->assertInstanceOf(\TYPO3\CMS\Extbase\Error\Error::class, $date);
378 return;
379 }
380
381 $this->assertInstanceOf('DateTime', $date);
382 if ($dateFormat === NULL) {
383 $dateFormat = \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT;
384 }
385 $dateAsString = isset($source['date']) ? strval($source['date']) : '';
386 $this->assertSame($dateAsString, $date->format($dateFormat));
387 }
388
389 /**
390 * @test
391 */
392 public function convertFromSupportsDateTimeSubClasses() {
393 $className = 'DateTimeSubClass' . md5(uniqid(mt_rand(), TRUE));
394 eval('
395 class ' . $className . ' extends \\DateTime {
396 public static function createFromFormat($format, $time, $timezone = NULL) {
397 return new ' . $className . '();
398 }
399 public function foo() { return "Bar"; }
400 }
401 ');
402 $date = $this->converter->convertFrom('2005-08-15T15:52:01+00:00', $className);
403
404 $this->assertInstanceOf($className, $date);
405 $this->assertSame('Bar', $date->foo());
406 }
407
408 }