Skip to content

Commit 6925bc1

Browse files
authored
Merge pull request #33 from chadicus/fea/collection-subset
Add Collection::select()
2 parents dfbc0dd + 5a66b2f commit 6925bc1

2 files changed

Lines changed: 117 additions & 10 deletions

File tree

src/Collection.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,20 @@ public function column($key)
200200
yield Util\Arrays::get($item, $key);
201201
}
202202
}
203+
204+
/**
205+
* Return an iterable generator containing only the fields specified in the $keys array.
206+
*
207+
* @param array $keys The list of field names to be returned.
208+
*
209+
* @return \Generator
210+
*/
211+
public function select(array $keys)
212+
{
213+
foreach ($this as $item) {
214+
$result = array_fill_keys($keys, null);
215+
Util\Arrays::copyIfKeysExist($item, $result, $keys);
216+
yield $result;
217+
}
218+
}
203219
}

tests/CollectionTest.php

Lines changed: 101 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,107 @@ public function column()
259259
iterator_to_array($collection->column('key'))
260260
);
261261
}
262+
263+
/**
264+
* Verifies basic behavior of select().
265+
*
266+
* @test
267+
* @covers ::select
268+
*
269+
* @return void
270+
*/
271+
public function select()
272+
{
273+
$authentication = Authentication::createClientCredentials('not under test', 'not under test');
274+
$client = new Client(new CollectionAdapter(), $authentication, 'not under test');
275+
$collection = new Collection($client, 'basic', ['limit' => 3]);
276+
$this->assertSame(
277+
[
278+
['key' => 0],
279+
['key' => 1],
280+
['key' => 2],
281+
['key' => 3],
282+
['key' => 4],
283+
],
284+
iterator_to_array($collection->select(['key']))
285+
);
286+
}
287+
288+
/**
289+
* Verifies behavior of select() with multiple keys.
290+
*
291+
* @test
292+
* @covers ::select
293+
*
294+
* @return void
295+
*/
296+
public function selectMultipleKeys()
297+
{
298+
$adapter = new CollectionAdapter();
299+
$adapter->results = [
300+
['id' => 1, 'name' => 'Sam', 'score' => 99],
301+
['id' => 2, 'name' => 'Bob', 'score' => 83],
302+
['id' => 3, 'name' => 'Jon', 'score' => 75],
303+
['id' => 4, 'name' => 'Ted', 'score' => 64],
304+
];
305+
$authentication = Authentication::createClientCredentials('not under test', 'not under test');
306+
$client = new Client($adapter, $authentication, 'not under test');
307+
$collection = new Collection($client, 'basic', ['limit' => 3]);
308+
$this->assertSame(
309+
[
310+
['id' => 1, 'score' => 99],
311+
['id' => 2, 'score' => 83],
312+
['id' => 3, 'score' => 75],
313+
['id' => 4, 'score' => 64],
314+
],
315+
iterator_to_array($collection->select(['id', 'score']))
316+
);
317+
}
318+
319+
/**
320+
* Verifies behavior of select() when results have missing keys.
321+
*
322+
* @test
323+
* @covers ::select
324+
*
325+
* @return void
326+
*/
327+
public function selectMissingKeys()
328+
{
329+
$adapter = new CollectionAdapter();
330+
$adapter->results = [
331+
['id' => 1, 'name' => 'Sam', 'score' => 99],
332+
['id' => 2, 'name' => 'Bob'],
333+
['id' => 3, 'name' => 'Jon', 'score' => 75],
334+
['id' => 4, 'score' => 64],
335+
];
336+
$authentication = Authentication::createClientCredentials('not under test', 'not under test');
337+
$client = new Client($adapter, $authentication, 'not under test');
338+
$collection = new Collection($client, 'basic', ['limit' => 3]);
339+
$this->assertSame(
340+
[
341+
['name' => 'Sam', 'score' => 99],
342+
['name' => 'Bob', 'score' => null],
343+
['name' => 'Jon', 'score' => 75],
344+
['name' => null, 'score' => 64],
345+
],
346+
iterator_to_array($collection->select(['name', 'score']))
347+
);
348+
}
262349
}
263350

264351
final class CollectionAdapter implements Adapter
265352
{
266353
private $_request;
267354

355+
public $results = [
356+
['id' => '0', 'key' => 0],
357+
['id' => '1', 'key' => 1],
358+
['id' => '2', 'key' => 2],
359+
['id' => '3', 'key' => 3],
360+
['id' => '4', 'key' => 4],
361+
];
362+
268363
public function start(Request $request)
269364
{
270365
$this->_request = $request;
@@ -293,14 +388,6 @@ public function end($handle)
293388
}
294389

295390
if (substr_count($this->_request->getUrl(), '/basic') === 1) {
296-
$results = [
297-
['id' => '0', 'key' => 0],
298-
['id' => '1', 'key' => 1],
299-
['id' => '2', 'key' => 2],
300-
['id' => '3', 'key' => 3],
301-
['id' => '4', 'key' => 4],
302-
];
303-
304391
$queryString = parse_url($this->_request->getUrl(), PHP_URL_QUERY);
305392
$queryParams = [];
306393
parse_str($queryString, $queryParams);
@@ -309,8 +396,12 @@ public function end($handle)
309396
$limit = (int)$queryParams['limit'];
310397

311398
$result = [
312-
'pagination' => ['offset' => $offset, 'total' => 5, 'limit' => $limit],
313-
'result' => array_slice($results, $offset, $limit),
399+
'pagination' => [
400+
'offset' => $offset,
401+
'total' => count($this->results),
402+
'limit' => min($limit, count($this->results)),
403+
],
404+
'result' => array_slice($this->results, $offset, $limit),
314405
];
315406

316407
return new Response(200, ['Content-Type' => ['application/json']], $result);

0 commit comments

Comments
 (0)