Skip to content

Commit b75a879

Browse files
committed
improved tests
1 parent ce70865 commit b75a879

File tree

3 files changed

+222
-0
lines changed

3 files changed

+222
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Utils\DateTime constructor __construct() method.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Nette\Utils\DateTime;
10+
use Tester\Assert;
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
date_default_timezone_set('Europe/Prague');
15+
16+
17+
test('Absolute date/time strings', function () {
18+
$dt = new DateTime('2024-08-20 14:30:00');
19+
Assert::same('2024-08-20 14:30:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'));
20+
21+
// Absolute format that might look relative
22+
$dt = new DateTime('2 january 2005');
23+
Assert::same('2005-01-02 00:00:00 CET (+01:00)', $dt->format('Y-m-d H:i:s T (P)'));
24+
});
25+
26+
27+
test('now', function () {
28+
$now = new DateTimeImmutable('now');
29+
30+
$dt = new DateTime('');
31+
Assert::true(abs($dt->getTimestamp() - $now->getTimestamp()) <= 1);
32+
33+
$dt = new DateTime('now');
34+
Assert::true(abs($dt->getTimestamp() - $now->getTimestamp()) <= 1);
35+
});
36+
37+
38+
test('Numeric relative strings (should use corrected modify logic)', function () {
39+
$nowTs = time();
40+
41+
$dt = new DateTime('+1 hour');
42+
// Expect time approximately one hour later than $nowTs
43+
Assert::true(abs($dt->getTimestamp() - ($nowTs + 3600)) <= 1);
44+
45+
$dt = new DateTime('- 2 days');
46+
// Allow slightly larger tolerance due to potential DST changes within the 2 days
47+
Assert::true(abs($dt->getTimestamp() - ($nowTs - 2 * 86400)) <= 2);
48+
49+
$dt = new DateTime(' +10 minutes '); // With spaces
50+
Assert::true(abs($dt->getTimestamp() - ($nowTs + 600)) <= 1);
51+
});
52+
53+
54+
test('Textual relative strings', function () {
55+
$dt = new DateTime('yesterday');
56+
$yesterdayRef = new DateTimeImmutable('yesterday');
57+
Assert::same($yesterdayRef->format('Y-m-d'), $dt->format('Y-m-d'));
58+
59+
$dt = new DateTime('next monday');
60+
$nextMondayRef = new DateTimeImmutable('next monday');
61+
Assert::same($nextMondayRef->format('Y-m-d'), $dt->format('Y-m-d'));
62+
63+
$dt = new DateTime('first day of next month');
64+
$firstNextRef = new DateTimeImmutable('first day of next month');
65+
Assert::same($firstNextRef->format('Y-m-d H:i:s'), $dt->format('Y-m-d H:i:s'));
66+
});
67+
68+
69+
test('Timezone handling', function () {
70+
$defaultTz = (new DateTime)->getTimezone();
71+
$utcTz = new DateTimeZone('UTC');
72+
73+
// 1. No timezone provided -> should use default
74+
$dt = new DateTime('2024-09-01 10:00:00');
75+
Assert::same($defaultTz->getName(), $dt->getTimezone()->getName(), 'Uses default timezone when null');
76+
77+
// 2. Explicit timezone provided -> should use provided
78+
$dt = new DateTime('2024-09-01 10:00:00', $utcTz);
79+
Assert::same($utcTz->getName(), $dt->getTimezone()->getName(), 'Uses provided timezone (UTC)');
80+
Assert::same('2024-09-01 10:00:00 UTC (+00:00)', $dt->format('Y-m-d H:i:s T (P)'));
81+
82+
// 3. Relative string, no timezone -> should use default
83+
$dt = new DateTime('+3 hours');
84+
Assert::same($defaultTz->getName(), $dt->getTimezone()->getName(), 'Relative string uses default timezone when null');
85+
86+
// 4. Relative string, explicit timezone -> should use provided
87+
$dt = new DateTime('+3 hours', $utcTz);
88+
Assert::same($utcTz->getName(), $dt->getTimezone()->getName(), 'Relative string uses provided timezone (UTC)');
89+
90+
// 5. Absolute string (date only), explicit timezone -> should use provided
91+
$dt = new DateTime('2024-11-11', $utcTz);
92+
Assert::same($utcTz->getName(), $dt->getTimezone()->getName(), 'Absolute date string uses provided timezone (UTC)');
93+
Assert::same('2024-11-11 00:00:00 UTC (+00:00)', $dt->format('Y-m-d H:i:s T (P)'));
94+
});
95+
96+
97+
test('Exception handling for invalid input', function () {
98+
Assert::exception(
99+
fn() => new DateTime('invalid date format'),
100+
Throwable::class,
101+
'%a%invalid date format%a%',
102+
);
103+
});

