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 |
||
| 9 | class FormTest extends FormTestCase { |
||
| 10 | |||
| 11 | /** @test */ |
||
| 12 | public function it_can_be_created() |
||
| 13 | { |
||
| 14 | $this->assertEquals(get_class($this->form()), 'Helmut\Forms\Testing\Stubs\Form'); |
||
| 15 | $this->assertEquals(get_parent_class($this->form()), 'Helmut\Forms\Form'); |
||
| 16 | } |
||
| 17 | |||
| 18 | /** @test */ |
||
| 19 | public function it_can_be_rendered() |
||
| 20 | { |
||
| 21 | $form = $this->form(); |
||
| 22 | |||
| 23 | $this->assertContains('<form', $form->render()); |
||
| 24 | } |
||
| 25 | |||
| 26 | /** @test */ |
||
| 27 | public function it_can_create_a_field() |
||
| 28 | { |
||
| 29 | $form = $this->form(); |
||
| 30 | $field = $form->text('foo'); |
||
| 31 | |||
| 32 | $this->assertTrue(is_subclass_of($field, 'Helmut\Forms\Field')); |
||
| 33 | } |
||
| 34 | |||
| 35 | /** @test */ |
||
| 36 | public function it_can_have_fields_defined() |
||
| 37 | { |
||
| 38 | $form = new FormWithDefinition($this->request()); |
||
| 39 | $form->removeAllPlugins(); |
||
| 40 | |||
| 41 | $fields = $form->fields(); |
||
| 42 | |||
| 43 | $this->assertCount(1, $form->fields()); |
||
| 44 | } |
||
| 45 | |||
| 46 | /** @test */ |
||
| 47 | public function it_wont_create_the_same_field_twice() |
||
| 48 | { |
||
| 49 | $form = $this->form(); |
||
| 50 | $field1 = $form->text('foo'); |
||
| 51 | $field2 = $form->text('foo'); |
||
| 52 | |||
| 53 | $this->assertCount(1, $form->fields()); |
||
| 54 | $this->assertSame($field1, $field2); |
||
| 55 | } |
||
| 56 | |||
| 57 | /** @test */ |
||
| 58 | public function it_fetches_all_the_keys() |
||
| 59 | { |
||
| 60 | $form = $this->form(); |
||
| 61 | $form->text('foo'); |
||
| 62 | $form->name('bar'); |
||
| 63 | $form->email('baz'); |
||
| 64 | |||
| 65 | $expected = ['foo', 'bar_first', 'bar_surname', 'bar', 'baz']; |
||
| 66 | $this->assertSame($expected, $form->keys()); |
||
| 67 | } |
||
| 68 | |||
| 69 | /** @test */ |
||
| 70 | public function it_fetches_all_values() |
||
| 71 | { |
||
| 72 | $form = $this->form(); |
||
| 73 | $form->text('foo'); |
||
| 74 | $form->name('bar'); |
||
| 75 | $form->email('baz'); |
||
| 76 | |||
| 77 | $expected = ['foo'=>'', 'bar_first'=>'', 'bar_surname'=>'', 'bar'=>'', 'baz'=>'']; |
||
| 78 | $this->assertSame($expected, $form->all()); |
||
| 79 | } |
||
| 80 | |||
| 81 | /** @test */ |
||
| 82 | public function it_fetches_values_for_simple_field() |
||
| 83 | { |
||
| 84 | $form = $this->form(); |
||
| 85 | $form->text('foo'); |
||
| 86 | |||
| 87 | $this->assertSame($form->get('foo'), ''); |
||
| 88 | } |
||
| 89 | |||
| 90 | /** @test */ |
||
| 91 | public function it_fetches_values_for_a_complex_field() |
||
| 92 | { |
||
| 93 | $form = $this->form(); |
||
| 94 | $form->name('foo'); |
||
| 95 | |||
| 96 | $expected = ['foo_first'=>'', 'foo_surname'=>'', 'foo'=>'']; |
||
| 97 | $this->assertSame($form->get('foo'), $expected); |
||
| 98 | } |
||
| 99 | |||
| 100 | /** @test */ |
||
| 101 | public function it_fetches_values_for_a_complex_field_by_key() |
||
| 102 | { |
||
| 103 | $form = $this->form(); |
||
| 104 | $form->name('foo'); |
||
| 105 | |||
| 106 | $this->assertSame($form->get('foo', 'surname'), ''); |
||
| 107 | } |
||
| 108 | |||
| 109 | /** @test */ |
||
| 110 | public function it_is_not_submitted_by_default() |
||
| 111 | { |
||
| 112 | $request = $this->request(); |
||
| 113 | $request->method('get')->will($this->returnValueMap([ |
||
| 114 | ['foo', false], |
||
| 115 | ]) |
||
| 116 | ); |
||
| 117 | |||
| 118 | $form = $this->form($request); |
||
| 119 | $form->button('foo'); |
||
| 120 | |||
| 121 | $this->assertFalse($form->submitted()); |
||
| 122 | } |
||
| 123 | |||
| 124 | /** @test */ |
||
| 125 | public function it_can_be_submitted() |
||
| 126 | { |
||
| 127 | $request = $this->request(); |
||
| 128 | $request->method('get')->will($this->returnValueMap([ |
||
| 129 | ['foo', true], |
||
| 130 | ]) |
||
| 131 | ); |
||
| 132 | |||
| 133 | $form = $this->form($request); |
||
| 134 | $form->button('foo'); |
||
| 135 | |||
| 136 | $this->assertTrue($form->submitted()); |
||
| 137 | } |
||
| 138 | |||
| 139 | /** @test */ |
||
| 140 | public function it_can_detect_which_submit_button_was_clicked() |
||
| 141 | { |
||
| 142 | $request = $this->request(); |
||
| 143 | $request->method('get')->will($this->returnValueMap([ |
||
| 144 | ['foo', null], |
||
| 145 | ['bar', true], |
||
| 146 | ]) |
||
| 147 | ); |
||
| 148 | |||
| 149 | $form = $this->form($request); |
||
| 150 | $form->button('foo'); |
||
| 151 | $form->button('bar'); |
||
| 152 | |||
| 153 | $this->assertFalse($form->submitted('foo')); |
||
| 154 | $this->assertTrue($form->submitted('bar')); |
||
| 155 | } |
||
| 156 | |||
| 157 | /** @test */ |
||
| 158 | public function it_loads_values_from_the_request() |
||
| 159 | { |
||
| 160 | $request = $this->request(); |
||
| 161 | $request->method('all')->will($this->returnValue(['foo'=>'bar', 'register'=>true])); |
||
| 162 | $request->method('get')->will($this->returnValueMap([ |
||
| 163 | ['foo', 'bar'], |
||
| 164 | ['register', true], |
||
| 165 | ])); |
||
| 166 | |||
| 167 | $form = $this->form($request); |
||
| 168 | $form->text('foo'); |
||
| 169 | $form->button('register'); |
||
| 170 | |||
| 171 | $this->assertSame($form->get('foo'), 'bar'); |
||
| 172 | } |
||
| 173 | |||
| 174 | /** @test */ |
||
| 175 | public function it_loads_complex_values_from_the_request() |
||
| 176 | { |
||
| 177 | $request = $this->request(); |
||
| 178 | $request->method('all')->will($this->returnValue(['foo_first'=>'John', 'foo_surname'=>'Smith', 'register'=>true])); |
||
| 179 | $request->method('get')->will($this->returnValueMap([ |
||
| 180 | ['foo_first', 'John'], |
||
| 181 | ['foo_surname', 'Smith'], |
||
| 182 | ['register', true], |
||
| 183 | ])); |
||
| 184 | |||
| 185 | $form = $this->form($request); |
||
| 186 | $form->name('foo'); |
||
| 187 | $form->button('register'); |
||
| 188 | |||
| 189 | $expected = ['foo_first'=>'John', 'foo_surname'=>'Smith', 'foo'=>'John Smith']; |
||
| 190 | $this->assertSame($form->get('foo'), $expected); |
||
| 191 | } |
||
| 192 | |||
| 193 | /** @test */ |
||
| 194 | public function it_loads_complex_values_by_key_from_the_request() |
||
| 195 | { |
||
| 196 | $request = $this->request(); |
||
| 197 | $request->method('all')->will($this->returnValue(['foo_first'=>'John', 'foo_surname'=>'Smith', 'register'=>true])); |
||
| 198 | $request->method('get')->will($this->returnValueMap([ |
||
| 199 | ['foo_first', 'John'], |
||
| 200 | ['foo_surname', 'Smith'], |
||
| 201 | ['register', true], |
||
| 202 | ])); |
||
| 203 | |||
| 204 | $form = $this->form($request); |
||
| 205 | $form->name('foo'); |
||
| 206 | $form->button('register'); |
||
| 207 | |||
| 208 | $this->assertSame($form->get('foo', 'surname'), 'Smith'); |
||
| 209 | } |
||
| 210 | |||
| 211 | /** @test */ |
||
| 212 | public function it_only_loads_values_if_submitted() |
||
| 213 | { |
||
| 214 | $request = $this->request(); |
||
| 215 | $request->method('all')->will($this->returnValue(['foo'=>'bar', 'register'=>null])); |
||
| 216 | $request->method('get')->will($this->returnValueMap([ |
||
| 217 | ['foo', 'bar'], |
||
| 218 | ['register', null], |
||
| 219 | ])); |
||
| 220 | |||
| 221 | $form = $this->form($request); |
||
| 222 | $form->text('foo'); |
||
| 223 | $form->button('register'); |
||
| 224 | |||
| 225 | $this->assertSame($form->get('foo'), ''); |
||
| 226 | } |
||
| 227 | |||
| 228 | /** @test */ |
||
| 229 | public function it_is_valid_by_default() |
||
| 230 | { |
||
| 231 | $form = $this->form(); |
||
| 232 | $form->text('foo'); |
||
| 233 | $form->button('register'); |
||
| 234 | |||
| 235 | $this->assertTrue($form->valid()); |
||
| 236 | } |
||
| 237 | |||
| 238 | /** @test */ |
||
| 239 | public function it_can_validate_specific_fields() |
||
| 240 | { |
||
| 241 | $form = $this->form(); |
||
| 242 | $form->email('foo')->default('[email protected]'); |
||
| 243 | $form->email('bar')->default('bar@invalid'); |
||
| 244 | $form->button('register'); |
||
| 245 | |||
| 246 | $this->assertTrue($form->valid('foo')); |
||
| 247 | $this->assertFalse($form->valid('bar')); |
||
| 248 | } |
||
| 249 | |||
| 250 | /** @test */ |
||
| 251 | public function it_renders_no_errors_unless_submitted() |
||
| 252 | { |
||
| 253 | $form = $this->form(); |
||
| 254 | $form->text('foo')->required(); |
||
| 255 | $form->button('register'); |
||
| 256 | |||
| 257 | $this->assertNotContains('<p class="error_message"', $form->render()); |
||
| 258 | } |
||
| 259 | |||
| 260 | /** @test */ |
||
| 261 | public function it_renders_errors() |
||
| 262 | { |
||
| 263 | $request = $this->request(); |
||
| 264 | $request->method('get')->will($this->returnValueMap([ |
||
| 265 | ['foo', ''], |
||
| 266 | ['register', true], |
||
| 267 | ])); |
||
| 268 | |||
| 269 | $form = $this->form($request); |
||
| 270 | $form->text('foo')->required(); |
||
| 271 | $form->button('register'); |
||
| 272 | |||
| 273 | $this->assertContains('<p class="error_message">', $form->render()); |
||
| 274 | } |
||
| 275 | |||
| 276 | /** @test */ |
||
| 277 | public function it_renders_default_language() |
||
| 278 | { |
||
| 279 | $form = $this->form(); |
||
| 280 | $form->text('foo')->required(); |
||
| 281 | $form->button('register'); |
||
| 282 | |||
| 283 | $this->assertContains('This field is required.', $form->render()); |
||
| 284 | } |
||
| 285 | |||
| 286 | /** @test */ |
||
| 287 | public function it_renders_default_added_language() |
||
| 288 | { |
||
| 289 | $form = $this->form(); |
||
| 290 | $form->setLanguage('es'); |
||
| 291 | $form->text('foo')->required(); |
||
| 292 | |||
| 293 | $this->assertContains('Este campo es obligatorio.', $form->render()); |
||
| 294 | } |
||
| 295 | |||
| 296 | /** @test */ |
||
| 297 | public function it_sets_own_namespace() |
||
| 298 | { |
||
| 299 | $form = $this->form(); |
||
| 300 | |||
| 301 | $this->assertSame($form->namespaces(), ['Helmut\Forms\Testing\Stubs', 'Helmut\Forms']); |
||
| 302 | } |
||
| 303 | |||
| 304 | /** @test */ |
||
| 305 | public function it_can_add_a_namespace() |
||
| 306 | { |
||
| 307 | $form = $this->form(); |
||
| 308 | $form->addNamespace('My\Custom\Namespace'); |
||
| 309 | $form->addNamespace('My\Other\Custom\Namespace'); |
||
| 310 | |||
| 311 | $this->assertSame($form->namespaces(), ['My\Other\Custom\Namespace', 'My\Custom\Namespace', 'Helmut\Forms\Testing\Stubs', 'Helmut\Forms']); |
||
| 312 | } |
||
| 313 | |||
| 314 | /** @test */ |
||
| 315 | public function it_can_add_autoload_paths() |
||
| 316 | { |
||
| 317 | $form = $this->form(); |
||
| 318 | $form->addPath(__DIR__.'/folder'); |
||
| 319 | $form->addPath(__DIR__.'/folder/subfolder'); |
||
| 320 | |||
| 321 | $paths = $form->paths(); |
||
| 322 | |||
| 323 | $this->assertCount(4, $paths); |
||
| 324 | $this->assertContains('forms/tests/unit/folder/subfolder', $paths[0]); |
||
| 325 | $this->assertContains('forms/tests/unit/folder/', $paths[1]); |
||
| 326 | $this->assertContains('forms/tests/unit/stubs/', $paths[2]); |
||
| 327 | $this->assertContains('forms/src/', $paths[3]); |
||
| 328 | } |
||
| 329 | |||
| 330 | /** @test */ |
||
| 331 | public function it_will_not_add_autoload_paths_that_do_not_exist() |
||
| 332 | { |
||
| 333 | $form = $this->form(); |
||
| 334 | $form->addPath(__DIR__.'/folder'); |
||
| 335 | $form->addPath(__DIR__.'/folder/subfolder'); |
||
| 336 | $form->addPath(__DIR__.'/folder/doesnotexist'); |
||
| 337 | |||
| 338 | $paths = $form->paths(); |
||
| 339 | |||
| 340 | $this->assertCount(4, $paths); |
||
| 341 | $this->assertContains('forms/tests/unit/folder/subfolder', $paths[0]); |
||
| 342 | $this->assertContains('forms/tests/unit/folder/', $paths[1]); |
||
| 343 | $this->assertContains('forms/tests/unit/stubs/', $paths[2]); |
||
| 344 | $this->assertContains('forms/src/', $paths[3]); |
||
| 345 | } |
||
| 346 | |||
| 347 | /** @test */ |
||
| 348 | public function it_adds_autoload_paths_with_trailing_slash() |
||
| 349 | { |
||
| 350 | $form = $this->form(); |
||
| 351 | $form->addPath(__DIR__.'/folder/'); |
||
| 352 | $form->addPath(__DIR__.'/folder/subfolder/'); |
||
| 353 | |||
| 354 | $paths = $form->paths(); |
||
| 355 | |||
| 356 | $this->assertContains('forms/tests/unit/folder/subfolder', $paths[0]); |
||
| 357 | $this->assertContains('forms/tests/unit/folder/', $paths[1]); |
||
| 358 | $this->assertContains('forms/tests/unit/stubs/', $paths[2]); |
||
| 359 | $this->assertContains('forms/src/', $paths[3]); |
||
| 360 | } |
||
| 361 | |||
| 362 | /** @test */ |
||
| 363 | public function it_can_set_template() |
||
| 364 | { |
||
| 365 | $form = $this->form(); |
||
| 366 | $form->setTemplate('testing'); |
||
| 367 | |||
| 368 | $paths = $form->templatePaths(); |
||
| 369 | |||
| 370 | $this->assertCount(1, $paths); |
||
| 371 | $this->assertContains('forms/tests/unit/stubs/templates/testing/', $paths[0]); |
||
| 372 | } |
||
| 373 | |||
| 374 | /** @test */ |
||
| 375 | public function it_will_not_add_template_path_that_does_not_exist() |
||
| 376 | { |
||
| 377 | $form = $this->form(); |
||
| 378 | $form->setTemplate('doesnotexist'); |
||
| 379 | |||
| 380 | $paths = $form->templatePaths(); |
||
| 381 | |||
| 382 | $this->assertCount(0, $paths); |
||
| 383 | } |
||
| 384 | |||
| 385 | /** @test */ |
||
| 386 | public function it_sets_template_autoload_path() |
||
| 387 | { |
||
| 388 | $form = $this->form(); |
||
| 389 | |||
| 390 | $paths = $form->templatePaths(); |
||
| 391 | |||
| 392 | $this->assertCount(2, $paths); |
||
| 393 | $this->assertContains('forms/tests/unit/stubs/templates/bootstrap/', $paths[0]); |
||
| 394 | $this->assertContains('forms/src/templates/bootstrap/', $paths[1]); |
||
| 395 | } |
||
| 396 | |||
| 397 | /** @test */ |
||
| 398 | public function it_uses_added_autoload_paths_to_find_templates() |
||
| 399 | { |
||
| 400 | $form = $this->form(); |
||
| 401 | $form->addPath(__DIR__.'/folder'); |
||
| 402 | |||
| 403 | $paths = $form->templatePaths(); |
||
| 404 | |||
| 405 | $this->assertCount(3, $paths); |
||
| 406 | $this->assertContains('forms/tests/unit/folder/templates/bootstrap/', $paths[0]); |
||
| 407 | $this->assertContains('forms/tests/unit/stubs/templates/bootstrap/', $paths[1]); |
||
| 408 | $this->assertContains('forms/src/templates/bootstrap/', $paths[2]); |
||
| 409 | } |
||
| 410 | |||
| 411 | /** @test */ |
||
| 412 | public function it_uses_added_autoload_paths_to_find_templates_with_a_set_template() |
||
| 413 | { |
||
| 414 | $form = $this->form(); |
||
| 415 | $form->setTemplate('testing'); |
||
| 416 | $form->addPath(__DIR__.'/folder'); |
||
| 417 | |||
| 418 | $paths = $form->templatePaths(); |
||
| 419 | |||
| 420 | $this->assertCount(2, $paths); |
||
| 421 | $this->assertContains('forms/tests/unit/folder/templates/testing/', $paths[0]); |
||
| 422 | $this->assertContains('forms/tests/unit/stubs/templates/testing/', $paths[1]); |
||
| 423 | } |
||
| 424 | |||
| 425 | /** @test */ |
||
| 426 | public function it_sets_your_namespace_as_an_autoload_path() |
||
| 427 | { |
||
| 428 | $form = new FormWithCustomNamespace($this->request()); |
||
| 429 | $form->removeAllPlugins(); |
||
| 430 | |||
| 431 | $paths = $form->paths(); |
||
| 432 | |||
| 433 | $this->assertCount(2, $paths); |
||
| 434 | $this->assertContains('tests/unit/stubs/Custom/', $paths[0]); |
||
| 435 | $this->assertContains('forms/src/', $paths[1]); |
||
| 436 | } |
||
| 437 | |||
| 438 | /** @test */ |
||
| 439 | public function it_sets_your_namespace_and_parent_namespaces_as_an_autoload_path() |
||
| 440 | { |
||
| 441 | $form = new FormWithCustomExtension($this->request()); |
||
| 442 | $form->removeAllPlugins(); |
||
| 443 | |||
| 444 | $paths = $form->paths(); |
||
| 445 | |||
| 446 | $this->assertCount(3, $paths); |
||
| 447 | $this->assertContains('tests/unit/stubs/CustomExtension/', $paths[0]); |
||
| 448 | $this->assertContains('tests/unit/stubs/CustomExtension/FormExtension/', $paths[1]); |
||
| 449 | $this->assertContains('forms/src/', $paths[2]); |
||
| 450 | } |
||
| 451 | |||
| 452 | /** @test */ |
||
| 453 | public function it_sets_your_namespace_template_autoload_path_with_added_template() |
||
| 454 | { |
||
| 455 | $form = new FormWithCustomNamespace($this->request()); |
||
| 456 | $form->removeAllPlugins(); |
||
| 457 | $form->setTemplate('testing'); |
||
| 458 | |||
| 459 | $paths = $form->templatePaths(); |
||
| 460 | |||
| 461 | $this->assertCount(1, $paths); |
||
| 462 | $this->assertContains('tests/unit/stubs/Custom/templates/testing/', $paths[0]); |
||
| 463 | } |
||
| 464 | |||
| 465 | /** @test */ |
||
| 466 | public function it_renders_using_your_namespace_template() |
||
| 467 | { |
||
| 468 | $form = new FormWithCustomNamespace($this->request()); |
||
| 469 | $form->removeAllPlugins(); |
||
| 470 | |||
| 471 | $this->assertContains('it_renders_using_your_namespace_template', $form->render()); |
||
| 472 | } |
||
| 473 | |||
| 474 | } |