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