diff --git a/.editorconfig b/.editorconfig index 3faf149..5e5b915 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,6 +11,6 @@ indent_style = tab indent_size = tab tab_width = 4 -[{*.json, *.yaml, *.yml, *.md}] +[*.{json,yaml,yml,md}] indent_style = space indent_size = 2 diff --git a/.gitattributes b/.gitattributes index 12910b6..8f5c55f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,11 +1,11 @@ -# Not archived .docs export-ignore -tests export-ignore +.github export-ignore .editorconfig export-ignore .gitattributes export-ignore .gitignore export-ignore .travis.yml export-ignore Makefile export-ignore -phpstan.neon export-ignore README.md export-ignore +phpstan.neon export-ignore ruleset.xml export-ignore +tests export-ignore diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml deleted file mode 100644 index 60c34b6..0000000 --- a/.github/.kodiak.toml +++ /dev/null @@ -1,10 +0,0 @@ -version = 1 - -[merge] -automerge_label = "automerge" -blacklist_title_regex = "^WIP.*" -blacklist_labels = ["WIP"] -method = "rebase" -delete_branch_on_merge = true -notify_on_conflict = true -optimistic_updates = false diff --git a/.github/workflows/codesniffer.yml b/.github/workflows/codesniffer.yml index d5ff803..a58ac4f 100644 --- a/.github/workflows/codesniffer.yml +++ b/.github/workflows/codesniffer.yml @@ -15,4 +15,4 @@ jobs: name: "Codesniffer" uses: contributte/.github/.github/workflows/codesniffer.yml@master with: - php: "8.3" + php: "8.2" diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 85f1300..fac01f8 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -8,11 +8,11 @@ on: branches: ["*"] schedule: - - cron: "0 8 * * 1" + - cron: "0 9 * * 1" jobs: coverage: name: "Nette Tester" uses: contributte/.github/.github/workflows/nette-tester-coverage-v2.yml@master with: - php: "8.3" + php: "8.2" diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 9827fdd..13ceb07 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -8,11 +8,11 @@ on: branches: ["*"] schedule: - - cron: "0 8 * * 1" + - cron: "0 10 * * 1" jobs: phpstan: name: "Phpstan" uses: contributte/.github/.github/workflows/phpstan.yml@master with: - php: "8.3" + php: "8.2" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a928206..ef17693 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,12 +5,18 @@ on: workflow_dispatch: push: - branches: [ "*" ] + branches: ["*"] schedule: - - cron: "0 8 * * 1" + - cron: "0 10 * * 1" jobs: + test85: + name: "Nette Tester" + uses: contributte/.github/.github/workflows/nette-tester.yml@master + with: + php: "8.5" + test84: name: "Nette Tester" uses: contributte/.github/.github/workflows/nette-tester.yml@master @@ -29,15 +35,9 @@ jobs: with: php: "8.2" - test81: - name: "Nette Tester" - uses: contributte/.github/.github/workflows/nette-tester.yml@master - with: - php: "8.1" - testlower: name: "Nette Tester" uses: contributte/.github/.github/workflows/nette-tester.yml@master with: - php: "8.1" + php: "8.2" composer: "composer update --no-interaction --no-progress --prefer-dist --prefer-stable --prefer-lowest" diff --git a/.gitignore b/.gitignore index d37b3a5..f0b3670 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ /composer.lock # Tests -/tests/_output -/tests/Support/_generated -/coverage.xml +/tests/tmp +/coverage.* +/tests/**/*.log +/tests/**/*.html +/tests/**/*.expected +/tests/**/*.actual diff --git a/Makefile b/Makefile index ba7d34b..33bc117 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,11 @@ -.PHONY: install qa cs csf phpstan tests coverage - +.PHONY: install install: composer update +.PHONY: qa qa: phpstan cs +.PHONY: cs cs: ifdef GITHUB_ACTION vendor/bin/phpcs --standard=ruleset.xml --encoding=utf-8 --extensions="php,phpt" --colors -nsp -q --report=checkstyle src tests | cs2pr @@ -12,21 +13,22 @@ else vendor/bin/phpcs --standard=ruleset.xml --encoding=utf-8 --extensions="php,phpt" --colors -nsp src tests endif +.PHONY: csf csf: - vendor/bin/phpcbf --standard=ruleset.xml --encoding=utf-8 --colors -nsp src tests + vendor/bin/phpcbf --standard=ruleset.xml --encoding=utf-8 --extensions="php,phpt" --colors -nsp src tests +.PHONY: phpstan phpstan: vendor/bin/phpstan analyse -c phpstan.neon +.PHONY: tests tests: - vendor/bin/codecept build - vendor/bin/codecept run + vendor/bin/tester -s -p php --colors 1 -C tests/Cases +.PHONY: coverage coverage: ifdef GITHUB_ACTION - vendor/bin/codecept build - XDEBUG_MODE=coverage vendor/bin/codecept run --coverage --coverage-xml + vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage coverage.xml --coverage-src src tests/Cases else - vendor/bin/codecept build - XDEBUG_MODE=coverage vendor/bin/codecept run --coverage --coverage-html + vendor/bin/tester -s -p phpdbg --colors 1 -C --coverage coverage.html --coverage-src src tests/Cases endif diff --git a/codeception.yml b/codeception.yml deleted file mode 100644 index 3adfcf2..0000000 --- a/codeception.yml +++ /dev/null @@ -1,22 +0,0 @@ -actor: Tester - -paths: - # where the tests stored - tests: tests - - # directory for fixture data - data: tests/Support/Data - - # directory for support code - support: tests/Support - - # directory for output - output: tests/_output - -settings: - log: true - -coverage: - enabled: true - include: - - src/** diff --git a/composer.json b/composer.json index 732957e..067d7ab 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,5 @@ { "name": "contributte/forms-multiplier", - "type": "library", - "license": "MIT", "description": "Multiplier for nette forms", "keywords": [ "nette", @@ -9,19 +7,26 @@ "forms", "multiplier" ], + "type": "library", + "license": "MIT", + "homepage": "https://github.com/contributte/forms-multiplier", + "authors": [ + { + "name": "Milan Felix Sulc", + "homepage": "https://f3l1x.io" + } + ], "require": { - "php": ">=8.1", - "nette/forms": "^3.1.12" + "php": ">=8.2", + "nette/forms": "^3.2.0" }, "require-dev": { - "codeception/codeception": "^5.0", - "codeception/module-asserts": "^3.0", - "codeception/module-phpbrowser": "^3.0", - "nette/application": "^3.1.11", - "nette/di": "^3.1.0", + "contributte/phpstan": "~0.2.0", + "contributte/qa": "~0.4.0", + "contributte/tester": "~0.4.0", "latte/latte": "^3.0.0", - "contributte/qa": "^0.3", - "contributte/phpstan": "^0.2", + "nette/application": "^3.2.0", + "nette/di": "^3.2.0", "webchemistry/testing-helpers": "^4.0.0" }, "conflict": { @@ -38,8 +43,8 @@ "Tests\\": "tests" } }, - "prefer-stable": true, "minimum-stability": "dev", + "prefer-stable": true, "config": { "sort-packages": true, "allow-plugins": { diff --git a/phpstan.neon b/phpstan.neon index 9e4a8b0..5fa45d0 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,11 +1,9 @@ includes: - - vendor/phpstan/phpstan-deprecation-rules/rules.neon - - vendor/phpstan/phpstan-nette/extension.neon - - vendor/phpstan/phpstan-nette/rules.neon + - vendor/contributte/phpstan/phpstan.neon parameters: level: 8 - phpVersion: 80100 + phpVersion: 80200 scanDirectories: - src @@ -24,3 +22,40 @@ parameters: identifier: argument.type count: 4 path: src/Multiplier.php + + # Strict rules - boolean conditions + - + identifier: if.condNotBoolean + path: src/ComponentResolver.php + - + identifier: if.condNotBoolean + path: src/Multiplier.php + - + identifier: booleanAnd.leftNotBoolean + path: src/Latte/Extension/Node/MultiplierAddNode.php + - + identifier: booleanAnd.leftNotBoolean + path: src/Multiplier.php + - + identifier: booleanAnd.rightNotBoolean + path: src/Multiplier.php + - + identifier: booleanNot.exprNotBoolean + path: src/Latte/Extension/Node/MultiplierRemoveNode.php + - + identifier: booleanNot.exprNotBoolean + path: src/Multiplier.php + - + identifier: ternary.condNotBoolean + path: src/Latte/Extension/Node/MultiplierAddNode.php + - + identifier: ternary.condNotBoolean + path: src/Latte/Extension/Node/MultiplierRemoveNode.php + + # Strict rules - covariance/contravariance + - + identifier: method.childReturnType + path: src/Latte/Extension/MultiplierExtension.php + - + identifier: method.childParameterType + path: src/Multiplier.php diff --git a/ruleset.xml b/ruleset.xml index 8eba5ea..57241ed 100644 --- a/ruleset.xml +++ b/ruleset.xml @@ -1,21 +1,22 @@ - - - + + + + + - + - - - /tests + + /tests/tmp diff --git a/tests/.coveralls.yml b/tests/.coveralls.yml deleted file mode 100644 index 740380b..0000000 --- a/tests/.coveralls.yml +++ /dev/null @@ -1,4 +0,0 @@ -# for php-coveralls -service_name: github-actions -coverage_clover: tests/_output/coverage.xml -json_path: tests/_output/coverage.json diff --git a/tests/Cases/Functional/MultiplierExtensionTest.phpt b/tests/Cases/Functional/MultiplierExtensionTest.phpt new file mode 100644 index 0000000..2a9bd9f --- /dev/null +++ b/tests/Cases/Functional/MultiplierExtensionTest.phpt @@ -0,0 +1,68 @@ +|null $multiplierConfig + */ +function initializeContainer(?array $multiplierConfig = null): void +{ + $config = [ + 'services' => [ + 'latte.latteFactory' => ILatteFactory::class, + ], + ]; + + if ($multiplierConfig !== null) { + $config['multiplier'] = $multiplierConfig; + } + + $loader = new ContainerLoader(Environment::getTestDir()); + $class = $loader->load(function (Compiler $compiler) use ($config): void { + $compiler->addExtension('multiplier', new MultiplierExtension()); + $compiler->addConfig($config); + }, md5(serialize($multiplierConfig)) . time()); + $container = new $class(); + $container->initialize(); +} + +// testDefaultConfiguration +Toolkit::test(function (): void { + initializeContainer(); + + $form = new Form(); + $multiplier = $form->addMultiplier('multiplier', function (Container $container, Form $form): void { + }); + Assert::type(Multiplier::class, $multiplier); +}); + +// testAlternativeConfiguration +Toolkit::test(function (): void { + initializeContainer(['name' => 'addMultiplierAlternative']); + + $form = new Form(); + $multiplier = $form->addMultiplierAlternative('multiplier', function (Container $container, Form $form): void { + }); + Assert::type(Multiplier::class, $multiplier); +}); + +// testInvalidConfiguration +Toolkit::test(function (): void { + Assert::exception(function (): void { + initializeContainer(['name' => 0]); + }, InvalidConfigurationException::class); +}); diff --git a/tests/Cases/Unit/CreateButtonTest.phpt b/tests/Cases/Unit/CreateButtonTest.phpt new file mode 100644 index 0000000..cc3793b --- /dev/null +++ b/tests/Cases/Unit/CreateButtonTest.phpt @@ -0,0 +1,139 @@ +form->createRequest( + MultiplierBuilder::create() + ->addCreateButton() + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => ''], + ['bar' => ''], + 'multiplier_creator' => '', + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[2][bar]"]'); +}); + +// testSendCreateOverMaxCopies +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2, 2) + ->addCreateButton() + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => ''], + ['bar' => ''], + 'multiplier_creator' => '', + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[2][bar]"]'); +}); + +// testSendCreateButtonWith5Copies +Toolkit::test(function () use ($services): void { + $factory = MultiplierBuilder::create() + ->addCreateButton(5) + ->addCreateButton() + ->addRemoveButton(); + + $response = $services->form->createRequest($factory->createForm())->setPost([ + 'm' => [ + ['bar' => ''], + 'multiplier_creator5' => '', + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[2][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[3][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[4][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[5][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[6][bar]"]'); +}); + +// testCallback +Toolkit::test(function () use ($services): void { + $factory = MultiplierBuilder::create() + ->setMinCopies(1) + ->addRemoveButton(function (SubmitButton $submitter): void { + $submitter->setHtmlAttribute('class', 'delete-btn'); + }) + ->addCreateButton(5, function (Submitter $submitter): void { + $submitter->setHtmlAttribute('class', 'add-btn'); + }); + + $response = $services->form->createRequest($factory->createForm())->setPost([ + 'm' => [ + ['bar' => ''], + ['bar' => ''], + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input.delete-btn'); + FormAssert::domHas($dom, 'input.add-btn'); +}); + +// testFormEvents +Toolkit::test(function () use ($services): void { + $factory = MultiplierBuilder::create(2) + ->setMinCopies(1) + ->addRemoveButton(function (SubmitButton $submitter): void { + $submitter->setHtmlAttribute('class', 'delete-btn'); + }) + ->addCreateButton(5, function (Submitter $submitter): void { + $submitter->setHtmlAttribute('class', 'add-btn'); + }); + + $called = false; + $factory->formModifier(function ($form) use (&$called): void { + $form->onSuccess[] = $form->onError[] = $form->onSubmit[] = function () use (&$called): void { + $called = true; + }; + }); + + $req = $services->form->createRequest($factory->createForm()); + $response = $req->setPost([ + 'm' => [ + ['bar' => ''], + 'multiplier_creator' => '', + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"]'); + Assert::true($called); +}); diff --git a/tests/Cases/Unit/DefaultValuesTest.phpt b/tests/Cases/Unit/DefaultValuesTest.phpt new file mode 100644 index 0000000..0ae820e --- /dev/null +++ b/tests/Cases/Unit/DefaultValuesTest.phpt @@ -0,0 +1,168 @@ + [ + ['bar' => 'foo'], + ['bar' => 'foo'], + ], +]; + +$defaultNested = [ + 'm' => [ + [ + 'bar' => 'foo1', + 'nested' => [ + ['foo' => 'bar1'], + ['foo' => 'bar2'], + ], + ], + [ + 'bar' => 'foo2', + 'nested' => [ + ['foo' => 'bar3'], + ['foo' => 'bar4'], + ], + ], + ], +]; + +// testRender +Toolkit::test(function () use ($services, $defaults): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2, null) + ->addCreateButton() + ->addRemoveButton() + ->setMinCopies(1) + ->setFormDefaults($defaults) + ->createForm() + )->render(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"][value="foo"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"][value="foo"]'); + FormAssert::domNotHas($dom, 'input[name="m[2][bar]"]'); +}); + +// testRenderAndSetDefaultsInAction +Toolkit::test(function () use ($services, $defaults): void { + $response = $services->form->createRequest( + MultiplierBuilder::create() + ->createForm() + )->setActionCallback(function (Form $form) use ($defaults): void { + $form->setDefaults($defaults); + })->render(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"][value="foo"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"][value="foo"]'); + FormAssert::domNotHas($dom, 'input[name="m[2][bar]"]'); +}); + +// testRenderAndSetDefaultsInRender +Toolkit::test(function () use ($services, $defaults): void { + $response = $services->form->createRequest( + MultiplierBuilder::create() + ->createForm() + )->setRenderCallback(function (Form $form) use ($defaults): void { + $form->setDefaults($defaults); + })->render(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"][value="foo"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"][value="foo"]'); + FormAssert::domNotHas($dom, 'input[name="m[2][bar]"]'); +}); + +// testRemoveButtons +Toolkit::test(function () use ($services, $defaults): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2, null) + ->addCreateButton() + ->addRemoveButton() + ->setMinCopies(1) + ->setFormDefaults($defaults) + ->createForm() + )->render(); + + $dom = $response->toDomQuery(); + FormAssert::domHas($dom, 'input[name="m[0][' . Multiplier::SUBMIT_REMOVE_NAME . ']"]'); + FormAssert::domHas($dom, 'input[name="m[1][' . Multiplier::SUBMIT_REMOVE_NAME . ']"]'); +}); + +// testDefaultValue +Toolkit::test(function () use ($services, $defaults): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2, null) + ->addCreateButton() + ->addRemoveButton() + ->setMinCopies(1) + ->setFormDefaults($defaults) + ->fields(['bar' => 'foo']) + ->createForm() + )->render(); + + $dom = $response->toDomQuery(); + FormAssert::domHas($dom, 'input[name="m[0][bar]"][value="foo"]'); +}); + +// testDefaultValueSend +Toolkit::test(function () use ($services, $defaults): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2, null) + ->addCreateButton() + ->addRemoveButton() + ->setMinCopies(1) + ->setFormDefaults($defaults) + ->fields(['bar' => 'foo']) + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => 'bar'], + Multiplier::SUBMIT_CREATE_NAME => '', + ], + ])->send(); + + $dom = $response->toDomQuery(); + FormAssert::domHas($dom, 'input[name="m[0][bar]"][value="bar"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"][value="foo"]'); +}); + +// testNestedMultiplier +Toolkit::test(function () use ($services, $defaultNested): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2, null) + ->containerModifier(function (Container $container): void { + $container['nested'] = new Multiplier(function (Container $container): void { + $container->addText('foo'); + }); + }) + ->fields(['bar' => 'foo']) + ->setFormDefaults($defaultNested) + ->createForm() + )->render(); + + $dom = $response->toDomQuery(); + FormAssert::domHas($dom, 'input[name="m[0][bar]"][value="foo1"]'); + FormAssert::domHas($dom, 'input[name="m[0][nested][0][foo]"][value="bar1"]'); + FormAssert::domHas($dom, 'input[name="m[0][nested][1][foo]"][value="bar2"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"][value="foo2"]'); + FormAssert::domHas($dom, 'input[name="m[1][nested][0][foo]"][value="bar3"]'); + FormAssert::domHas($dom, 'input[name="m[1][nested][1][foo]"][value="bar4"]'); +}); diff --git a/tests/Cases/Unit/LatteTest.phpt b/tests/Cases/Unit/LatteTest.phpt new file mode 100644 index 0000000..487478c --- /dev/null +++ b/tests/Cases/Unit/LatteTest.phpt @@ -0,0 +1,35 @@ +addExtension(new FormsExtension()); + $latte->addExtension(new MultiplierExtension()); + + $presenter = new FooPresenter(); + $form = new NetteForm(); + $form['m'] = $m = new Multiplier(function (Container $container): void { + $container->addText('foo'); + }); + $m->addCreateButton('Create one'); + $m->addCreateButton('Create two', 2); + $presenter['m'] = $form; + + $string = $latte->renderToString(__DIR__ . '/templates/macros.latte', ['form' => $form]); + Assert::match('#name="m\[multiplier_creator]"#', $string); + Assert::match('#name="m\[multiplier_creator2]"#', $string); +}); diff --git a/tests/Cases/Unit/MultiplierTest.phpt b/tests/Cases/Unit/MultiplierTest.phpt new file mode 100644 index 0000000..fa2dbcb --- /dev/null +++ b/tests/Cases/Unit/MultiplierTest.phpt @@ -0,0 +1,361 @@ +form->createRequest( + MultiplierBuilder::create() + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier) use (&$onCreateParams): void { + $multiplier->onCreate[] = function (Container $container) use (&$onCreateParams): void { + $onCreateParams[] = $container; + }; + }) + ->createForm() + )->render(); + + FormAssert::domHas($response->toDomQuery(), 'input[name="m[0][bar]"]'); +}); + +// testSendBase +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create() + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + }) + ->createForm() + ) + ->setPost($params = [ + 'm' => [ + ['bar' => 'foo'], + ], + ])->send(); + + Assert::true($response->isSuccess()); + Assert::same($params, $response->getValues()); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"][value="foo"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][bar]"]'); +}); + +// testRenderCopy2 +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2) + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + }) + ->createForm() + )->render(); + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"]'); +}); + +// testSendCopy2 +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2) + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + }) + ->createForm() + ) + ->setPost($params = [ + 'm' => [ + ['bar' => 'foo'], + ['bar' => 'bar'], + ], + ])->send(); + + Assert::same($params, $response->getValues()); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[1][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[2][bar]"]'); +}); + +// testRenderMaxCopy +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2, 1) + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + }) + ->createForm() + )->render(); + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][bar]"]'); +}); + +// testSendMaxCopy +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2, 1) + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + }) + ->createForm() + ) + ->setPost([ + 'm' => [ + ['bar' => 'foo'], + ['bar' => 'bar'], + ], + ])->send(); + + Assert::same([ + 'm' => [ + ['bar' => 'foo'], + ], + ], $response->getValues()); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][bar]"]'); +}); + +// testNested +Toolkit::test(function () use ($services): void { + $request = $services->form->createRequest( + MultiplierBuilder::create() + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + }) + ->containerModifier(function (Container $container): void { + $container['m2'] = (new Multiplier(function (Container $container): void { + $container->addText('bar2'); + })); + $container['m2']->addCreateButton('create'); + }) + ->createForm() + ); + + $dom = $request->render()->toDomQuery(); + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domHas($dom, 'input[name="m[0][m2][0][bar2]"]'); + FormAssert::domHas($dom, 'input[name="m[0][m2][' . Multiplier::SUBMIT_CREATE_NAME . ']"]'); +}); + +// testSubmitFilter +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create() + ->fields([]) + ->beforeFormModifier(function (Form $form): void { + $form->addInteger('num'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + $container->addInteger('mnum'); + }; + }) + ->formModifier(function (Form $form): void { + $form->onSuccess[] = $form->onError[] = $form->onSubmit[] = function (): void { + }; + }) + ->createForm() + ) + ->setPost([ + 'num' => '11', + 'm' => [ + ['mnum' => '49'], + ], + ])->send(); + + Assert::true($response->isSuccess()); + Assert::same([ + 'num' => 11, + 'm' => [ + ['mnum' => 49], + ], + ], $response->getValues()); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][mnum]"][value="49"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][mnum]"]'); +}); + +// testGroup +Toolkit::test(function () use ($services): void { + $request = $services->form->createRequest( + MultiplierBuilder::create() + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + }) + ->createForm() + ); + $dom = $request->render()->toDomQuery(); + FormAssert::domHas($dom, 'fieldset'); + FormAssert::domHas($dom, 'fieldset input[name="m[0][bar]"]'); +}); + +// testGroupManualRenderWithRemovedButtons +Toolkit::test(function () use ($services): void { + $request = $services->form->createRequest( + MultiplierBuilder::create(2) + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + $multiplier->addCreateButton(); + $multiplier->addRemoveButton(); + }) + ->createForm() + ); + $dom = $request->render()->toDomQuery(); + + FormAssert::domNotHas($dom, 'input[name="m[0][multiplier_remover]"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][multiplier_remover]"]'); +}); + +// testGroupManualRenderWithButtons +Toolkit::test(function () use ($services): void { + $request = $services->form->createRequest(MultiplierBuilder::create(2) + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + $multiplier->addCreateButton(); + $multiplier->addRemoveButton(); + $multiplier->setMinCopies(1); + }) + ->createForm()); + $dom = $request->render(__DIR__ . '/templates/group.latte')->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][multiplier_remover]"]'); + FormAssert::domHas($dom, 'input[name="m[1][multiplier_remover]"]'); +}); + +// testOnCreateEvent +Toolkit::test(function () use ($services): void { + $onCreateParams = []; + $request = $services->form->createRequest( + MultiplierBuilder::create() + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier) use (&$onCreateParams): void { + $multiplier->onCreate[] = function (Container $container) use (&$onCreateParams): void { + $onCreateParams[] = $container; + }; + }) + ->createForm() + )->modifyForm(function (Form $form): void { + $form['m']->setValues([ + ['bar' => 'foo'], + ['bar' => 'foo2'], + ]); + }); + $request->render()->toString(); + + Assert::true(count($onCreateParams) > 0); + $values = ['foo', 'foo2']; + foreach ($onCreateParams as $i => $parameter) { + Assert::type(Container::class, $parameter); + Assert::same($values[$i], $parameter['bar']->getValue()); + } +}); + +// testAddDynamic +Toolkit::test(function () use ($services): void { + $request = $services->form->createRequest( + MultiplierBuilder::create() + ->beforeFormModifier(function (Form $form): void { + $form->addGroup('testGroup'); + }) + ->multiplierModifier(function (Multiplier $multiplier): void { + $multiplier->onCreate[] = function (Container $container): void { + }; + }) + ->createForm() + )->modifyForm(function (Form $form): void { + $form['m']->onCreateComponents[] = function (Multiplier $multiplier): void { + $multiplier->addCopy(99)['bar']->setHtmlAttribute('class', 'myClass'); + }; + }); + + $dom = $request->render()->toDomQuery(); + + FormAssert::domHas($dom, '[name="m[99][bar]"]'); + FormAssert::domHas($dom, 'input.myClass'); +}); + +// testPromptSelect +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create() + ->containerModifier(function (Container $container): void { + $container->addSelect('select', null, ['foo' => 'foo']) + ->setPrompt('Select'); + }) + ->addCreateButton() + ->createForm() + ) + ->setPost([ + 'm' => [ + ['select' => '', 'multiplier_creator' => ''], + ], + ])->send(); + + Assert::true($response->isSuccess()); +}); diff --git a/tests/Cases/Unit/RemoveButtonTest.phpt b/tests/Cases/Unit/RemoveButtonTest.phpt new file mode 100644 index 0000000..9ec217b --- /dev/null +++ b/tests/Cases/Unit/RemoveButtonTest.phpt @@ -0,0 +1,229 @@ +form->createRequest( + MultiplierBuilder::create(2) + ->setMinCopies(1) + ->addRemoveButton() + ->addCreateButton() + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => ''], + ['bar' => '', 'multiplier_remover' => ''], + ], + ])->send(); + + $dom = $response->toDomQuery(); + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][bar]"]'); +}); + +// testSendRemoveShouldNotValidate +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2) + ->setMinCopies(1) + ->beforeFormModifier(function (Form $form): void { + $form->addInteger('num'); + }) + ->addRemoveButton() + ->createForm() + )->setPost([ + 'num' => '5+1', + 'm' => [ + ['bar' => ''], + ['bar' => '', 'multiplier_remover' => ''], + ], + ])->send(); + + $dom = $response->toDomQuery(); + Assert::false($response->hasErrors()); + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][bar]"]'); +}); + +// testSendRemoveWithoutButton +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2) + ->setMinCopies(1) + ->addCreateButton() + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => ''], + ['bar' => '', 'multiplier_remover' => ''], + ], + ])->send(); + + $dom = $response->toDomQuery(); + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][bar]"]'); +}); + +// testSendRemoveBelowMinCopies +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(1) + ->setMinCopies(1) + ->addRemoveButton() + ->addCreateButton() + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => '', 'multiplier_remover' => ''], + ], + ])->send(); + + FormAssert::domHas($response->toDomQuery(), 'input[name="m[0][bar]"]'); +}); + +// test2Multipliers +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(1) + ->setMinCopies(1) + ->addRemoveButton() + ->addCreateButton() + ->formModifier(function (Form $form): void { + $form['m2'] = new Multiplier(function (Container $container): void { + $container->addText('bar2'); + }); + + $form['m2']->addRemoveButton(); + $form['m2']->addCreateButton(); + }) + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => ''], + ], + 'm2' => [ + ['bar2' => ''], + Multiplier::SUBMIT_CREATE_NAME => '', + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m2[0][multiplier_remover]"]'); + FormAssert::domHas($dom, 'input[name="m2[1][multiplier_remover]"]'); + FormAssert::domNotHas($dom, 'input[name="m[0][multiplier_remover]"]'); +}); + +// testFormEvents +Toolkit::test(function () use ($services): void { + $req = $services->form->createRequest( + MultiplierBuilder::create(2) + ->setMinCopies(1) + ->addRemoveButton() + ->addCreateButton() + ->formModifier(function (Form $form): void { + $form->onSuccess[] = $form->onError[] = $form->onSubmit[] = function (): void { + Assert::fail('Events should not be called'); + }; + }) + ->createForm() + ); + $response = $req->setPost([ + 'm' => [ + ['bar' => ''], + ['bar' => '', 'multiplier_remover' => ''], + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domNotHas($dom, 'input[name="m[1][bar]"]'); +}); + +// testAddClass +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(2) + ->setMinCopies(1) + ->addRemoveButton(function (SubmitButton $submitter): void { + $submitter->setHtmlAttribute('class', 'btn btn-remove'); + }) + ->addCreateButton() + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => ''], + ['bar' => ''], + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[0][bar]"]'); + FormAssert::domHas($dom, 'input.btn.btn-remove'); +}); + +// testDeleteLastElementToZero +Toolkit::test(function () use ($services): void { + $response = $services->form->createRequest( + MultiplierBuilder::create(1) + ->setMinCopies(0) + ->addRemoveButton() + ->addCreateButton() + ->createForm() + )->modifyForm(function (Form $form): void { + $form['m']->setValues([ + ['bar' => 'foo'], + ]); + })->setPost([ + 'm' => [ + ['bar' => '', 'multiplier_remover' => ''], + ], + ])->send(); + + $dom = $response->toDomQuery(); + + FormAssert::domHas($dom, 'input[name="m[multiplier_creator]"]'); + FormAssert::domNotHas($dom, 'input[name="m[0][bar]"]'); +}); + +// testOnRemoveEvent +Toolkit::test(function () use ($services): void { + $called = false; + $response = $services->form->createRequest( + MultiplierBuilder::create() + ->setMinCopies(0) + ->addRemoveButton() + ->multiplierModifier(function (Multiplier $multiplier) use (&$called): void { + $multiplier->onRemove[] = function () use (&$called): void { + $called = true; + }; + }) + ->createForm() + )->setPost([ + 'm' => [ + ['bar' => '', 'multiplier_remover' => ''], + ], + ])->send(); + + $dom = $response->toDomQuery(); + + Assert::true($called); + FormAssert::domNotHas($dom, 'input[name="m[0][bar]"]'); +}); diff --git a/tests/Unit/templates/group.latte b/tests/Cases/Unit/templates/group.latte similarity index 100% rename from tests/Unit/templates/group.latte rename to tests/Cases/Unit/templates/group.latte diff --git a/tests/Unit/templates/macros.latte b/tests/Cases/Unit/templates/macros.latte similarity index 100% rename from tests/Unit/templates/macros.latte rename to tests/Cases/Unit/templates/macros.latte diff --git a/tests/Functional.suite.yml b/tests/Functional.suite.yml deleted file mode 100644 index f6d0dd2..0000000 --- a/tests/Functional.suite.yml +++ /dev/null @@ -1,11 +0,0 @@ -# Codeception Test Suite Configuration -# -# Suite for functional (integration) tests -# Emulate web requests and make application process them -# Include one of framework modules (Symfony2, Yii2, Laravel5) to use it - -class_name: FunctionalTester -modules: - enabled: - # add framework module here - - Tests\Support\Helper\Functional diff --git a/tests/Functional/MultiplierExtensionTest.php b/tests/Functional/MultiplierExtensionTest.php deleted file mode 100644 index 6df9f8f..0000000 --- a/tests/Functional/MultiplierExtensionTest.php +++ /dev/null @@ -1,81 +0,0 @@ -initializeContainer(); - - $form = new Form(); - $multiplier = $form->addMultiplier('multiplier', function (Container $container, Form $form) {}); - $this->assertInstanceOf(Multiplier::class, $multiplier); - } - - public function testAlternativeConfiguration() - { - $this->initializeContainer(['name' => 'addMultiplierAlternative']); - - $form = new Form(); - $multiplier = $form->addMultiplierAlternative('multiplier', function (Container $container, Form $form) {}); - $this->assertInstanceOf(Multiplier::class, $multiplier); - } - - public function testInvalidConfiguration() - { - try { - $this->initializeContainer(['name' => 0]); - $e = null; - } catch (InvalidConfigurationException $e) {} - - $this->assertNotNull($e); - } - - protected function _before() - { - FileSystem::createDir(self::TEMP_DIR); - } - - protected function _after() - { - FileSystem::delete(self::TEMP_DIR); - } - - private function initializeContainer(?array $multiplierConfig = null): void - { - $config = [ - 'services' => [ - 'latte.latteFactory' => ILatteFactory::class, - ], - ]; - if ($multiplierConfig !== null) { - $config['multiplier'] = $multiplierConfig; - } - - $loader = new ContainerLoader(self::TEMP_DIR); - $class = $loader->load(function (Compiler $compiler) use ($config) { - $compiler->addExtension('multiplier', new MultiplierExtension()); - $compiler->addConfig($config); - }, md5(serialize($multiplierConfig)) . time()); - $container = new $class(); - $container->initialize(); - } - -} diff --git a/tests/Helpers/FormAssert.php b/tests/Helpers/FormAssert.php new file mode 100644 index 0000000..a88b0eb --- /dev/null +++ b/tests/Helpers/FormAssert.php @@ -0,0 +1,21 @@ +has($selector), sprintf('Element %s not found in DOM', $selector)); + } + + public static function domNotHas(DomQuery $domQuery, string $selector): void + { + Assert::false($domQuery->has($selector), sprintf('Element %s found in DOM', $selector)); + } + +} diff --git a/tests/Support/Helper/MultiplierBuilder.php b/tests/Helpers/MultiplierBuilder.php similarity index 81% rename from tests/Support/Helper/MultiplierBuilder.php rename to tests/Helpers/MultiplierBuilder.php index 3a45e8b..49f9c4e 100644 --- a/tests/Support/Helper/MultiplierBuilder.php +++ b/tests/Helpers/MultiplierBuilder.php @@ -1,42 +1,44 @@ */ + public array $fields = [ 'bar' => '', ]; /** @var callable[] */ - protected $formModifiers = []; + protected array $formModifiers = []; /** @var callable[] */ - protected $beforeFormModifiers = []; + protected array $beforeFormModifiers = []; /** @var callable[] */ - protected $multiplierModifiers = []; + protected array $multiplierModifiers = []; /** @var callable[] */ - protected $containerModifiers = []; + protected array $containerModifiers = []; - /** @var array */ - protected $multiplierArgs = []; + /** @var array */ + protected array $multiplierArgs = []; public function __construct(int $copyNumber = 1, ?int $maxCopies = null) { $this->multiplierArgs = [$copyNumber, $maxCopies]; } + public static function create(int $copyNumber = 1, ?int $maxCopies = null): self + { + return new self($copyNumber, $maxCopies); + } + public function factory(Container $container): void { foreach ($this->fields as $field => $value) { @@ -49,6 +51,9 @@ public function factory(Container $container): void } } + /** + * @param array $fields + */ public function fields(array $fields): self { $this->fields = $fields; @@ -58,9 +63,9 @@ public function fields(array $fields): self public function addRemoveButton(?callable $onCreate = null): self { - $this->multiplierModifiers[] = function (Multiplier $multiplier) use ($onCreate) { + $this->multiplierModifiers[] = function (Multiplier $multiplier) use ($onCreate): void { $btn = $multiplier->addRemoveButton('add'); - if ($onCreate) { + if ($onCreate !== null) { $btn->addOnCreateCallback($onCreate); } }; @@ -70,9 +75,9 @@ public function addRemoveButton(?callable $onCreate = null): self public function addCreateButton(int $copyCount = 1, ?callable $onCreate = null): self { - $this->multiplierModifiers[] = function (Multiplier $multiplier) use ($copyCount, $onCreate) { + $this->multiplierModifiers[] = function (Multiplier $multiplier) use ($copyCount, $onCreate): void { $btn = $multiplier->addCreateButton('add', $copyCount); - if ($onCreate) { + if ($onCreate !== null) { $btn->addOnCreateCallback($onCreate); } }; @@ -80,14 +85,9 @@ public function addCreateButton(int $copyCount = 1, ?callable $onCreate = null): return $this; } - public static function create(int $copyNumber = 1, ?int $maxCopies = null): self - { - return new self($copyNumber, $maxCopies); - } - public function setMinCopies(int $minCopies): self { - $this->multiplierModifiers[] = function (Multiplier $multiplier) use ($minCopies) { + $this->multiplierModifiers[] = function (Multiplier $multiplier) use ($minCopies): void { $multiplier->setMinCopies($minCopies); }; @@ -114,7 +114,8 @@ public function createForm(): Form $form->addSubmit('send'); - $form->onSuccess[] = function(Form $form) {}; + $form->onSuccess[] = function (Form $form): void { + }; return $form; } @@ -147,9 +148,12 @@ public function containerModifier(callable $callback): self return $this; } + /** + * @param array $defaults + */ public function setFormDefaults(array $defaults): self { - $this->formModifiers[] = function (Form $form) use ($defaults) { + $this->formModifiers[] = function (Form $form) use ($defaults): void { $form->setDefaults($defaults); }; diff --git a/tests/Mocks/FooPresenter.php b/tests/Mocks/FooPresenter.php new file mode 100644 index 0000000..f3282a8 --- /dev/null +++ b/tests/Mocks/FooPresenter.php @@ -0,0 +1,15 @@ +services = new Services(); - - $parent = get_parent_class($this); - if ($parent !== FALSE && method_exists($parent, 'setUp')) { - parent::setUp(); - } - } - - public function assertThrownException(callable $function, string $class, ?string $message = NULL, $code = NULL): void - { - $this->addToAssertionCount(1); - - $e = NULL; - try { - call_user_func($function); - } catch (\Exception $e) { - } - - if ($e === NULL) { - $this->fail("$class was expected, but none was thrown"); - } elseif (!$e instanceof $class) { - $this->fail("$class was expected but got " . get_class($e) . ($e->getMessage() ? " ({$e->getMessage()})" : '')); - } elseif ($message && $message !== $e->getMessage()) { - $this->fail("$class with a message matching {$message} was expected but got {$e->getMessage()}"); - } elseif ($code !== NULL && $e->getCode() !== $code) { - $this->fail("$class with a code {$code} was expected but got {$e->getCode()}"); - } - } - - public function assertDomHas(DomQuery $domQuery, string $selector): void - { - $this->addToAssertionCount(1); - - if (!$domQuery->has($selector)) { - $this->fail(sprintf('Element %s not found in DOM', $selector)); - } - } - - public function assertDomNotHas(DomQuery $domQuery, string $selector): void - { - $this->addToAssertionCount(1); - - if ($domQuery->has($selector)) { - $this->fail(sprintf('Element %s found in DOM', $selector)); - } - } - -} diff --git a/tests/Support/Helper/Unit.php b/tests/Support/Helper/Unit.php deleted file mode 100644 index 4540886..0000000 --- a/tests/Support/Helper/Unit.php +++ /dev/null @@ -1,11 +0,0 @@ -services->form->createRequest( - MultiplierBuilder::create() - ->addCreateButton() - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => ''], - ['bar' => ''], - 'multiplier_creator' => '', - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[2][bar]"]'); - } - - public function testSendCreateWithoutButton() - { - $this->markTestIncomplete("New containers are added even without a button"); - - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => ''], - ['bar' => ''], - 'multiplier_creator' => '', - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[2][bar]"]'); - } - - public function testSendCreateOverMaxCopies() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2, 2) - ->addCreateButton() - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => ''], - ['bar' => ''], - 'multiplier_creator' => '', - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[2][bar]"]'); - } - - public function testSendCreateButtonWith5Copies() - { - $factory = MultiplierBuilder::create() - ->addCreateButton(5) - ->addCreateButton() - ->addRemoveButton(); - - $response = $this->services->form->createRequest($factory->createForm())->setPost([ - 'm' => [ - ['bar' => ''], - 'multiplier_creator5' => '', - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[2][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[3][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[4][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[5][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[6][bar]"]'); - } - - public function testCallback() - { - $factory = MultiplierBuilder::create() - ->setMinCopies(1) - ->addRemoveButton(function (SubmitButton $submitter) { - $submitter->setHtmlAttribute('class', 'delete-btn'); - }) - ->addCreateButton(5, function (Submitter $submitter) { - $submitter->setHtmlAttribute('class', 'add-btn'); - }); - - $response = $this->services->form->createRequest($factory->createForm())->setPost([ - 'm' => [ - ['bar' => ''], - ['bar' => ''], - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input.delete-btn'); - $this->assertDomHas($dom, 'input.add-btn'); - } - - public function testFormEvents() - { - $factory = MultiplierBuilder::create(2) - ->setMinCopies(1) - ->addRemoveButton(function (SubmitButton $submitter) { - $submitter->setHtmlAttribute('class', 'delete-btn'); - }) - ->addCreateButton(5, function (Submitter $submitter) { - $submitter->setHtmlAttribute('class', 'add-btn'); - }); - - $called = false; - $factory->formModifier(function ($form) use (&$called) { - $form->onSuccess[] = $form->onError[] = $form->onSubmit[] = function () use (&$called) { - $called = true; - }; - }); - - $req = $this->services->form->createRequest($factory->createForm()); - $response = $req->setPost([ - 'm' => [ - ['bar' => ''], - 'multiplier_creator' => '', - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"]'); - $this->assertTrue($called); - } - - public function testNoOrphanFieldsets() - { - $this->markTestIncomplete( - 'We currently incorrectly produce extra fieldsets. See https://github.com/contributte/forms-multiplier/pull/83' - ); - - $i = 1; - $form = new Form(); - $form['members'] = $membersMultiplier = new Multiplier(function (Container $container) use ($form, &$i) { - $group = $form->addGroup('Team member #' . $i++); - $container->setCurrentGroup($group); - $container->addText('name', 'Name'); - }); - $form->setCurrentGroup(null); - $membersMultiplier->addCreateButton('add'); - - $req = $this->services->form->createRequest($form); - $response = $req->setPost([ - 'members' => [ - [], - 'multiplier_creator' => '', - ], - ])->send(); - - $dom = $response->toDomQuery(); - codecept_debug($response->toString()); - - $this->assertCount(2, $dom->find('fieldset'), 'After adding a container, there should be two fieldsets.'); - } - - /** - * Ensure filters (e.g. integer) work on submit, - * since they are dependent on properly set validation scope. - */ - public function testSendCreateFilter() - { - $this->markTestIncomplete( - '`getValues()` omits `num` field, even though it works ' - . 'just fine when sending without the button.' - ); - - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->fields([]) - ->beforeFormModifier(function (Form $form) { - $form->addInteger('num'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $container->addInteger('mnum')->setDefaultValue(47); - }; - }) - ->addCreateButton() - ->createForm() - ) - ->setPost([ - 'num' => '11', - 'm' => [ - ['mnum' => '49'], - 'multiplier_creator' => '', - ], - ])->send(); - - $this->assertTrue($response->isSuccess()); - $this->assertSame([ - 'num' => 11, - 'm' => [ - ['mnum' => 49], - // TODO: not sure if this is correct - ['mnum' => null], - ], - ], $response->getValues()); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][mnum]"][value="49"]'); - $this->assertDomHas($dom, 'input[name="m[1][mnum]"][value="47"]'); - $this->assertDomNotHas($dom, 'input[name="m[2][mnum]"]'); - } - -} diff --git a/tests/Unit/DefaultValuesTest.php b/tests/Unit/DefaultValuesTest.php deleted file mode 100644 index f5e7315..0000000 --- a/tests/Unit/DefaultValuesTest.php +++ /dev/null @@ -1,172 +0,0 @@ - [ - ['bar' => 'foo'], - ['bar' => 'foo'], - ], - ]; - - /** @var array */ - private static $defaultNested = [ - 'm' => [ - [ - 'bar' => 'foo1', - 'nested' => [ - ['foo' => 'bar1'], - ['foo' => 'bar2'], - ], - ], - [ - 'bar' => 'foo2', - 'nested' => [ - ['foo' => 'bar3'], - ['foo' => 'bar4'], - ], - ], - ], - ]; - - public function testRender() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2, null) - ->addCreateButton() - ->addRemoveButton() - ->setMinCopies(1) - ->setFormDefaults(self::$defaults) - ->createForm() - )->render(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"][value="foo"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"][value="foo"]'); - $this->assertDomNotHas($dom, 'input[name="m[2][bar]"]'); - } - - public function testRenderAndSetDefaultsInAction() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->createForm() - )->setActionCallback(function (Form $form) { - $form->setDefaults(self::$defaults); - })->render(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"][value="foo"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"][value="foo"]'); - $this->assertDomNotHas($dom, 'input[name="m[2][bar]"]'); - } - - public function testRenderAndSetDefaultsInRender() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->createForm() - )->setRenderCallback(function (Form $form) { - $form->setDefaults(self::$defaults); - })->render(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"][value="foo"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"][value="foo"]'); - $this->assertDomNotHas($dom, 'input[name="m[2][bar]"]'); - } - - public function testRemoveButtons() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2, null) - ->addCreateButton() - ->addRemoveButton() - ->setMinCopies(1) - ->setFormDefaults(self::$defaults) - ->createForm() - )->render(); - - $dom = $response->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][' . Multiplier::SUBMIT_REMOVE_NAME . ']"]'); - $this->assertDomHas($dom, 'input[name="m[1][' . Multiplier::SUBMIT_REMOVE_NAME . ']"]'); - } - - public function testDefaultValue() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2, null) - ->addCreateButton() - ->addRemoveButton() - ->setMinCopies(1) - ->setFormDefaults(self::$defaults) - ->fields(['bar' => 'foo']) - ->createForm() - )->render(); - - $dom = $response->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][bar]"][value="foo"]'); - } - - public function testDefaultValueSend() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2, null) - ->addCreateButton() - ->addRemoveButton() - ->setMinCopies(1) - ->setFormDefaults(self::$defaults) - ->fields(['bar' => 'foo']) - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => 'bar'], - Multiplier::SUBMIT_CREATE_NAME => '', - ], - ])->send(); - - $dom = $response->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][bar]"][value="bar"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"][value="foo"]'); - } - - public function testNestedMultiplier() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2, null) - ->containerModifier(function (Container $container) { - $container['nested'] = new Multiplier(function (Container $container) { - $container->addText('foo'); - }); - }) - ->fields(['bar' => 'foo']) - ->setFormDefaults(self::$defaultNested) - ->createForm() - )->render(); - - $dom = $response->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][bar]"][value="foo1"]'); - $this->assertDomHas($dom, 'input[name="m[0][nested][0][foo]"][value="bar1"]'); - $this->assertDomHas($dom, 'input[name="m[0][nested][1][foo]"][value="bar2"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"][value="foo2"]'); - $this->assertDomHas($dom, 'input[name="m[1][nested][0][foo]"][value="bar3"]'); - $this->assertDomHas($dom, 'input[name="m[1][nested][1][foo]"][value="bar4"]'); - } - -} diff --git a/tests/Unit/LatteTest.php b/tests/Unit/LatteTest.php deleted file mode 100644 index 83091a2..0000000 --- a/tests/Unit/LatteTest.php +++ /dev/null @@ -1,57 +0,0 @@ -latte = $latte = new Engine(); - $latte->addExtension(new FormsExtension()); - $latte->addExtension(new MultiplierExtension()); - } - - public function testBtnCreate() - { - $presenter = new FooPresenter(); - $form = new NetteForm(); - $form['m'] = $m = new Multiplier(function (Container $container) { - $container->addText('foo'); - }); - $m->addCreateButton('Create one'); - $m->addCreateButton('Create two', 2); - $presenter['m'] = $form; - - $string = $this->latte->renderToString(__DIR__ . '/templates/macros.latte', ['form' => $form]); - $this->assertMatchesRegularExpression('#name="m\[multiplier_creator]"#', $string); - $this->assertMatchesRegularExpression('#name="m\[multiplier_creator2]"#', $string); - } - -} - -class FooPresenter extends Presenter -{ - - public function link(string $destination, $args = []): string - { - return ''; - } - -} diff --git a/tests/Unit/MultiplierTest.php b/tests/Unit/MultiplierTest.php deleted file mode 100644 index e0aee98..0000000 --- a/tests/Unit/MultiplierTest.php +++ /dev/null @@ -1,521 +0,0 @@ - [], - ]; - - public function testRenderBase() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - )->render(); - - $this->assertDomHas($response->toDomQuery(), 'input[name="m[0][bar]"]'); - } - - public function testSendBase() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - ) - ->setPost($params = [ - 'm' => [ - ['bar' => 'foo'], - ], - ])->send(); - - $this->assertTrue($response->isSuccess()); - $this->assertSame($params, $response->getValues()); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"][value="foo"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][bar]"]'); - } - - public function testRenderCopy2() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - )->render(); - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"]'); - } - - public function testSendCopy2() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - ) - ->setPost($params = [ - 'm' => [ - ['bar' => 'foo'], - ['bar' => 'bar'], - ], - ])->send(); - - $this->assertSame($params, $response->getValues()); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[1][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[2][bar]"]'); - } - - public function testRenderMaxCopy() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2, 1) - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - )->render(); - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][bar]"]'); - } - - public function testSendMaxCopy() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2, 1) - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - ) - ->setPost([ - 'm' => [ - ['bar' => 'foo'], - ['bar' => 'bar'], - ], - ])->send(); - - $this->assertSame([ - 'm' => [ - ['bar' => 'foo'], - ], - ], $response->getValues()); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][bar]"]'); - } - - public function testNested() - { - $request = $this->services->form->createRequest( - MultiplierBuilder::create() - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->containerModifier(function (Container $container) { - $container['m2'] = (new Multiplier(function (Container $container) { - $container->addText('bar2'); - })); - $container['m2']->addCreateButton('create'); - }) - ->createForm() - ); - - $dom = $request->render()->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[0][m2][0][bar2]"]'); - $this->assertDomHas($dom, 'input[name="m[0][m2][' . Multiplier::SUBMIT_CREATE_NAME . ']"]'); - } - - public function testSendNested() - { - $this->markTestIncomplete('Nested multipliers are broken.'); - - $request = $this->services->form->createRequest( - MultiplierBuilder::create() - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->containerModifier(function (Container $container) { - $container['m2'] = (new Multiplier(function (Container $container) { - $container->addText('bar2'); - })); - $container['m2']->addCreateButton('create'); - }) - ->createForm() - ); - $request->setPost([ - 'm' => [ - [ - 'bar' => 'foo', - 'm2' => [ - ['bar2' => 'xx'], - ], - ], - ['bar' => 'bar'], - Multiplier::SUBMIT_CREATE_NAME => '', - ], - ]); - - $send = $request->send(); - $dom = $send->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[0][m2][0][bar2]"]'); - - $this->assertSame([ - 'm' => [ - [ - 'bar' => 'foo', - 'm2' => [ - ['bar2' => 'xx'], - ], - ], - [ - 'bar' => 'bar', - 'm2' => [ - ['bar2' => ''], - ], - ], - [ - 'bar' => '', - 'm2' => [ - ['bar2' => ''], - ], - ], - ], - ], $send->getValues()); - } - - /** - * Pressing “Create” inside a nested multiplier with fields with default values. - * This has been reported in the first bullet point in - * https://github.com/contributte/forms-multiplier/issues/56 - */ - public function testSendNestedInnerWithDefault() - { - $this->markTestIncomplete('Nested multipliers are broken.'); - - $request = $this->services->form->createRequest( - MultiplierBuilder::create() - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->containerModifier(function (Container $container) { - $container['m2'] = (new Multiplier(function (Container $container) { - $container->addText('bar2')->setDefaultValue('qux'); - })); - $container['m2']->addCreateButton('create'); - }) - ->createForm() - ); - $request->setPost([ - 'm' => [ - [ - 'bar' => 'foo', - 'm2' => [ - [ - 'bar2' => 'xx', - ], - Multiplier::SUBMIT_CREATE_NAME => '', - ], - ], - ['bar' => 'bar'], - ], - ]); - - $send = $request->send(); - $dom = $send->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input[name="m[0][m2][0][bar2]"]'); - $this->assertDomHas($dom, 'input[name="m[0][m2][1][bar2]"]'); - $this->assertDomHas($dom, 'input[name="m[0][m2][' . Multiplier::SUBMIT_CREATE_NAME . ']"]'); - - $form = $send->getForm(); - $this->assertSame( - [ - 'm' => [ - [ - 'bar' => 'foo', - 'm2' => [ - ['bar2' => 'xx'], - ['bar2' => 'qux'], - ], - ], - [ - 'bar' => 'bar', - 'm2' => [ - ['bar2' => 'qux'], - ], - ], - ], - ], - // Pass form, otherwise the values would be limited to m[0][m2] validation scope, - // since that is where the submitter button is pressed. - $form->getValues('array', [$form]) - ); - } - - /** - * Ensure filters work on submit, since they are dependent on properly set valdation scope. - * Regression test for https://github.com/contributte/forms-multiplier/issues/68 - */ - public function testSubmitFilter() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->fields([]) - ->beforeFormModifier(function (Form $form) { - $form->addInteger('num'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $container->addInteger('mnum'); - }; - }) - ->formModifier(function (Form $form) { - $form->onSuccess[] = $form->onError[] = $form->onSubmit[] = function () { - }; - }) - ->createForm() - ) - ->setPost([ - 'num' => '11', - 'm' => [ - ['mnum' => '49'], - ], - ])->send(); - - $this->assertTrue($response->isSuccess()); - $this->assertSame([ - 'num' => 11, - 'm' => [ - ['mnum' => 49], - ], - ], $response->getValues()); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][mnum]"][value="49"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][mnum]"]'); - } - - public function testGroup() - { - $request = $this->services->form->createRequest( - MultiplierBuilder::create() - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - ); - $dom = $request->render()->toDomQuery(); - $this->assertDomHas($dom, 'fieldset'); - $this->assertDomHas($dom, 'fieldset input[name="m[0][bar]"]'); - } - - public function testGroupManualRenderWithRemovedButtons() - { - $request = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - $multiplier->addCreateButton(); - $multiplier->addRemoveButton(); - }) - ->createForm() - ); - $dom = $request->render()->toDomQuery(); - - $this->assertDomNotHas($dom, 'input[name="m[0][multiplier_remover]"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][multiplier_remover]"]'); - } - - public function testGroupManualRenderWithButtons() - { - $request = $this->services->form->createRequest(MultiplierBuilder::create(2) - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - $multiplier->addCreateButton(); - $multiplier->addRemoveButton(); - $multiplier->setMinCopies(1); - }) - ->createForm()); - $dom = $request->render(__DIR__ . '/templates/group.latte')->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][multiplier_remover]"]'); - $this->assertDomHas($dom, 'input[name="m[1][multiplier_remover]"]'); - } - - public function testOnCreateEvent() - { - $this->assertEmpty($this->parameters['onCreate']); - $request = $this->services->form->createRequest( - MultiplierBuilder::create() - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - )->modifyForm(function (Form $form) { - $form['m']->setValues([ - ['bar' => 'foo'], - ['bar' => 'foo2'], - ]); - }); - $request->render()->toString(); - - $this->assertNotEmpty($this->parameters['onCreate']); - $values = ['foo', 'foo2']; - foreach ($this->parameters['onCreate'] as $i => $parameter) { - $this->assertInstanceOf(Container::class, $parameter); - $this->assertSame($values[$i], $parameter['bar']->getValue()); - } - } - - public function testAddDynamic() - { - $request = $this->services->form->createRequest( - MultiplierBuilder::create() - ->beforeFormModifier(function (Form $form) { - $form->addGroup('testGroup'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $this->parameters['onCreate'][] = $container; - }; - }) - ->createForm() - )->modifyForm(function (Form $form) { - $form['m']->onCreateComponents[] = function (Multiplier $multiplier) { - $multiplier->addCopy(99)['bar']->setHtmlAttribute('class', 'myClass'); - }; - }); - - $dom = $request->render()->toDomQuery(); - - $this->assertDomHas($dom, '[name="m[99][bar]"]'); - $this->assertDomHas($dom, 'input.myClass'); - } - - public function testPromptSelect() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->containerModifier(function (Container $container) { - $container->addSelect('select', null, ['foo' => 'foo']) - ->setPrompt('Select'); - }) - ->addCreateButton() - ->createForm() - ) - ->setPost($params = [ - 'm' => [ - ['select' => '', 'multiplier_creator' => ''], - ], - ])->send(); - - $this->assertTrue($response->isSuccess()); - - $dom = $response->toDomQuery(); - - } - -} diff --git a/tests/Unit/RemoveButtonTest.php b/tests/Unit/RemoveButtonTest.php deleted file mode 100644 index 0a3d8a3..0000000 --- a/tests/Unit/RemoveButtonTest.php +++ /dev/null @@ -1,363 +0,0 @@ -addSubmit('send'); - - return $form; - } - - protected function a_before() - { - $form = $this->services->form; - - $form->addForm('buttons', function ($copyNumber = 2, $maxCopies = null, $removeCallback = null) { - $form = $this->createMultiplier(function (Container $container) { - $container->addText('bar'); - }, $copyNumber, $maxCopies); - - /** @var Multiplier $multiplier */ - $multiplier = $form['m']; - - $multiplier->setMinCopies(1); - $btn = $multiplier->addRemoveButton(); - $multiplier->addCreateButton(); - - if (is_callable($removeCallback)) { - $removeCallback($btn); - } - - return $form; - }); - - $form->addForm('base', function ($copyNumber = 1, $maxCopies = null) { - $form = $this->createMultiplier(function (Container $container) { - $container->addText('bar'); - }, $copyNumber, $maxCopies); - - /** @var Multiplier $multiplier */ - $multiplier = $form['m']; - - $multiplier->addRemoveButton(); - $multiplier->addCreateButton(); - - return $form; - }); - - $form->addForm('2multipliers', function ($copyNumber = 2, $maxCopies = null) { - $form = $this->createMultiplier(function (Container $container) { - $container->addText('bar'); - }, $copyNumber, $maxCopies); - - $form['m2'] = new Multiplier(function (Container $container) { - $container->addText('bar2'); - }); - - /** @var Multiplier $multiplier */ - $multiplier = $form['m']; - - $multiplier->setMinCopies(1); - $multiplier->addRemoveButton(); - $multiplier->addCreateButton(); - - $form['m2']->addRemoveButton(); - $form['m2']->addCreateButton(); - - return $form; - }); - - } - - public function testSendRemove() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->setMinCopies(1) - ->addRemoveButton() - ->addCreateButton() - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => ''], - ['bar' => '', 'multiplier_remover' => ''], - ], - ])->send(); - - $dom = $response->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][bar]"]'); - } - - /** Regression test for https://github.com/contributte/forms-multiplier/pull/51 */ - public function testSendRemoveShouldNotValidate() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->setMinCopies(1) - ->beforeFormModifier(function (Form $form) { - $form->addInteger('num'); - }) - ->addRemoveButton() - ->createForm() - )->setPost([ - 'num' => '5+1', - 'm' => [ - ['bar' => ''], - ['bar' => '', 'multiplier_remover' => ''], - ], - ])->send(); - - $dom = $response->toDomQuery(); - $this->assertFalse($response->hasErrors()); - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][bar]"]'); - } - - public function testSendRemoveWithoutButton() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->setMinCopies(1) - ->addCreateButton() - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => ''], - ['bar' => '', 'multiplier_remover' => ''], - ], - ])->send(); - - $dom = $response->toDomQuery(); - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][bar]"]'); - } - - public function testSendRemoveBelowMinCopies() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(1) - ->setMinCopies(1) - ->addRemoveButton() - ->addCreateButton() - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => '', 'multiplier_remover' => ''], - ], - ])->send(); - - $this->assertDomHas($response->toDomQuery(), 'input[name="m[0][bar]"]'); - } - - public function test2Multipliers() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(1) - ->setMinCopies(1) - ->addRemoveButton() - ->addCreateButton() - ->formModifier(function (Form $form) { - $form['m2'] = new Multiplier(function (Container $container) { - $container->addText('bar2'); - }); - - $form['m2']->addRemoveButton(); - $form['m2']->addCreateButton(); - }) - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => ''], - ], - 'm2' => [ - ['bar2' => ''], - Multiplier::SUBMIT_CREATE_NAME => '', - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m2[0][multiplier_remover]"]'); - $this->assertDomHas($dom, 'input[name="m2[1][multiplier_remover]"]'); - $this->assertDomNotHas($dom, 'input[name="m[0][multiplier_remover]"]'); - } - - public function testFormEvents() - { - $req = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->setMinCopies(1) - ->addRemoveButton() - ->addCreateButton() - ->formModifier(function (Form $form) { - $form->onSuccess[] = $form->onError[] = $form->onSubmit[] = function () { - $this->fail('Events called'); - }; - }) - ->createForm() - ); - $response = $req->setPost([ - 'm' => [ - ['bar' => ''], - ['bar' => '', 'multiplier_remover' => ''], - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][bar]"]'); - } - - public function testAddClass() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->setMinCopies(1) - ->addRemoveButton(function (SubmitButton $submitter) { - $submitter->setHtmlAttribute('class', 'btn btn-remove'); - }) - ->addCreateButton() - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => ''], - ['bar' => ''], - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][bar]"]'); - $this->assertDomHas($dom, 'input.btn.btn-remove'); - } - - // bug #32 - public function testDeleteLastElementToZero() - { - $response = $this->services->form->createRequest( - MultiplierBuilder::create(1) - ->setMinCopies(0) - ->addRemoveButton() - ->addCreateButton() - ->createForm() - )->modifyForm(function (Form $form) { - $form['m']->setValues([ - ['bar' => 'foo'], - ]); - })->setPost([ - 'm' => [ - ['bar' => '', 'multiplier_remover' => ''], - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[multiplier_creator]"]'); - $this->assertDomNotHas($dom, 'input[name="m[0][bar]"]'); - } - - public function testOnRemoveEvent() - { - $called = false; - $response = $this->services->form->createRequest( - MultiplierBuilder::create() - ->setMinCopies(0) - ->addRemoveButton() - ->multiplierModifier(function (Multiplier $multiplier) use (&$called) { - $multiplier->onRemove[] = function () use (&$called) { - $called = true; - }; - }) - ->createForm() - )->setPost([ - 'm' => [ - ['bar' => '', 'multiplier_remover' => ''], - ], - ])->send(); - - $dom = $response->toDomQuery(); - - $this->assertTrue($called); - $this->assertDomNotHas($dom, 'input[name="m[0][bar]"]'); - } - - /** - * Ensure filters (e.g. integer) work on submit, - * since they are dependent on properly set validation scope. - */ - public function testSendRemoveFilter() - { - $this->markTestIncomplete( - '`getValues()` returns array `["m" => [], "m2" => []]`, ' - . 'even though it works just fine when sending without the button.' - ); - - $response = $this->services->form->createRequest( - MultiplierBuilder::create(2) - ->setMinCopies(1) - ->fields([]) - ->beforeFormModifier(function (Form $form) { - $form->addInteger('num'); - }) - ->multiplierModifier(function (Multiplier $multiplier) { - $multiplier->onCreate[] = function (Container $container) { - $container->addInteger('mnum')->setDefaultValue(47); - }; - $multiplier->addRemoveButton(); - }) - ->formModifier(function (Form $form) { - $form['m2'] = new Multiplier(function (Container $container) { - $container->addInteger('m2num')->setDefaultValue(72); - }); - }) - ->createForm() - ) - ->setPost([ - 'num' => '11', - 'm' => [ - ['mnum' => '49'], - ['mnum' => '47', 'multiplier_remover' => ''], - ], - 'm2' => [ - ['m2num' => '72'], - ], - ])->send(); - - $this->assertTrue($response->isSuccess()); - $this->assertSame([ - 'num' => 11, - 'm' => [ - ['mnum' => 49], - ], - 'm2' => [ - ['m2num' => 72], - ], - ], $response->getValues()); - - $dom = $response->toDomQuery(); - - $this->assertDomHas($dom, 'input[name="m[0][mnum]"][value="49"]'); - $this->assertDomNotHas($dom, 'input[name="m[1][mnum]"]'); - } - -} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..86c92a0 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,10 @@ +