1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the OverblogGraphQLBundle package. |
5
|
|
|
* |
6
|
|
|
* (c) Overblog <http://github.com/overblog/> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Overblog\GraphQLBundle\Tests\Relay\Connection\Output; |
13
|
|
|
|
14
|
|
|
use Overblog\GraphQLBundle\Relay\Connection\Output\Connection; |
15
|
|
|
use Overblog\GraphQLBundle\Relay\Connection\Output\ConnectionBuilder; |
16
|
|
|
use Overblog\GraphQLBundle\Relay\Connection\Output\PageInfo; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Class ConnectionBuilderTest. |
20
|
|
|
* |
21
|
|
|
* @see https://github.com/graphql/graphql-relay-js/blob/master/src/connection/__tests__/arrayconnection.js |
22
|
|
|
*/ |
23
|
|
|
class ConnectionBuilderTest extends AbstractConnectionBuilderTest |
24
|
|
|
{ |
25
|
|
View Code Duplication |
public function testBasicSlicing() |
|
|
|
|
26
|
|
|
{ |
27
|
|
|
$actual = ConnectionBuilder::connectionFromArray($this->letters); |
28
|
|
|
|
29
|
|
|
$expected = $this->getExpectedConnection($this->letters, false, false); |
30
|
|
|
|
31
|
|
|
$this->assertEquals($expected, $actual); |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
public function testRespectsASmallerFirst() |
35
|
|
|
{ |
36
|
|
|
$actual = ConnectionBuilder::connectionFromArray($this->letters, ['first' => 2]); |
37
|
|
|
|
38
|
|
|
$expected = $this->getExpectedConnection(['A', 'B'], false, true); |
39
|
|
|
|
40
|
|
|
$this->assertEquals($expected, $actual); |
41
|
|
|
} |
42
|
|
|
|
43
|
|
View Code Duplication |
public function testRespectsAnOverlyLargeFirst() |
|
|
|
|
44
|
|
|
{ |
45
|
|
|
$actual = ConnectionBuilder::connectionFromArray($this->letters, ['first' => 10]); |
46
|
|
|
|
47
|
|
|
$expected = $this->getExpectedConnection($this->letters, false, false); |
48
|
|
|
|
49
|
|
|
$this->assertEquals($expected, $actual); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
public function testRespectsASmallerLast() |
53
|
|
|
{ |
54
|
|
|
$actual = ConnectionBuilder::connectionFromArray($this->letters, ['last' => 2]); |
55
|
|
|
|
56
|
|
|
$expected = $this->getExpectedConnection(['D', 'E'], true, false); |
57
|
|
|
|
58
|
|
|
$this->assertEquals($expected, $actual); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
View Code Duplication |
public function testRespectsAnOverlyLargeLast() |
|
|
|
|
62
|
|
|
{ |
63
|
|
|
$actual = ConnectionBuilder::connectionFromArray($this->letters, ['last' => 10]); |
64
|
|
|
|
65
|
|
|
$expected = $this->getExpectedConnection($this->letters, false, false); |
66
|
|
|
|
67
|
|
|
$this->assertEquals($expected, $actual); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
public function testRespectsFirstAndAfter() |
71
|
|
|
{ |
72
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
73
|
|
|
$this->letters, |
74
|
|
|
['first' => 2, 'after' => 'YXJyYXljb25uZWN0aW9uOjE='] |
75
|
|
|
); |
76
|
|
|
|
77
|
|
|
$expected = $this->getExpectedConnection(['C', 'D'], false, true); |
78
|
|
|
|
79
|
|
|
$this->assertEquals($expected, $actual); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
View Code Duplication |
public function testRespectsFirstAndAfterWithLongFirst() |
|
|
|
|
83
|
|
|
{ |
84
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
85
|
|
|
$this->letters, |
86
|
|
|
['first' => 10, 'after' => 'YXJyYXljb25uZWN0aW9uOjE='] |
87
|
|
|
); |
88
|
|
|
|
89
|
|
|
$expected = $this->getExpectedConnection(['C', 'D', 'E'], false, false); |
90
|
|
|
|
91
|
|
|
$this->assertEquals($expected, $actual); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
public function testRespectsLastAndBefore() |
95
|
|
|
{ |
96
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
97
|
|
|
$this->letters, |
98
|
|
|
['last' => 2, 'before' => 'YXJyYXljb25uZWN0aW9uOjM='] |
99
|
|
|
); |
100
|
|
|
|
101
|
|
|
$expected = $this->getExpectedConnection(['B', 'C'], true, false); |
102
|
|
|
|
103
|
|
|
$this->assertEquals($expected, $actual); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
View Code Duplication |
public function testRespectsLastAndBeforeWithLongLast() |
|
|
|
|
107
|
|
|
{ |
108
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
109
|
|
|
$this->letters, |
110
|
|
|
['last' => 10, 'before' => 'YXJyYXljb25uZWN0aW9uOjM='] |
111
|
|
|
); |
112
|
|
|
|
113
|
|
|
$expected = $this->getExpectedConnection(['A', 'B', 'C'], false, false); |
114
|
|
|
|
115
|
|
|
$this->assertEquals($expected, $actual); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
View Code Duplication |
public function testRespectsFirstAndAfterAndBeforeTooFew() |
|
|
|
|
119
|
|
|
{ |
120
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
121
|
|
|
$this->letters, |
122
|
|
|
['first' => 2, 'after' => 'YXJyYXljb25uZWN0aW9uOjA=', 'before' => 'YXJyYXljb25uZWN0aW9uOjQ='] |
123
|
|
|
); |
124
|
|
|
|
125
|
|
|
$expected = $this->getExpectedConnection(['B', 'C'], false, true); |
126
|
|
|
|
127
|
|
|
$this->assertEquals($expected, $actual); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
View Code Duplication |
public function testRespectsFirstAndAfterAndBeforeTooMany() |
|
|
|
|
131
|
|
|
{ |
132
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
133
|
|
|
$this->letters, |
134
|
|
|
['first' => 4, 'after' => 'YXJyYXljb25uZWN0aW9uOjA=', 'before' => 'YXJyYXljb25uZWN0aW9uOjQ='] |
135
|
|
|
); |
136
|
|
|
|
137
|
|
|
$expected = $this->getExpectedConnection(['B', 'C', 'D'], false, false); |
138
|
|
|
|
139
|
|
|
$this->assertEquals($expected, $actual); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
View Code Duplication |
public function testRespectsFirstAndAfterAndBeforeExactlyRight() |
|
|
|
|
143
|
|
|
{ |
144
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
145
|
|
|
$this->letters, |
146
|
|
|
['first' => 3, 'after' => 'YXJyYXljb25uZWN0aW9uOjA=', 'before' => 'YXJyYXljb25uZWN0aW9uOjQ='] |
147
|
|
|
); |
148
|
|
|
|
149
|
|
|
$expected = $this->getExpectedConnection(['B', 'C', 'D'], false, false); |
150
|
|
|
|
151
|
|
|
$this->assertEquals($expected, $actual); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
View Code Duplication |
public function testRespectsLastAndAfterAndBeforeTooFew() |
|
|
|
|
155
|
|
|
{ |
156
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
157
|
|
|
$this->letters, |
158
|
|
|
['last' => 2, 'after' => 'YXJyYXljb25uZWN0aW9uOjA=', 'before' => 'YXJyYXljb25uZWN0aW9uOjQ='] |
159
|
|
|
); |
160
|
|
|
|
161
|
|
|
$expected = $this->getExpectedConnection(['C', 'D'], true, false); |
162
|
|
|
|
163
|
|
|
$this->assertEquals($expected, $actual); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
View Code Duplication |
public function testRespectsLastAndAfterAndBeforeTooMany() |
|
|
|
|
167
|
|
|
{ |
168
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
169
|
|
|
$this->letters, |
170
|
|
|
['last' => 4, 'after' => 'YXJyYXljb25uZWN0aW9uOjA=', 'before' => 'YXJyYXljb25uZWN0aW9uOjQ='] |
171
|
|
|
); |
172
|
|
|
|
173
|
|
|
$expected = $this->getExpectedConnection(['B', 'C', 'D'], false, false); |
174
|
|
|
|
175
|
|
|
$this->assertEquals($expected, $actual); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
View Code Duplication |
public function testRespectsLastAndAfterAndBeforeExactlyRight() |
|
|
|
|
179
|
|
|
{ |
180
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
181
|
|
|
$this->letters, |
182
|
|
|
['last' => 3, 'after' => 'YXJyYXljb25uZWN0aW9uOjA=', 'before' => 'YXJyYXljb25uZWN0aW9uOjQ='] |
183
|
|
|
); |
184
|
|
|
|
185
|
|
|
$expected = $this->getExpectedConnection(['B', 'C', 'D'], false, false); |
186
|
|
|
|
187
|
|
|
$this->assertEquals($expected, $actual); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* @expectedException \InvalidArgumentException |
192
|
|
|
* @expectedExceptionMessage Argument "first" must be a non-negative integer |
193
|
|
|
*/ |
194
|
|
|
public function testThrowsAnErrorIfFirstLessThan0() |
195
|
|
|
{ |
196
|
|
|
ConnectionBuilder::connectionFromArray( |
197
|
|
|
$this->letters, |
198
|
|
|
['first' => -1] |
199
|
|
|
); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* @expectedException \InvalidArgumentException |
204
|
|
|
* @expectedExceptionMessage Argument "last" must be a non-negative integer |
205
|
|
|
*/ |
206
|
|
|
public function testThrowsAnErrorIfLastLessThan0() |
207
|
|
|
{ |
208
|
|
|
ConnectionBuilder::connectionFromArray( |
209
|
|
|
$this->letters, |
210
|
|
|
['last' => -1] |
211
|
|
|
); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
public function testReturnsNoElementsIfFirstIs0() |
215
|
|
|
{ |
216
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
217
|
|
|
$this->letters, |
218
|
|
|
['first' => 0] |
219
|
|
|
); |
220
|
|
|
|
221
|
|
|
$expected = new Connection( |
222
|
|
|
[ |
223
|
|
|
], |
224
|
|
|
new PageInfo(null, null, false, true) |
225
|
|
|
); |
226
|
|
|
|
227
|
|
|
$this->assertEquals($expected, $actual); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
public function testReturnsAllElementsIfCursorsAreInvalid() |
231
|
|
|
{ |
232
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
233
|
|
|
$this->letters, |
234
|
|
|
['before' => 'invalid', 'after' => 'invalid'] |
235
|
|
|
); |
236
|
|
|
|
237
|
|
|
$expected = $this->getExpectedConnection($this->letters, false, false); |
238
|
|
|
|
239
|
|
|
$this->assertEquals($expected, $actual); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
public function testReturnsAllElementsIfCursorsAreOnTheOutside() |
243
|
|
|
{ |
244
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
245
|
|
|
$this->letters, |
246
|
|
|
['before' => 'YXJyYXljb25uZWN0aW9uOjYK', 'after' => 'YXJyYXljb25uZWN0aW9uOi0xCg=='] |
247
|
|
|
); |
248
|
|
|
|
249
|
|
|
$expected = $this->getExpectedConnection($this->letters, false, false); |
250
|
|
|
|
251
|
|
|
$this->assertEquals($expected, $actual); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
public function testReturnsNoElementsIfCursorsCross() |
255
|
|
|
{ |
256
|
|
|
$actual = ConnectionBuilder::connectionFromArray( |
257
|
|
|
$this->letters, |
258
|
|
|
['before' => 'YXJyYXljb25uZWN0aW9uOjI=', 'after' => 'YXJyYXljb25uZWN0aW9uOjQ='] |
259
|
|
|
); |
260
|
|
|
|
261
|
|
|
$expected = $this->getExpectedConnection([], false, false); |
262
|
|
|
|
263
|
|
|
$this->assertEquals($expected, $actual); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* transcript of JS implementation test : works with a just-right array slice. |
268
|
|
|
*/ |
269
|
|
View Code Duplication |
public function testWorksWithAJustRightArraySlice() |
|
|
|
|
270
|
|
|
{ |
271
|
|
|
$actual = ConnectionBuilder::connectionFromArraySlice( |
272
|
|
|
array_slice($this->letters, 1, 2), // equals to letters.slice(1,3) in JS |
273
|
|
|
['first' => 2, 'after' => 'YXJyYXljb25uZWN0aW9uOjA='], |
274
|
|
|
['sliceStart' => 1, 'arrayLength' => 5] |
275
|
|
|
); |
276
|
|
|
|
277
|
|
|
$expected = $this->getExpectedConnection(['B', 'C'], false, true); |
278
|
|
|
|
279
|
|
|
$this->assertEquals($expected, $actual); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
/** |
283
|
|
|
* transcript of JS implementation test : works with an oversized array slice ("left" side). |
284
|
|
|
*/ |
285
|
|
View Code Duplication |
public function testWorksWithAnOversizedArraySliceLeftSide() |
|
|
|
|
286
|
|
|
{ |
287
|
|
|
$actual = ConnectionBuilder::connectionFromArraySlice( |
288
|
|
|
array_slice($this->letters, 0, 3), // equals to letters.slice(0,3) in JS |
289
|
|
|
['first' => 2, 'after' => 'YXJyYXljb25uZWN0aW9uOjA='], |
290
|
|
|
['sliceStart' => 0, 'arrayLength' => 5] |
291
|
|
|
); |
292
|
|
|
|
293
|
|
|
$expected = $this->getExpectedConnection(['B', 'C'], false, true); |
294
|
|
|
|
295
|
|
|
$this->assertEquals($expected, $actual); |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* transcript of JS implementation test : works with an oversized array slice ("right" side). |
300
|
|
|
*/ |
301
|
|
View Code Duplication |
public function testWorksWithAnOversizedArraySliceRightSide() |
|
|
|
|
302
|
|
|
{ |
303
|
|
|
$actual = ConnectionBuilder::connectionFromArraySlice( |
304
|
|
|
array_slice($this->letters, 2, 2), // equals to letters.slice(2,4) in JS |
305
|
|
|
['first' => 1, 'after' => 'YXJyYXljb25uZWN0aW9uOjE='], |
306
|
|
|
['sliceStart' => 2, 'arrayLength' => 5] |
307
|
|
|
); |
308
|
|
|
|
309
|
|
|
$expected = $this->getExpectedConnection(['C'], false, true); |
310
|
|
|
|
311
|
|
|
$this->assertEquals($expected, $actual); |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
/** |
315
|
|
|
* transcript of JS implementation test : works with an oversized array slice (both sides). |
316
|
|
|
*/ |
317
|
|
View Code Duplication |
public function testWorksWithAnOversizedArraySliceBothSides() |
|
|
|
|
318
|
|
|
{ |
319
|
|
|
$actual = ConnectionBuilder::connectionFromArraySlice( |
320
|
|
|
array_slice($this->letters, 1, 3), // equals to letters.slice(1,4) in JS |
321
|
|
|
['first' => 1, 'after' => 'YXJyYXljb25uZWN0aW9uOjE='], |
322
|
|
|
['sliceStart' => 1, 'arrayLength' => 5] |
323
|
|
|
); |
324
|
|
|
|
325
|
|
|
$expected = $this->getExpectedConnection(['C'], false, true); |
326
|
|
|
|
327
|
|
|
$this->assertEquals($expected, $actual); |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
/** |
331
|
|
|
* transcript of JS implementation test : works with an undersized array slice ("left" side). |
332
|
|
|
*/ |
333
|
|
View Code Duplication |
public function testWorksWithAnUndersizedArraySliceLeftSide() |
|
|
|
|
334
|
|
|
{ |
335
|
|
|
$actual = ConnectionBuilder::connectionFromArraySlice( |
336
|
|
|
array_slice($this->letters, 3, 2), // equals to letters.slice(3,5) in JS |
337
|
|
|
['first' => 3, 'after' => 'YXJyYXljb25uZWN0aW9uOjE='], |
338
|
|
|
['sliceStart' => 3, 'arrayLength' => 5] |
339
|
|
|
); |
340
|
|
|
|
341
|
|
|
$expected = $this->getExpectedConnection(['D', 'E'], false, false); |
342
|
|
|
|
343
|
|
|
$this->assertEquals($expected, $actual); |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* transcript of JS implementation test : works with an undersized array slice ("right" side). |
348
|
|
|
*/ |
349
|
|
View Code Duplication |
public function testWorksWithAnUndersizedArraySliceRightSide() |
|
|
|
|
350
|
|
|
{ |
351
|
|
|
$actual = ConnectionBuilder::connectionFromArraySlice( |
352
|
|
|
array_slice($this->letters, 2, 2), // equals to letters.slice(2,4) in JS |
353
|
|
|
['first' => 3, 'after' => 'YXJyYXljb25uZWN0aW9uOjE='], |
354
|
|
|
['sliceStart' => 2, 'arrayLength' => 5] |
355
|
|
|
); |
356
|
|
|
|
357
|
|
|
$expected = $this->getExpectedConnection(['C', 'D'], false, true); |
358
|
|
|
|
359
|
|
|
$this->assertEquals($expected, $actual); |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
/** |
363
|
|
|
* transcript of JS implementation test : works with an undersized array slice (both sides). |
364
|
|
|
*/ |
365
|
|
View Code Duplication |
public function worksWithAnUndersizedArraySliceBothSides() |
|
|
|
|
366
|
|
|
{ |
367
|
|
|
$actual = ConnectionBuilder::connectionFromArraySlice( |
368
|
|
|
array_slice($this->letters, 3, 1), // equals to letters.slice(3,4) in JS |
369
|
|
|
['first' => 3, 'after' => 'YXJyYXljb25uZWN0aW9uOjE='], |
370
|
|
|
['sliceStart' => 3, 'arrayLength' => 5] |
371
|
|
|
); |
372
|
|
|
|
373
|
|
|
$expected = $this->getExpectedConnection(['D'], false, true); |
374
|
|
|
|
375
|
|
|
$this->assertEquals($expected, $actual); |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
public function testReturnsAnEdgesCursorGivenAnArrayAndAMemberObject() |
379
|
|
|
{ |
380
|
|
|
$letterCursor = ConnectionBuilder::cursorForObjectInConnection($this->letters, 'B'); |
381
|
|
|
|
382
|
|
|
$this->assertEquals('YXJyYXljb25uZWN0aW9uOjE=', $letterCursor); |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
public function testReturnsAnEdgesCursorGivenAnArrayAndANonMemberObject() |
386
|
|
|
{ |
387
|
|
|
$letterCursor = ConnectionBuilder::cursorForObjectInConnection($this->letters, 'F'); |
388
|
|
|
|
389
|
|
|
$this->assertNull($letterCursor); |
390
|
|
|
} |
391
|
|
|
} |
392
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.