Skip to content

Commit b29dcb9

Browse files
committed
Fixed specification members not being cloned before passed to collection members.
1 parent 098de60 commit b29dcb9

File tree

2 files changed

+44
-61
lines changed

2 files changed

+44
-61
lines changed

src/Porter.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public function __construct()
6060
*/
6161
public function import(ImportSpecification $specification)
6262
{
63+
$specification = clone $specification;
6364
$records = $this->fetch($specification->getResource(), $specification->getCacheAdvice());
6465

6566
if (!$records instanceof ProviderRecords) {
@@ -74,15 +75,15 @@ public function import(ImportSpecification $specification)
7475
$records = $this->map($records, $specification->getMapping(), $specification->getContext());
7576
}
7677

77-
return $this->createPorterRecords($records, clone $specification);
78+
return $this->createPorterRecords($records, $specification);
7879
}
7980

8081
/**
8182
* Imports one record according to the design of the specified import specification.
8283
*
8384
* @param ImportSpecification $specification Import specification.
8485
*
85-
* @return array Record.
86+
* @return array|null Record.
8687
*
8788
* @throws ImportException More than one record was imported.
8889
*/

test/Integration/Porter/PorterTest.php

Lines changed: 41 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use ScriptFUSION\Porter\Cache\CacheToggle;
1010
use ScriptFUSION\Porter\Cache\CacheUnavailableException;
1111
use ScriptFUSION\Porter\Collection\CountableMappedRecords;
12-
use ScriptFUSION\Porter\Collection\CountableProviderRecords;
1312
use ScriptFUSION\Porter\Collection\FilteredRecords;
1413
use ScriptFUSION\Porter\Collection\MappedRecords;
1514
use ScriptFUSION\Porter\Collection\PorterRecords;
@@ -47,7 +46,9 @@ protected function setUp()
4746
$this->provider =
4847
\Mockery::mock(Provider::class)
4948
->shouldReceive('fetch')
50-
->andReturn(new \ArrayIterator(['foo']))
49+
->andReturnUsing(function () {
50+
yield 'foo';
51+
})
5152
->byDefault()
5253
->getMock()
5354
);
@@ -56,6 +57,8 @@ protected function setUp()
5657
$this->specification = new ImportSpecification($this->resource);
5758
}
5859

60+
#region Providers
61+
5962
public function testGetProvider()
6063
{
6164
self::assertSame($this->provider, $this->porter->getProvider(get_class($this->provider)));
@@ -115,29 +118,21 @@ public function testHasProvider()
115118
self::assertFalse($this->porter->hasProvider('foo'));
116119
}
117120

118-
public function testImport()
119-
{
120-
$records = $this->porter->import($this->specification);
121+
#endregion
121122

122-
self::assertInstanceOf(PorterRecords::class, $records);
123-
self::assertNotSame($this->specification, $records->getSpecification());
124-
self::assertInstanceOf(CountableProviderRecords::class, $records->getPreviousCollection());
125-
self::assertSame('foo', $records->current());
126-
}
123+
#region Import
127124

128-
public function testNonCountableIteratorImport()
125+
public function testImport()
129126
{
130-
$this->provider->shouldReceive('fetch')->andReturnUsing(function () {
131-
yield 'foo';
132-
});
133-
134127
$records = $this->porter->import($this->specification);
135128

136129
self::assertInstanceOf(PorterRecords::class, $records);
137-
self::assertNotSame($this->specification, $records->getSpecification());
138-
self::assertInstanceOf(ProviderRecords::class, $records->getPreviousCollection());
139-
self::assertNotInstanceOf(CountableProviderRecords::class, $records->getPreviousCollection());
130+
self::assertNotSame($this->specification, $records->getSpecification(), 'Specification was not cloned.');
140131
self::assertSame('foo', $records->current());
132+
133+
/** @var ProviderRecords $previous */
134+
self::assertInstanceOf(ProviderRecords::class, $previous = $records->getPreviousCollection());
135+
self::assertNotSame($this->resource, $previous->getResource(), 'Resource was not cloned.');
141136
}
142137

