Skip to content
This repository was archived by the owner on Dec 6, 2022. It is now read-only.

Commit e65ae5a

Browse files
TimeToogoElliot Levin
authored andcommitted
Change identity hash to hash instances of \DateTimeInterface by class and timestamp hence treating it as a value type throughout the PINQ API
1 parent e528d48 commit e65ae5a

File tree

15 files changed

+279
-24
lines changed

15 files changed

+279
-24
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ dev
44
- Fix bug when attempting to parse function with a magic scope parameter type hint (eg `function (self $param) { ... }`.
55
- Implement `Analysis\TolerantExpressionAnalyser` which will convert analysis exceptions into the *mixed* type.
66
- Add `Providers\DSL\Compilation\Parameters\ParameterCollection::contains` to check whether the collection contains a parameter.
7-
- Add `Providers\DSL\Compilation\Parameters\ParameterCollection::remove` to remove a previously added parameter.\
7+
- Add `Providers\DSL\Compilation\Parameters\ParameterCollection::remove` to remove a previously added parameter.
88
- Introduce `Analysis\INativeType::TYPE_NUMERIC` acting as a union type for `Analysis\INativeType::TYPE_INT` and `Analysis\INativeType::TYPE_DOUBLE`
9+
- Change identity hash to hash instances of `DateTimeInterface` by class and timestamp hence treating it as a value type throughout the PINQ API
910

1011
3.1.0 (29/3/15)
1112
===============

Source/Iterators/Common/Identity.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ public static function hash($value)
4545

4646
case 'o': //object
4747

48-
return 'o' . spl_object_hash($value);
48+
return $value instanceof \DateTimeInterface || $value instanceof \DateTime
49+
? 'dt:' . get_class($value) . ':' . $value->getTimestamp()
50+
: 'o' . spl_object_hash($value);
4951

5052
case 'a': //array
5153

Tests/Helpers/ExtendedDateTime.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Pinq\Tests\Helpers;
4+
5+
/**
6+
*
7+
* @author Elliot Levin <[email protected]>
8+
*/
9+
class ExtendedDateTime extends \DateTime
10+
{
11+
12+
}

Tests/Integration/Collection/GroupJoinApplyTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,33 @@ public function testThatApplyGroupJoinWithDefaultValueOperatedCorrectly(\Pinq\IC
149149
'10:1,3,5,7,9,11,13,15,17,19',
150150
]);
151151
}
152+
153+
/**
154+
* @dataProvider oneToTen
155+
*/
156+
public function testThatOnEqualityWillNotMatchNullsAndUseDefault(\Pinq\ICollection $collection, array $data)
157+
{
158+
$collection
159+
->groupJoin($collection)
160+
->onEquality(
161+
function ($i) { return $i % 2 === 0 ? $i : null; },
162+
function ($i) { return $i % 2 === 0 ? $i : null; })
163+
->withDefault('<DEFAULT>')
164+
->apply(function (&$outer, \Pinq\ITraversable $innerGroup) {
165+
$outer .= ':' . $innerGroup->implode('-');
166+
});
167+
168+
$this->assertMatches($collection, [
169+
'1:<DEFAULT>',
170+
'2:2',
171+
'3:<DEFAULT>',
172+
'4:4',
173+
'5:<DEFAULT>',
174+
'6:6',
175+
'7:<DEFAULT>',
176+
'8:8',
177+
'9:<DEFAULT>',
178+
'10:10'
179+
]);
180+
}
152181
}

Tests/Integration/Collection/JoinApplyTest.php

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -206,31 +206,25 @@ function ($i) { return $i % 2 === 0 ? $i : null; })
206206
}
207207