tests/Utils/DateTime.modify.phpt

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Utils\DateTime modify() method.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Nette\Utils\DateTime;
10+
use Tester\Assert;
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
date_default_timezone_set('Europe/Prague');
15+
16+
17+
test('Basic operations', function () {
18+
$base = new DateTime('2024-07-15 10:00:00'); // Summer time (CEST)
19+
20+
$dt = clone $base;
21+
$dt->modify('+30 minutes');
22+
Assert::same('2024-07-15 10:30:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), '+30 minutes');
23+
24+
$dt = clone $base;
25+
$dt->modify('+2 hours');
26+
Assert::same('2024-07-15 12:00:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), '+2 hours');
27+
28+
$dt = clone $base;
29+
$dt->modify('-5 days');
30+
Assert::same('2024-07-10 10:00:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), '-5 days');
31+
32+
$dt = new DateTime('2024-01-15 10:00:00'); // Winter time (CET)
33+
$dt->modify('+1 month');
34+
Assert::same('2024-02-15 10:00:00 CET (+01:00)', $dt->format('Y-m-d H:i:s T (P)'), '+1 month in winter');
35+
});
36+
37+
38+
test('Complex and varied format strings', function () {
39+
$dt = new DateTime('2024-04-10 12:00:00'); // CEST
40+
// Expected: -2m -> 2024-02-10 12:00 CET | +7d -> 2024-02-17 12:00 CET | +23h 59m 59s -> 2024-02-18 11:59:59 CET
41+
$dt->modify('- 2 months +7 days +23 hours +59 minutes +59 seconds');
42+
Assert::same('2024-02-18 11:59:59 CET (+01:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Complex mixed modification 1');
43+
44+
$dt = new DateTime('2024-01-10 15:00:00'); // CET
45+
$dt->modify(' 2days '); // Spaces and format variation
46+
Assert::same('2024-01-12 15:00:00 CET (+01:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Format " 2days "');
47+
48+
// Textual relative modifier
49+
$dt = new DateTime('2024-04-10 12:00:00'); // CEST
50+
$dt->modify('first day of next month noon');
51+
Assert::same('2024-05-01 12:00:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Textual relative modifier');
52+
53+
// Complex mixed modification 2 (year/month/day/hour/min)
54+
$dt = new DateTime('2023-11-20 08:30:00'); // CET
55+
// +1y -> 2024-11-20 08:30 CET | -3m -> 2024-08-20 08:30 CEST | +10d -> 2024-08-30 08:30 CEST | +5h -> 2024-08-30 13:30 CEST | -15min -> 2024-08-30 13:15 CEST
56+
$dt->modify('+1 year -3 months + 10 days + 5 hours - 15 minutes');
57+
Assert::same('2024-08-30 13:15:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Complex mixed modification 2');
58+
59+
// Extra spaces and singular unit
60+
$dt = new DateTime('2024-05-15 10:00:00'); // CEST
61+
$dt->modify('+ 2 days - 1hour'); // Extra spaces, 'hour' singular
62+
Assert::same('2024-05-17 09:00:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Extra spaces and singular unit');
63+
64+
// Seconds and milliseconds
65+
$dt = new DateTime('2024-06-01 12:00:00.000000'); // CEST, explicit microseconds
66+
$dt->modify('+3 sec - 500 milliseconds');
67+
Assert::same('2024-06-01 12:00:02.500000', $dt->format('Y-m-d H:i:s.u'), 'Seconds and milliseconds');
68+
Assert::same('CEST (+02:00)', $dt->format('T (P)'), 'Timezone check for ms test');
69+
70+
// Textual day + numeric hour
71+
$dt = new DateTime('2024-06-15 09:00:00'); // CEST (Saturday)
72+
// 'next sunday' -> 2024-06-16 00:00:00, '+ 4 hours' -> 2024-06-16 04:00:00
73+
$dt->modify('next sunday + 4 hours');
74+
Assert::same('2024-06-16 04:00:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Textual day + numeric hour');
75+
76+
// Textual time + numeric minute
77+
$dt = new DateTime('2024-06-15 09:00:00'); // CEST
78+
// 'noon' -> 12:00:00, '- 30 minutes' -> 11:30:00
79+
$dt->modify('noon - 30 minutes');
80+
Assert::same('2024-06-15 11:30:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Textual time + numeric minute');
81+
82+
// Zero value modifiers
83+
$dt = new DateTime('2024-05-05 05:05:05'); // CEST
84+
$dt->modify('+0 days - 0 hours + 0 seconds');
85+
Assert::same('2024-05-05 05:05:05 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Zero value modifiers');
86+
87+
// Microsecond addition
88+
$dt = new DateTime('2024-07-01 10:20:30.123456'); // CEST
89+
$dt->modify('+ 100 usecs');
90+
Assert::same('2024-07-01 10:20:30.123556', $dt->format('Y-m-d H:i:s.u'), 'Microsecond addition');
91+
Assert::same('CEST (+02:00)', $dt->format('T (P)'), 'Timezone check for usec test');
92+
93+
// Chained textual modifiers
94+
$dt = new DateTime('2024-03-10 10:00:00'); // CET
95+
// 'first day of may' -> 2024-05-01 00:00 | 'noon' -> 2024-05-01 12:00
96+
$dt->modify('first day of may 2024 noon');
97+
Assert::same('2024-05-01 12:00:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'), 'Chained textual modifiers');
98+
});
99+
100+
101+
test('Invalid modifier format exceptions', function () {
102+
if (PHP_VERSION_ID < 80300) {
103+
Assert::error(
104+
fn() => (new DateTime)->modify('+'),
105+
E_WARNING,
106+
'DateTime::modify(): Failed to parse time string (+) at position 0 (+): Unexpected character',
107+
);
108+
} else {
109+
Assert::error(
110+
fn() => (new DateTime)->modify('+'),
111+
DateMalformedStringException::class,
112+
'DateTime::modify(): Failed to parse time string (+) at position 0 (+): Unexpected character',
113+
);
114+
}
115+
});

tests/Utils/Image.send.phpt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ require __DIR__ . '/../bootstrap.php';
1616

1717
$main = Image::fromFile(__DIR__ . '/fixtures.images/alpha1.png');
1818

19+
ob_start(); // test descriptions
1920

2021
test('sending image as JPEG by default', function () use ($main) {
2122
ob_start();
23+
header_remove();
2224
$main->send();
2325
$data = ob_get_clean();
2426

@@ -31,6 +33,7 @@ test('sending image as JPEG by default', function () use ($main) {
3133

3234
test('sending image as PNG', function () use ($main) {
3335
ob_start();
36+
header_remove();
3437
$main->send(Image::PNG);
3538
$data = ob_get_clean();
3639

@@ -47,6 +50,7 @@ test('sending WEBP image if supported', function () use ($main) {
4750
}
4851

4952
ob_start();
53+
header_remove();
5054
$main->send(Image::WEBP);
5155
$data = ob_get_clean();
5256

0 commit comments

Comments
 (0)