From 7280f8693dcde36c8e0641d7a0c9cee29cce078b Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 5 Aug 2022 15:26:22 +0000 Subject: [PATCH] Merge pull request #348 from hydephp/create-static-array-parser Create static array parser https://github.com/hydephp/develop/commit/09a038bcbbeefaa7cc0e8c0ac9338c8fdb8fa464 --- src/Actions/BladeMatterParser.php | 51 ++++++++++++++++++++++++- tests/Feature/BladeMatterParserTest.php | 34 ++++++++++++++++- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/Actions/BladeMatterParser.php b/src/Actions/BladeMatterParser.php index d7fb526a..dd7674da 100644 --- a/src/Actions/BladeMatterParser.php +++ b/src/Actions/BladeMatterParser.php @@ -110,15 +110,62 @@ public static function extractValue(string $line): string return trim($key); } - /** @internal */ + /** @internal Return the proper type for the string */ public static function normalizeValue($value): mixed { + $value = trim($value); + if ($value === 'null') { return null; } + if (static::isValueArrayString($value)) { + return static::parseArrayString($value); + } + // This will cast integers, floats, and booleans to their respective types - // Still working on a way to handle arrays and objects + // Still working on a way to handle multidimensional arrays and objects return json_decode($value) ?? $value; } + + /** @internal */ + public static function parseArrayString(string $string): array + { + $array = []; + + // Trim input string + $string = trim($string); + + // Check if string is an array + if (! static::isValueArrayString($string)) { + throw new \RuntimeException('Failed parsing BladeMatter array. Input string must follow array syntax.'); + } + + // Check if string is multidimensional (not yet supported) + if (substr_count($string, '[') > 1 || substr_count($string, ']') > 1) { + throw new \RuntimeException('Failed parsing BladeMatter array. Multidimensional arrays are not supported yet.'); + } + + // Remove opening and closing brackets + $string = substr($string, 1, strlen($string) - 2); + + // tokenize string between commas + $tokens = explode(',', $string); + + // Parse each token + foreach ($tokens as $entry) { + // Split string into key/value pairs + $pair = explode('=>', $entry); + + // Add key/value pair to array + $array[static::normalizeValue(trim(trim($pair[0]), "'"))] = static::normalizeValue(trim(trim($pair[1]), "'")); + } + + return $array; + } + + protected static function isValueArrayString(string $string): bool + { + return str_starts_with($string, '[') && str_ends_with($string, ']'); + } } diff --git a/tests/Feature/BladeMatterParserTest.php b/tests/Feature/BladeMatterParserTest.php index 58df102d..01de3df6 100644 --- a/tests/Feature/BladeMatterParserTest.php +++ b/tests/Feature/BladeMatterParserTest.php @@ -58,6 +58,12 @@ public function test_can_parse_front_matter_with_various_formats() } } + public function test_can_parse_front_matter_with_array() + { + $document = "@php(\$foo = ['bar' => 'baz'])"; + $this->assertEquals(['foo' => ['bar' => 'baz']], BladeMatterParser::parseString($document)); + } + public function test_line_matches_front_matter() { $this->assertTrue(BladeMatterParser::lineMatchesFrontMatter('@php($foo = "bar")')); @@ -97,6 +103,32 @@ public function test_normalize_value() $this->assertSame(1.0, BladeMatterParser::normalizeValue('1.0')); $this->assertSame(0.0, BladeMatterParser::normalizeValue('0.0')); $this->assertSame(null, BladeMatterParser::normalizeValue('null')); - $this->assertSame('["foo" => "bar"]', BladeMatterParser::normalizeValue('["foo" => "bar"]')); + $this->assertSame(['foo' => 'bar'], BladeMatterParser::normalizeValue('["foo" => "bar"]')); + $this->assertSame(['foo' => 'bar'], BladeMatterParser::normalizeValue("['foo' => 'bar']")); + } + + public function test_parse_array_string() + { + $this->assertSame(['foo' => 'bar'], BladeMatterParser::parseArrayString('["foo" => "bar"]')); + $this->assertSame(['foo' => 'bar'], BladeMatterParser::parseArrayString('["foo" => "bar"]')); + $this->assertSame(['foo' => 'bar'], BladeMatterParser::parseArrayString("['foo' => 'bar']")); + + $this->assertSame(['foo' => 'bar', 'bar' => 'baz'], BladeMatterParser::parseArrayString('["foo" => "bar", "bar" => "baz"]')); + $this->assertSame(['foo' => 'true'], BladeMatterParser::parseArrayString('["foo" => "true"]')); + $this->assertSame(['foo' => true], BladeMatterParser::parseArrayString('["foo" => true]')); + $this->assertSame(['foo' => '1'], BladeMatterParser::parseArrayString('["foo" => "1"]')); + $this->assertSame(['foo' => 1], BladeMatterParser::parseArrayString('["foo" => 1]')); + } + + public function test_parse_invalid_array_string() + { + $this->expectException(\RuntimeException::class); + BladeMatterParser::parseArrayString('foo'); + } + + public function test_parse_multidimensional_array_string() + { + $this->expectException(\RuntimeException::class); + BladeMatterParser::parseArrayString('["foo" => ["bar" => "baz"]]'); } }