From 13318e54387b2be35deb04312c21eb1bfce82824 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <233836+stevegrunwell@users.noreply.github.com> Date: Thu, 10 Jul 2025 17:48:48 -0400 Subject: [PATCH 1/6] Remove PHP 5.x from composer.json, GitHub Actions --- .github/workflows/unit-tests.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index e6f3aea..3435a7c 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] + php-version: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/composer.json b/composer.json index 27be0dc..2a98380 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "source": "https://github.com/stevegrunwell/phpunit-markup-assertions/" }, "require": { - "php": "^5.6 || ^7.0 || ^8.0", + "php": "^7.0 || ^8.0", "symfony/css-selector": "^3.4|^4.4|^5.4|^6.0", "symfony/dom-crawler": "^3.4|^4.4|^5.4|^6.0" }, From fead4597be845cb0d113f4bff87d3c69a1af0f2e Mon Sep 17 00:00:00 2001 From: Steve Grunwell <233836+stevegrunwell@users.noreply.github.com> Date: Thu, 10 Jul 2025 17:52:16 -0400 Subject: [PATCH 2/6] Add return typehints, missing docblocks to the test class --- tests/MarkupAssertionsTraitTest.php | 50 ++++++++++++++++------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/tests/MarkupAssertionsTraitTest.php b/tests/MarkupAssertionsTraitTest.php index 0cacc7f..bee0a6c 100644 --- a/tests/MarkupAssertionsTraitTest.php +++ b/tests/MarkupAssertionsTraitTest.php @@ -19,7 +19,7 @@ class MarkupAssertionsTraitTest extends TestCase * @testdox assertContainsSelector() should find matching selectors * @dataProvider provideSelectorVariants */ - public function assertContainsSelector_should_find_matching_selectors($selector) + public function assertContainsSelector_should_find_matching_selectors(string $selector): void { $this->assertContainsSelector( $selector, @@ -31,7 +31,7 @@ public function assertContainsSelector_should_find_matching_selectors($selector) * @test * @testdox assertContainsSelector() should pick up multiple instances of a selector */ - public function assertContainsSelector_should_pick_up_multiple_instances() + public function assertContainsSelector_should_pick_up_multiple_instances(): void { $this->assertContainsSelector( 'a', @@ -44,7 +44,7 @@ public function assertContainsSelector_should_pick_up_multiple_instances() * @testdox assertNotContainsSelector() should verify that the given selector does not exist * @dataProvider provideSelectorVariants */ - public function assertNotContainsSelector_should_verify_that_the_given_selector_does_not_exist($selector) + public function assertNotContainsSelector_should_verify_that_the_given_selector_does_not_exist(string $selector): void { $this->assertNotContainsSelector( $selector, @@ -56,7 +56,7 @@ public function assertNotContainsSelector_should_verify_that_the_given_selector_ * @test * @testdox assertSelectorCount() should count the instances of a selector */ - public function assertSelectorCount_should_count_the_number_of_instances() + public function assertSelectorCount_should_count_the_number_of_instances(): void { $this->assertSelectorCount( 3, @@ -69,7 +69,7 @@ public function assertSelectorCount_should_count_the_number_of_instances() * @test * @testdox assertHasElementWithAttributes() should find an element with the given attributes */ - public function assertHasElementWithAttributes_should_find_elements_with_matching_attributes() + public function assertHasElementWithAttributes_should_find_elements_with_matching_attributes(): void { $this->assertHasElementWithAttributes( [ @@ -85,7 +85,7 @@ public function assertHasElementWithAttributes_should_find_elements_with_matchin * @testdox assertHasElementWithAttributes() should be able to parse spaces in attribute values * @ticket https://github.com/stevegrunwell/phpunit-markup-assertions/issues/13 */ - public function assertHasElementWithAttributes_should_be_able_to_handle_spaces() + public function assertHasElementWithAttributes_should_be_able_to_handle_spaces(): void { $this->assertHasElementWithAttributes( [ @@ -99,7 +99,7 @@ public function assertHasElementWithAttributes_should_be_able_to_handle_spaces() * @test * @testdox assertNotHasElementWithAttributes() should ensure no element has the provided attributes */ - public function assertNotHasElementWithAttributes_should_find_no_elements_with_matching_attributes() + public function assertNotHasElementWithAttributes_should_find_no_elements_with_matching_attributes(): void { $this->assertNotHasElementWithAttributes( [ @@ -114,7 +114,7 @@ public function assertNotHasElementWithAttributes_should_find_no_elements_with_m * @test * @testdox assertElementContains() should be able to search for a selector */ - public function assertElementContains_can_match_a_selector() + public function assertElementContains_can_match_a_selector(): void { $this->assertElementContains( 'ipsum', @@ -127,7 +127,7 @@ public function assertElementContains_can_match_a_selector() * @test * @testdox assertElementContains() should be able to chain multiple selectors */ - public function assertElementContains_can_chain_multiple_selectors() + public function assertElementContains_can_chain_multiple_selectors(): void { $this->assertElementContains( 'ipsum', @@ -140,7 +140,7 @@ public function assertElementContains_can_chain_multiple_selectors() * @test * @testdox assertElementContains() should scope text to the selected element */ - public function assertElementContains_should_scope_matches_to_selector() + public function assertElementContains_should_scope_matches_to_selector(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage('The #main div does not contain the string "ipsum".'); @@ -159,7 +159,7 @@ public function assertElementContains_should_scope_matches_to_selector() * @dataProvider provideGreetingsInDifferentLanguages * @ticket https://github.com/stevegrunwell/phpunit-markup-assertions/issues/31 */ - public function assertElementContains_should_handle_various_character_sets($greeting) + public function assertElementContains_should_handle_various_character_sets(string $greeting): void { $this->assertElementContains( $greeting, @@ -172,7 +172,7 @@ public function assertElementContains_should_handle_various_character_sets($gree * @test * @testdox assertElementNotContains() should be able to search for a selector */ - public function assertElementNotContains_can_match_a_selector() + public function assertElementNotContains_can_match_a_selector(): void { $this->assertElementNotContains( 'ipsum', @@ -187,7 +187,7 @@ public function assertElementNotContains_can_match_a_selector() * @dataProvider provideGreetingsInDifferentLanguages * @ticket https://github.com/stevegrunwell/phpunit-markup-assertions/issues/31 */ - public function assertElementNotContains_should_handle_various_character_sets($greeting) + public function assertElementNotContains_should_handle_various_character_sets(string $greeting): void { $this->assertElementNotContains( $greeting, @@ -200,7 +200,7 @@ public function assertElementNotContains_should_handle_various_character_sets($g * @test * @testdox assertElementRegExp() should use regular expression matching */ - public function assertElementRegExp_should_use_regular_expression_matching() + public function assertElementRegExp_should_use_regular_expression_matching(): void { $this->assertElementRegExp( '/[A-Z0-9-]+/', @@ -213,7 +213,7 @@ public function assertElementRegExp_should_use_regular_expression_matching() * @test * @testdox assertElementRegExp() should be able to search for nested contents */ - public function assertElementRegExp_should_be_able_to_match_nested_contents() + public function assertElementRegExp_should_be_able_to_match_nested_contents(): void { $this->assertElementRegExp( '/[A-Z]+/', @@ -226,7 +226,7 @@ public function assertElementRegExp_should_be_able_to_match_nested_contents() * @test * @testdox assertElementNotRegExp() should use regular expression matching */ - public function testAssertElementNotRegExp() + public function testAssertElementNotRegExp(): void { $this->assertElementNotRegExp( '/[0-9-]+/', @@ -240,8 +240,10 @@ public function testAssertElementNotRegExp() * @test * @testdox flattenAttributeArray() should flatten an array of attributes * @dataProvider provideAttributes + * + * @param array $attributes */ - public function flattenArrayAttribute_should_flatten_arrays_of_attributes($attributes, $expected) + public function flattenArrayAttribute_should_flatten_arrays_of_attributes(array $attributes, string $expected): void { $method = new \ReflectionMethod($this, 'flattenAttributeArray'); $method->setAccessible(true); @@ -254,7 +256,7 @@ public function flattenArrayAttribute_should_flatten_arrays_of_attributes($attri * @testdox flattenAttributeArray() should throw a RiskyTestError if the array is empty * @dataProvider provideAttributes */ - public function flattenAttributeArray_should_throw_a_RiskyTestError_if_given_an_empty_array() + public function flattenAttributeArray_should_throw_a_RiskyTestError_if_given_an_empty_array(): void { $this->expectException(RiskyTestError::class); @@ -268,7 +270,7 @@ public function flattenAttributeArray_should_throw_a_RiskyTestError_if_given_an_ * @testdox getInnerHtmlOfMatchedElements() should retrieve the inner HTML * @dataProvider provideInnerHtml */ - public function getInnerHtmlOfMatchedElements_should_retrieve_the_inner_HTML($markup, $selector, $expected) + public function getInnerHtmlOfMatchedElements_should_retrieve_the_inner_HTML(string $markup, string $selector, string $expected): void { $method = new \ReflectionMethod($this, 'getInnerHtmlOfMatchedElements'); $method->setAccessible(true); @@ -278,8 +280,10 @@ public function getInnerHtmlOfMatchedElements_should_retrieve_the_inner_HTML($ma /** * Data provider for testFlattenAttributeArray(). + * + * @return array,string}> */ - public function provideAttributes() + public function provideAttributes(): array { return [ 'Single attribute' => [ @@ -321,7 +325,7 @@ public function provideAttributes() * * @return array> */ - public function provideInnerHtml() + public function provideInnerHtml(): array { return [ 'A single match' => [ @@ -347,7 +351,7 @@ public function provideInnerHtml() * * @return array> */ - public function provideSelectorVariants() + public function provideSelectorVariants(): array { return [ 'Simple tag name' => ['a'], @@ -365,7 +369,7 @@ public function provideSelectorVariants() * * @return array> */ - public function provideGreetingsInDifferentLanguages() + public function provideGreetingsInDifferentLanguages(): array { return [ 'Arabic' => ['مرحبا!'], From 72daef6dfbf92bdad505c57adb72e7d3a15988e2 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <233836+stevegrunwell@users.noreply.github.com> Date: Thu, 10 Jul 2025 18:01:06 -0400 Subject: [PATCH 3/6] Add PHP 8.4 to the unit test matrix --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 3435a7c..f64fddf 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] + php-version: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout uses: actions/checkout@v4 From e04ac94a3bad253d6265d651c5f6fa5aecfcc916 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <233836+stevegrunwell@users.noreply.github.com> Date: Thu, 10 Jul 2025 18:12:32 -0400 Subject: [PATCH 4/6] Drop PHP 7.0 as well, since it doesn't support the void typehint --- .github/workflows/unit-tests.yml | 2 +- .phpcs.xml.dist | 2 +- composer.json | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f64fddf..0ec9256 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + php-version: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index 57b3de6..4b4510d 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -20,5 +20,5 @@ - + diff --git a/composer.json b/composer.json index 2a98380..2979148 100644 --- a/composer.json +++ b/composer.json @@ -15,9 +15,9 @@ "source": "https://github.com/stevegrunwell/phpunit-markup-assertions/" }, "require": { - "php": "^7.0 || ^8.0", - "symfony/css-selector": "^3.4|^4.4|^5.4|^6.0", - "symfony/dom-crawler": "^3.4|^4.4|^5.4|^6.0" + "php": "^7.1 || ^8.0", + "symfony/css-selector": "^4.4|^5.4|^6.0", + "symfony/dom-crawler": "^4.4|^5.4|^6.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^1.0", From 169fb0742a68acfec06f4c3b7314ed6bca183722 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <233836+stevegrunwell@users.noreply.github.com> Date: Thu, 10 Jul 2025 18:13:00 -0400 Subject: [PATCH 5/6] Ensure that PHPUnit exists before running PHPStan in GitHub Actions --- .github/workflows/static-code-analysis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/static-code-analysis.yml b/.github/workflows/static-code-analysis.yml index 38397a9..745f15f 100644 --- a/.github/workflows/static-code-analysis.yml +++ b/.github/workflows/static-code-analysis.yml @@ -19,5 +19,10 @@ jobs: - name: Install Composer dependencies uses: ramsey/composer-install@v2 + # PHPUnit Bridge won't install a version of PHPUnit by default, but this will trick + # it into doing so. + - name: Install PHPUnit + run: composer test -- --version + - name: Run PHPStan run: composer static-analysis From 8d1e26ff0a22e3e675008742b91bbe6ab777a21e Mon Sep 17 00:00:00 2001 From: Steve Grunwell <233836+stevegrunwell@users.noreply.github.com> Date: Thu, 10 Jul 2025 18:13:29 -0400 Subject: [PATCH 6/6] Formatting, empty() check to satisfy PHP_CodeSniffer and PHPStan --- src/MarkupAssertionsTrait.php | 2 +- tests/MarkupAssertionsTraitTest.php | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/MarkupAssertionsTrait.php b/src/MarkupAssertionsTrait.php index 59bb6fa..c580bc8 100644 --- a/src/MarkupAssertionsTrait.php +++ b/src/MarkupAssertionsTrait.php @@ -249,7 +249,7 @@ private function flattenAttributeArray(array $attributes) array_walk($attributes, function (&$value, $key) { // Boolean attributes. - if (null === $value) { + if (empty($value)) { $value = sprintf('[%s]', $key); } else { $value = sprintf('[%s="%s"]', $key, htmlspecialchars($value)); diff --git a/tests/MarkupAssertionsTraitTest.php b/tests/MarkupAssertionsTraitTest.php index bee0a6c..642927d 100644 --- a/tests/MarkupAssertionsTraitTest.php +++ b/tests/MarkupAssertionsTraitTest.php @@ -44,8 +44,9 @@ public function assertContainsSelector_should_pick_up_multiple_instances(): void * @testdox assertNotContainsSelector() should verify that the given selector does not exist * @dataProvider provideSelectorVariants */ - public function assertNotContainsSelector_should_verify_that_the_given_selector_does_not_exist(string $selector): void - { + public function assertNotContainsSelector_should_verify_that_the_given_selector_does_not_exist( + string $selector + ): void { $this->assertNotContainsSelector( $selector, '

This element has little to do with the link.

' @@ -270,8 +271,11 @@ public function flattenAttributeArray_should_throw_a_RiskyTestError_if_given_an_ * @testdox getInnerHtmlOfMatchedElements() should retrieve the inner HTML * @dataProvider provideInnerHtml */ - public function getInnerHtmlOfMatchedElements_should_retrieve_the_inner_HTML(string $markup, string $selector, string $expected): void - { + public function getInnerHtmlOfMatchedElements_should_retrieve_the_inner_HTML( + string $markup, + string $selector, + string $expected + ): void { $method = new \ReflectionMethod($this, 'getInnerHtmlOfMatchedElements'); $method->setAccessible(true);