208208
/**
209-
* @dataProvider oneToTen
209+
* @dataProvider emptyData
210210
*/
211-
public function testThatOnEqualityWillNotMatchNullsAndUseDefault(\Pinq\ICollection $collection, array $data)
211+
public function testThatOnEqualityWillPassForValueWiseIdenticalDateTimes(\Pinq\ICollection $collection, array $data)
212212
{
213+
$dateTime = new \DateTime('2-1-2001');
214+
$anotherDateTime = new \DateTime('2-1-2000');
215+
$collection[] = $dateTime;
216+
$collection[] = $anotherDateTime;
217+
213218
$collection
214-
->groupJoin($collection)
215-
->onEquality(
216-
function ($i) { return $i % 2 === 0 ? $i : null; },
217-
function ($i) { return $i % 2 === 0 ? $i : null; })
218-
->withDefault('<DEFAULT>')
219-
->apply(function (&$outer, \Pinq\ITraversable $innerGroup) {
220-
$outer .= ':' . $innerGroup->implode('-');
219+
->join([$dateTime])
220+
->onEquality(function ($outer) { return $outer; }, function ($inner) { return $inner; })
221+
->apply(function (&$outer) {
222+
$outer = '<MATCHED>';
221223
});
222224

223-
$this->assertMatches($collection, [
224-
'1:<DEFAULT>',
225-
'2:2',
226-
'3:<DEFAULT>',
227-
'4:4',
228-
'5:<DEFAULT>',
229-
'6:6',
230-
'7:<DEFAULT>',
231-
'8:8',
232-
'9:<DEFAULT>',
233-
'10:10'
225+
$this->assertMatchesValues($collection, [
226+
'<MATCHED>',
227+
$anotherDateTime
234228
]);
235229
}
236230
}

Tests/Integration/Collection/RemoveTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,20 @@ public function testThatRemoveWillRemovesIdenticalValuesFromCollectionAndPreserv
3333

3434
$this->assertMatchesValues($collection, $data);
3535
}
36+
37+
/**
38+
* @dataProvider dateTimes
39+
*/
40+
public function testRemovesDateTimeClassesByValueRatherThenReference(
41+
\Pinq\ICollection $collection,
42+
array $data
43+
) {
44+
$originalCount = $collection->count();
45+
$dateTime = $collection[2];
46+
47+
$collection->remove($dateTime);
48+
49+
$this->assertCount($originalCount - 1, $collection);
50+
$this->assertNotContains($dateTime, $collection);
51+
}
3652
}

Tests/Integration/Collection/SetIndexTest.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function testThatSettingAnIndexWillOverrideTheElementInTheCollection(\Pin
2424
}
2525

2626
/**
27-
* @dataProvider everything
27+
* @dataProvider emptyData
2828
*/
2929
public function testThatSetIndexWithNoKeyAppendsTheValueWithTheNextLargestIntGreaterThanOrEqualToZeroLikeAnArray(\Pinq\ICollection $collection, array $data)
3030
{
@@ -53,4 +53,21 @@ public function testThatSetIndexWithNoKeyAppendsTheValueWithTheNextLargestIntGre
5353

5454
$this->assertSame('boo', $collection[1]);
5555
}
56+
57+
/**
58+
* @dataProvider emptyData
59+
*/
60+
public function testThatDateTimeIndexesAreComparedByValue(\Pinq\ICollection $collection, array $data)
61+
{
62+
$dateTime = new \DateTime('2-1-2001');
63+
$anotherDateTime = new \DateTime('2-1-2000');
64+
65+
$collection[$dateTime] = 1;
66+
$collection[$anotherDateTime] = 2;
67+
$collection[clone $anotherDateTime] = 3;
68+
69+
$this->assertSame(1, $collection[$dateTime]);
70+
$this->assertSame(3, $collection[$anotherDateTime]);
71+
$this->assertSame(3, $collection[clone $anotherDateTime]);
72+
}
5673
}

Tests/Integration/Collection/UnsetIndexTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,22 @@ public function testThatUnsetingAnIndexWillRemoveTheElementFromTheCollection(\Pi
2020

2121
$this->assertMatches($collection, $data);
2222
}
23+
24+
/**
25+
* @dataProvider emptyData
26+
*/
27+
public function testThatDateTimeIndexesAreComparedByValue(\Pinq\ICollection $collection, array $data)
28+
{
29+
$dateTime = new \DateTime('2-1-2001');
30+
$anotherDateTime = new \DateTime('2-1-2000');
31+
32+
$collection[$dateTime] = 1;
33+
$collection[$anotherDateTime] = 2;
34+
unset($collection[new \DateTime('2-1-2000')]);
35+
36+
$this->assertTrue(isset($collection[$dateTime]));
37+
$this->assertFalse(isset($collection[$anotherDateTime]));
38+
$this->assertFalse(isset($collection[clone $anotherDateTime]));
39+
$this->assertFalse(isset($collection[new \DateTime('2-1-2000')]));
40+
}
2341
}

Tests/Integration/DataTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public function everything()
2828
'oneToTenTwice',
2929
'assocOneToTen',
3030
'tenRandomStrings',
31-
'assocMixedValues'
31+
'assocMixedValues',
32+
'dateTimes'
3233
];
3334

3435
foreach ($dataProviders as $provider) {
@@ -106,6 +107,17 @@ public function assocTenRandomStrings()
106107
return $this->getImplementations(array_combine($this->randomStrings(10), $this->randomStrings(10)));
107108
}
108109

110+
public function dateTimes()
111+
{
112+
return $this->getImplementations(iterator_to_array(
113+
new \DatePeriod(
114+
new \DateTime('1-1-2000'),
115+
new \DateInterval('P4M'),
116+
new \DateTime('2-3-2004')
117+
)
118+
));
119+
}
120+
109121
private function randomStrings($amount)
110122
{
111123
$letters = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890-!@#$%^&*()_';

Tests/Integration/Traversable/GetIndexTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,26 @@ public function testThatIndexesSupportArrayKeys(\Pinq\ITraversable $traversable,
6161
'Should be using strict equality for arrays (order matters)');
6262
}
6363
}
64+
65+
/**
66+
* @dataProvider emptyData
67+
*/
68+
public function testThatDateTimeIndexesAreComparedByValueAndClass(\Pinq\ITraversable $traversable, array $data)
69+
{
70+
$dateTime = new \DateTime('2-1-2001');
71+
$anotherDateTime = new \DateTime('2-1-2000');
72+
73+
$traversable = $traversable
74+
->append([$dateTime, $anotherDateTime])
75+
->indexBy(function ($value) { return $value; })
76+
->select(function (\DateTime $dateTime) { return $dateTime->format('j-n-Y'); });
77+
78+
$this->assertSame('2-1-2001', $traversable[$dateTime]);
79+
$this->assertSame('2-1-2001', $traversable[clone $dateTime]);
80+
$this->assertSame('2-1-2001', $traversable[new \DateTime('2-1-2001')]);
81+
82+
if(class_exists('DateTimeImmutable', false)) {
83+
$this->assertNull($traversable[new \DateTimeImmutable('2-1-2001')]);
84+
}
85+
}
6486
}

0 commit comments

Comments
 (0)