Skip to content

Commit 63387ee

Browse files
committed
Merge branch 'v2.x' into v3.x
2 parents 49a636e + 24ebb0f commit 63387ee

16 files changed

+466
-15
lines changed

Date.php

+23-7
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,20 @@ class Date
7676
*/
7777
public static function createFromTimestamp(int $timestamp, ?string $timezone = null): self
7878
{
79-
// Timestamp based
80-
return new self(
79+
$serverTimezone = date_default_timezone_get();
80+
if ($timezone) {
81+
date_default_timezone_set($timezone);
82+
}
83+
84+
$params = [
8185
date('Y', $timestamp), date('m', $timestamp), date('d', $timestamp), date('H', $timestamp),
8286
date('i', $timestamp),
8387
date('s', $timestamp),
8488
$timezone
85-
);
89+
];
90+
date_default_timezone_set($serverTimezone);
91+
92+
return new self(...$params);
8693
}
8794

8895
/**
@@ -109,18 +116,27 @@ public static function createFromNow(?string $timezone = null): self
109116
*/
110117
public static function createFromString(string $date, ?string $timezone = null): self
111118
{
119+
// Timestamp based
120+
$serverTimezone = date_default_timezone_get();
121+
if ($timezone) {
122+
date_default_timezone_set($timezone);
123+
}
124+
112125
if (str_contains($date, '-') && str_contains($date, '/')) {
113126
throw new InvalidDateException('Invalid date string - ' . $date);
114127
}
115128
if (strtotime($date) === false) {
116129
throw new InvalidDateException('Invalid date string - ' . $date);
117130
}
118-
$date = date('Y-m-d H:i:s', strtotime($date));
131+
$date = date('Y-m-d H:i:s', strtotime($date . ' ' . ($timezone ?: '')));
119132

120-
return new self(
133+
$params = [
121134
substr($date, 0, 4), substr($date, 5, 2), substr($date, 8, 2), substr($date, 11, 2),
122-
substr($date, 14, 2), substr($date, 17, 2), $timezone
123-
);
135+
substr($date, 14, 2), substr($date, 17, 2), $timezone];
136+
137+
date_default_timezone_set($serverTimezone);
138+
139+
return new self(...$params);
124140
}
125141

126142
/**

Deferred.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2023 Jeremy Presutti <[email protected]>
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
declare(strict_types=1);
20+
21+
namespace Feast;
22+
abstract class Deferred
23+
{
24+
protected bool $cancelled = false;
25+
abstract public function deferredAction(): void;
26+
27+
public function __destruct()
28+
{
29+
if ( $this->cancelled === false ) {
30+
$this->deferredAction();
31+
}
32+
}
33+
34+
/**
35+
* Cancel this deferred call.
36+
* @return void
37+
*/
38+
public final function cancelDeferral(): void
39+
{
40+
$this->cancelled = true;
41+
}
42+
}

DeferredCall.php

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2023 Jeremy Presutti <[email protected]>
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
declare(strict_types=1);
20+
21+
namespace Feast;
22+
class DeferredCall extends Deferred
23+
{
24+
protected bool $cancelled = false;
25+
26+
/** @var callable|null $callable */
27+
protected $callable = null;
28+
public function deferredAction(): void {
29+
/** @var callable $callable */
30+
$callable = $this->callable;
31+
$callable();
32+
}
33+
34+
public function __construct(callable $callable)
35+
{
36+
$this->callable = $callable;
37+
}
38+
}

FeastTests/DateTest.php

+25
Original file line numberDiff line numberDiff line change
@@ -510,4 +510,29 @@ public function testTimezones(): void
510510
$date->setTimezone('America/Chicago');
511511
$this->assertEquals('2020-07-13 05:39:52', $date->getFormattedDate());
512512
}
513+
514+
public function testCreateFromTimestampMatch()
515+
{
516+
$timestamp = 1634567890;
517+
$date = Date::createFromTimestamp($timestamp, 'America/New_York');
518+
$dateTime = $date->getAsDateTime();
519+
$this->assertEquals($timestamp, $dateTime->getTimestamp());
520+
}
521+
522+
public function testCreateFromFormatTimestampMatch()
523+
{
524+
$timestamp = 1634567890;
525+
$date = Date::createFromFormat('U',(string)$timestamp, 'America/New_York');
526+
$dateTime = $date->getAsDateTime();
527+
$this->assertEquals($timestamp, $dateTime->getTimestamp());
528+
}
529+
530+
public function testCreateFromStringDateMatch()
531+
{
532+
$timestamp = '1970/01/02 01:02:03';
533+
$date = Date::createFromString($timestamp, 'America/Chicago');
534+
$dateTime = $date->getAsDateTime();
535+
$this->assertEquals($timestamp, $dateTime->format('Y/m/d H:i:s'));
536+
$this->assertEquals(111723, $dateTime->getTimestamp());
537+
}
513538
}

