From 56d7c489d18c1194b30216cef4b0b1821d59edcf Mon Sep 17 00:00:00 2001 From: Christopher Georg Date: Tue, 14 Nov 2023 16:55:39 +0100 Subject: [PATCH] feat: drop support for PHP <= 7.3 --- .github/workflows/continuous-integration.yml | 13 +-- .github/workflows/lint.yml | 1 - CHANGELOG.md | 4 + composer.json | 6 +- phpunit.xml.dist | 18 ++-- tests/JsonParserTest.php | 97 +++++++------------- 6 files changed, 47 insertions(+), 92 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 9e07b88..564d6ae 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -16,18 +16,11 @@ jobs: strategy: matrix: php-version: - - "5.3" - - "5.4" - - "5.5" - - "5.6" - - "7.0" - - "7.1" - - "7.2" - - "7.3" - "7.4" - "8.0" - # disabled for now as it leads to PHPUnit installing in a very old 4.3 version due to phpspec/prophecy not allowing 8.1 - # - "8.1" + - "8.1" + - "8.2" + - "8.3" steps: - name: "Checkout" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index cb07e31..d3480bc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,7 +13,6 @@ jobs: strategy: matrix: php-version: - - "5.3" - "7.4" steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index b141347..d44b371 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ You can find newer changelog entries in [GitHub releases](https://github.com/Seldaek/jsonlint/releases) +### 1.11.0 (2023-11-xx) + + * Drop Support for PHP <= 7.3 + ### 1.10.0 (2023-05-11) * Added ALLOW_COMMENTS flag to parse while allowing (and ignoring) inline `//` and multiline `/* */` comments in the JSON document (#81) diff --git a/composer.json b/composer.json index d01217c..bfd785d 100644 --- a/composer.json +++ b/composer.json @@ -12,11 +12,11 @@ } ], "require": { - "php": "^5.3 || ^7.0 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13", - "phpstan/phpstan": "^1.5" + "phpunit/phpunit": "^9.6 || ^10.4", + "phpstan/phpstan": "^1.10" }, "autoload": { "psr-4": { "Seld\\JsonLint\\": "src/Seld/JsonLint/" } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5de888b..a233822 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,14 +1,8 @@ - @@ -17,9 +11,9 @@ - - + + ./src/Seld/JsonLint/ - - + + diff --git a/tests/JsonParserTest.php b/tests/JsonParserTest.php index 560e303..09ca848 100644 --- a/tests/JsonParserTest.php +++ b/tests/JsonParserTest.php @@ -19,7 +19,7 @@ class JsonParserTest extends TestCase /** * @var list */ - protected $json = array( + protected static array $json = [ '42', '42.3', '0.3', '-42', '-42.3', '-0.3', '2e1', '2E1', '-2e1', '-2E1', '2E+2', '2E-2', '-2E+2', '-2E-2', 'true', 'false', 'null', '""', '[]', '{}', '"string"', @@ -42,23 +42,22 @@ class JsonParserTest extends TestCase '"Argument \u0022input\u0022 has an invalid value: ..."', '"👻"', '"\u1f47d"', - ); + ]; /** * @dataProvider provideValidStrings - * @param string $input */ - public function testParsesValidStrings($input) + public function testParsesValidStrings(string $input) { $parser = new JsonParser(); $this->assertEquals(json_decode($input), $parser->parse($input)); } - public function provideValidStrings() + public static function provideValidStrings(): array { - $strings = array(); - foreach ($this->json as $input) { - $strings[] = array($input); + $strings = []; + foreach (self::$json as $input) { + $strings[] = [$input]; } return $strings; @@ -73,7 +72,7 @@ public function testErrorOnTrailingComma() }'); $this->fail('Invalid trailing comma should be detected'); } catch (ParsingException $e) { - $this->assertContains('It appears you have an extra trailing comma', $e->getMessage()); + $this->assertStringContainsString('It appears you have an extra trailing comma', $e->getMessage()); } } @@ -86,7 +85,7 @@ public function testErrorOnInvalidQuotes() }'); $this->fail('Invalid quotes for string should be detected'); } catch (ParsingException $e) { - $this->assertContains('Invalid string, it appears you used single quotes instead of double quotes', $e->getMessage()); + $this->assertStringContainsString('Invalid string, it appears you used single quotes instead of double quotes', $e->getMessage()); } } @@ -99,7 +98,7 @@ public function testErrorOnUnescapedBackslash() }'); $this->fail('Invalid unescaped string should be detected'); } catch (ParsingException $e) { - $this->assertContains('Invalid string, it appears you have an unescaped backslash at: \z', $e->getMessage()); + $this->assertStringContainsString('Invalid string, it appears you have an unescaped backslash at: \z', $e->getMessage()); } } @@ -148,7 +147,7 @@ public function testErrorOnUnterminatedString() $parser->parse('{"bar": "foo}'); $this->fail('Invalid unterminated string should be detected'); } catch (ParsingException $e) { - $this->assertContains('Invalid string, it appears you forgot to terminate a string, or attempted to write a multiline string which is invalid', $e->getMessage()); + $this->assertStringContainsString('Invalid string, it appears you forgot to terminate a string, or attempted to write a multiline string which is invalid', $e->getMessage()); } } @@ -160,7 +159,7 @@ public function testErrorOnMultilineString() bar"}'); $this->fail('Invalid multi-line string should be detected'); } catch (ParsingException $e) { - $this->assertContains('Invalid string, it appears you forgot to terminate a string, or attempted to write a multiline string which is invalid', $e->getMessage()); + $this->assertStringContainsString('Invalid string, it appears you forgot to terminate a string, or attempted to write a multiline string which is invalid', $e->getMessage()); } } @@ -173,14 +172,14 @@ public function testErrorAtBeginning() '); $this->fail('Empty string should be invalid'); } catch (ParsingException $e) { - $this->assertContains("Parse error on line 1:\n\n^", $e->getMessage()); + $this->assertStringContainsString("Parse error on line 1:\n\n^", $e->getMessage()); } } public function testParsesMultiInARow() { $parser = new JsonParser(); - foreach ($this->json as $input) { + foreach (self::$json as $input) { $this->assertEquals(json_decode($input), $parser->parse($input)); } } @@ -193,26 +192,9 @@ public function testDetectsKeyOverrides() $parser->parse('{"a":"b", "a":"c"}', JsonParser::DETECT_KEY_CONFLICTS); $this->fail('Duplicate keys should not be allowed'); } catch (DuplicateKeyException $e) { - $this->assertContains('Duplicate key: a', $e->getMessage()); + $this->assertStringContainsString('Duplicate key: a', $e->getMessage()); $this->assertSame('a', $e->getKey()); - $this->assertSame(array('line' => 1, 'key' => 'a'), $e->getDetails()); - } - } - - public function testDetectsKeyOverridesWithEmpty() - { - $parser = new JsonParser(); - - if (PHP_VERSION_ID >= 70100) { - $this->markTestSkipped('Only for PHP < 7.1'); - } - try { - $parser->parse('{"":"b", "_empty_":"a"}', JsonParser::DETECT_KEY_CONFLICTS); - $this->fail('Duplicate keys should not be allowed'); - } catch (DuplicateKeyException $e) { - $this->assertContains('Duplicate key: _empty_', $e->getMessage()); - $this->assertSame('_empty_', $e->getKey()); - $this->assertSame(array('line' => 1, 'key' => '_empty_'), $e->getDetails()); + $this->assertSame(['line' => 1, 'key' => 'a'], $e->getDetails()); } } @@ -221,28 +203,11 @@ public function testDuplicateKeys() $parser = new JsonParser(); $result = $parser->parse('{"a":"b", "a":"c", "a":"d"}', JsonParser::ALLOW_DUPLICATE_KEYS); - $this->assertThat($result, - $this->logicalAnd( - $this->objectHasAttribute('a'), - $this->objectHasAttribute('a.1'), - $this->objectHasAttribute('a.2') - ) - ); - } - public function testDuplicateKeysWithEmpty() - { - $parser = new JsonParser(); - - if (PHP_VERSION_ID >= 70100) { - $this->markTestSkipped('Only for PHP < 7.1'); - } - $result = $parser->parse('{"":"a", "_empty_":"b"}', JsonParser::ALLOW_DUPLICATE_KEYS); - $this->assertThat($result, - $this->logicalAnd( - $this->objectHasAttribute('_empty_'), - $this->objectHasAttribute('_empty_.1') - ) + $this->assertTrue( + property_exists($result, 'a') && + property_exists($result, 'a.1') && + property_exists($result, 'a.2') ); } @@ -262,7 +227,7 @@ public function testFileWithBOM() $parser->parse((string) file_get_contents(dirname(__FILE__) .'/bom.json')); $this->fail('BOM should be detected'); } catch (ParsingException $e) { - $this->assertContains('BOM detected', $e->getMessage()); + $this->assertStringContainsString('BOM detected', $e->getMessage()); } } @@ -281,7 +246,7 @@ public function testParseNoneTerminatingString() try { $this->assertEquals('', $parser->parse('{"')); } catch (ParsingException $e) { - $this->assertContains('Invalid string, it appears you forgot to terminate a string', $e->getMessage()); + $this->assertStringContainsString('Invalid string, it appears you forgot to terminate a string', $e->getMessage()); } } @@ -299,25 +264,25 @@ public function testParsesJsonStringWithComments($withComment, $valid) $this->assertEquals(json_decode($valid), $parser->parse($withComment, JsonParser::ALLOW_COMMENTS)); } - public function provideStringsWithComments() + public static function provideStringsWithComments(): array { - $json = array( + $json = [ '["a", "sdfsd"]//test' => '["a", "sdfsd"]', '[/*"a",*/ "sdfsd"]//' => '["sdfsd"]', '["a", "sdf//sd"]/**/' => '["a", "sdf//sd"]', '/**/{/*"":*/"g":"foo"}' => '{"g":"foo"}', '{"a":"b"}//, "b":"c"}' => '{"a":"b"}', - ); + ]; - $strings = array(); + $strings = []; foreach ($json as $withComment => $valid) { - $strings[] = array($withComment, $valid); + $strings[] = [$withComment, $valid]; } - $strings[] = array( - file_get_contents(dirname(__FILE__) .'/with-comments.json'), - file_get_contents(dirname(__FILE__) .'/without-comments.json') - ); + $strings[] = [ + file_get_contents(__DIR__ .'/with-comments.json'), + file_get_contents(__DIR__ .'/without-comments.json') + ]; return $strings; }