143138
/**
@@ -146,9 +141,7 @@ public function testNonCountableIteratorImport()
146141
public function testImportCountableRecords()
147142
{
148143
$records = $this->porter->import(
149-
new StaticDataImportSpecification(
150-
new CountableProviderRecords(\Mockery::mock(\Iterator::class), $count = rand(1, 9), $this->resource)
151-
)
144+
new StaticDataImportSpecification(new \ArrayIterator(range(1, $count = 10)))
152145
);
153146

154147
// Innermost collection.
@@ -160,23 +153,6 @@ public function testImportCountableRecords()
160153
self::assertCount($count, $records);
161154
}
162155

163-
public function testImportAndMapNonCountableRecords()
164-
{
165-
$iterateOne = function () {
166-
yield 'foo';
167-
};
168-
$records = $this->porter->import(
169-
(new StaticDataImportSpecification(
170-
new ProviderRecords($iterateOne(), $this->resource)
171-
))->setMapping(\Mockery::mock(Mapping::class))
172-
);
173-
174-
self::assertInstanceOf(MappedRecords::class, $records->getPreviousCollection());
175-
self::assertInstanceOf(\Iterator::class, $records);
176-
self::assertNotInstanceOf(CountableMappedRecords::class, $records->getPreviousCollection());
177-
self::assertNotInstanceOf(\Countable::class, $records);
178-
}
179-
180156
/**
181157
* Tests that when the resource is countable the count is propagated to the outermost collection via a mapped
182158
* collection.
@@ -185,7 +161,7 @@ public function testImportAndMapCountableRecords()
185161
{
186162
$records = $this->porter->import(
187163
(new StaticDataImportSpecification(
188-
new CountableProviderRecords(\Mockery::mock(\Iterator::class), $count = rand(1, 9), $this->resource)
164+
new \ArrayIterator(range(1, $count = 10))
189165
))->setMapping(\Mockery::mock(Mapping::class))
190166
);
191167

@@ -201,7 +177,7 @@ public function testImportAndFilterCountableRecords()
201177
{
202178
$records = $this->porter->import(
203179
(new StaticDataImportSpecification(
204-
new CountableProviderRecords(\Mockery::mock(\Iterator::class), $count = rand(1, 9), $this->resource)
180+
new \ArrayIterator(range(1, $count = 10))
205181
))->setFilter([$this, __FUNCTION__])
206182
);
207183

@@ -212,6 +188,30 @@ public function testImportAndFilterCountableRecords()
212188
self::assertNotInstanceOf(\Countable::class, $records);
213189
}
214190

191+
public function testImportTaggedResource()
192+
{
193+
$this->porter->registerProvider(
194+
$provider = \Mockery::mock(Provider::class)
195+
->shouldReceive('fetch')
196+
->andReturn(new \ArrayIterator([$output = 'bar']))
197+
->getMock(),
198+
$tag = 'foo'
199+
);
200+
201+
$records = $this->porter->import(MockFactory::mockImportSpecification(
202+
MockFactory::mockResource($provider)
203+
->shouldReceive('getProviderTag')
204+
->andReturn($tag)
205+
->getMock()
206+
));
207+
208+
self::assertSame($output, $records->current());
209+
}
210+
211+
#endregion
212+
213+
#region Import one
214+
215215
public function testImportOne()
216216
{
217217
$result = $this->porter->importOne($this->specification);
@@ -237,25 +237,7 @@ public function testImportOneOfMany()
237237
$this->porter->importOne($this->specification);
238238
}
239239

240-
public function testImportTaggedResource()
241-
{
242-
$this->porter->registerProvider(
243-
$provider = \Mockery::mock(Provider::class)
244-
->shouldReceive('fetch')
245-
->andReturn(new \ArrayIterator([$output = 'bar']))
246-
->getMock(),
247-
$tag = 'foo'
248-
);
249-
250-
$records = $this->porter->import(MockFactory::mockImportSpecification(
251-
MockFactory::mockResource($provider)
252-
->shouldReceive('getProviderTag')
253-
->andReturn($tag)
254-
->getMock()
255-
));
256-
257-
self::assertSame($output, $records->current());
258-
}
240+
#endregion
259241

260242
public function testFilter()
261243
{

0 commit comments

Comments
 (0)