FeastTests/DeferredTest.php

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2023 Jeremy Presutti <[email protected]>
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
declare(strict_types=1);
20+
21+
use PHPUnit\Framework\TestCase;
22+
23+
class DeferredTest extends TestCase
24+
{
25+
public function testDeferredMethod(): void
26+
{
27+
$this->deferredTester();
28+
$output = $this->getActualOutputForAssertion();
29+
$this->assertEquals('This is firstThis is second', $output);
30+
}
31+
32+
public function testCancelledDeferredMethod(): void
33+
{
34+
$this->deferredTester(true);
35+
$output = $this->getActualOutputForAssertion();
36+
$this->assertEquals('This is first', $output);
37+
}
38+
39+
public function testDeferredCallable(): void
40+
{
41+
$this->deferredCallableTester();
42+
$output = $this->getActualOutputForAssertion();
43+
$this->assertEquals('This is firstThis is second', $output);
44+
}
45+
46+
public function testDeferredCallableEnsureOrder(): void
47+
{
48+
$this->deferredCallableTesterEnsureProcessingOrder();
49+
$output = $this->getActualOutputForAssertion();
50+
$this->assertEquals('This is firstThis is second', $output);
51+
}
52+
53+
public function testCancelledDeferredCallable(): void
54+
{
55+
$this->deferredCallableTester(true);
56+
$output = $this->getActualOutputForAssertion();
57+
$this->assertEquals('This is first', $output);
58+
}
59+
60+
protected function deferredTester(bool $cancel = false): void
61+
{
62+
$deferred = new \Mocks\DeferredMock('This is second');
63+
echo 'This is first';
64+
if ( $cancel ) {
65+
$deferred->cancelDeferral();
66+
}
67+
}
68+
69+
protected function deferredCallableTester(bool $cancel = false): void
70+
{
71+
$deferred = new \Feast\DeferredCall(function() { echo 'This is second'; });
72+
echo 'This is first';
73+
if ( $cancel ) {
74+
$deferred->cancelDeferral();
75+
}
76+
}
77+
78+
protected function deferredCallableTesterEnsureProcessingOrder(bool $cancel = false): void
79+
{
80+
$output = 'This is second';
81+
$deferred = new \Feast\DeferredCall(function() use ($output) { echo $output; });
82+
$output = 'This is not second';
83+
echo 'This is first';
84+
if ( $cancel ) {
85+
$deferred->cancelDeferral();
86+
}
87+
}
88+
89+
}

FeastTests/HttpRequest/CurlTest.php

+67
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,73 @@ public function testGetResponseCode(): void
210210
);
211211
}
212212

213+
public function testGetResponseContentType(): void
214+
{
215+
$request = new Curl();
216+
$request->get('https://www.google.com/json');
217+
$request->makeRequest();
218+
$response = $request->getResponse();
219+
$this->assertEquals('application/json', $request->getResponseContentType());
220+
$this->assertEquals('application/json; charset=UTF-8', $response->getContentTypeHeader());
221+
$this->assertNull(
222+
$request->getResponseAsXml()
223+
);
224+
}
225+
226+
public function testGetResponseContentTypeNoRequestMade(): void
227+
{
228+
$request = new Curl();
229+
$request->get('https://www.google.com/json');
230+
$response = $request->getResponse();
231+
$this->assertNull($request->getResponseContentType());
232+
$this->assertNull(
233+
$request->getResponseAsXml()
234+
);
235+
}
236+
237+
public function testGetHeaderContentType(): void
238+
{
239+
$request = new Curl();
240+
$request->get('https://www.google.com/json');
241+
$request->makeRequest();
242+
$this->assertEquals('application/json', $request->getResponseHeader('Content-Type'));
243+
$this->assertNull(
244+
$request->getResponseAsXml()
245+
);
246+
}
247+
248+
public function testGetHeader(): void
249+
{
250+
$request = new Curl();
251+
$request->get('https://www.google.com/json');
252+
$request->makeRequest();
253+
$this->assertEquals('no-cache', $request->getResponseHeader('Pragma'));
254+
$this->assertNull(
255+
$request->getResponseAsXml()
256+
);
257+
}
258+
259+
public function testGetHeaderNoRequestMade(): void
260+
{
261+
$request = new Curl();
262+
$request->get('https://www.google.com/json');
263+
$this->assertNull($request->getResponseHeader('Pragma'));
264+
$this->assertNull(
265+
$request->getResponseAsXml()
266+
);
267+
}
268+
269+
public function testGetHeaderMulti(): void
270+
{
271+
$request = new Curl();
272+
$request->get('https://www.google.com/json');
273+
$request->makeRequest();
274+
$this->assertEquals('no-store, no-cache, must-revalidate', $request->getResponseHeader('Cache-Control'));
275+
$this->assertNull(
276+
$request->getResponseAsXml()
277+
);
278+
}
279+
213280
public function testGetResultAsJson(): void
214281
{
215282
$request = new Curl();

FeastTests/Mocks/Curl.mock

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function curl_exec($handle)
5959
return str_replace(PHP_EOL,"\n",\file_get_contents(__DIR__ . '/SampleResponses/GetXml.txt'));
6060
}
6161
if (str_contains($handle->url, 'https://www.google.com/json')) {
62-
$handle->length = 338;
62+
$handle->length = 352;
6363
return str_replace(PHP_EOL,"\n",\file_get_contents(__DIR__ . '/SampleResponses/GetJson.txt'));
6464
}
6565
return false;

FeastTests/Mocks/DeferredMock.php

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2023 Jeremy Presutti <[email protected]>
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
declare(strict_types=1);
20+
21+
namespace Mocks;
22+
23+
use Feast\Deferred;
24+
25+
class DeferredMock extends Deferred
26+
{
27+
28+
public function __construct(public string $echo)
29+
{
30+
31+
}
32+
33+
public function deferredAction(): void
34+
{
35+
echo $this->echo;
36+
}
37+
}

FeastTests/Mocks/SampleResponses/GetJson.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ Date: Sun, 31 Jan 2021 00:31:57 GMT
33
Server: Apache/2.4.18 (Ubuntu)
44
Set-Cookie: user=mdmpd0d58gqpktf10h4dt67dkc; path=/
55
Expires: Thu, 19 Nov 1981 08:52:00 GMT
6-
Cache-Control: no-store, no-cache, must-revalidate
6+
Cache-Control: no-store, no-cache
7+
Cache-Control: must-revalidate
78
Pragma: no-cache
89
Vary: Accept-Encoding
910
Transfer-Encoding: chunked

0 commit comments

Comments
 (0)