diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a6b780f..8b6ec0b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,11 +20,16 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - coverage: pcov + coverage: xdebug tools: composer:v2 - name: Install dependencies run: composer update ${{ matrix.deps_strategy }} - name: Tests - run: vendor/bin/phpunit --colors=always + run: vendor/bin/phpunit --colors=always --coverage-clover=coverage.xml + + - name: SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/README.md b/README.md index 7bcc4a9..1e99249 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ Front Matter ============ [![Packagist](https://img.shields.io/packagist/v/webuni/front-matter.svg?style=flat-square)](https://packagist.org/packages/webuni/front-matter) -[![Build Status](https://img.shields.io/github/workflow/status/webuni/front-matter/Tests/master.svg?style=flat-square)](https://github.com/webuni/front-matter/actions?query=workflow%3ATests+branch%3Amaster) -[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/quality/g/webuni/front-matter?style=flat-square)](https://scrutinizer-ci.com/g/webuni/front-matter/?branch=master) -[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/webuni/front-matter?style=flat-square)](https://scrutinizer-ci.com/g/webuni/front-matter/?branch=master) +[![Build Status](https://img.shields.io/github/workflow/status/webuni/front-matter/Tests/main.svg?style=flat-square)](https://github.com/webuni/front-matter/actions?query=workflow%3ATests+branch%3Amain) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=webuni_front-matter&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=webuni_front-matter) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=webuni_front-matter&metric=coverage)](https://sonarcloud.io/summary/new_code?id=webuni_front-matter) The most universal Front matter (yaml, json, neon, toml) parser and dumper for PHP. Front matter allows page-specific variables to be included at the top of a page. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index faeb3ad..56fc576 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,10 @@ - + + + ./src + + ./tests/ diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..e90f0e7 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,6 @@ +sonar.organization=webuni +sonar.projectKey=webuni_front-matter + +sonar.sources=src +sonar.tests=tests +sonar.php.coverage.reportPaths=coverage.xml diff --git a/src/FrontMatter.php b/src/FrontMatter.php index 22766c6..a6b0a0b 100644 --- a/src/FrontMatter.php +++ b/src/FrontMatter.php @@ -44,8 +44,7 @@ public function __construct(ProcessorInterface $processor = null, string $startS $this->startSep = $startSep; $this->endSep = $endSep; $this->processor = $processor ?: new YamlProcessor(); - - $this->regexp = '{^(?:'.preg_quote($startSep).")[\r\n|\n]*(.*?)[\r\n|\n]+(?:".preg_quote($endSep).")[\r\n|\n]*(.*)$}s"; + $this->regexp = $this->getRegExp($startSep, $endSep); } /** @@ -111,4 +110,13 @@ private function revealIndention(string $string): string return ''; } + + private function getRegExp(string $startSep, string $endSep): string + { + $startSepQuoted = preg_quote($startSep); + $endSepQuoted = preg_quote($endSep); + $newline = '[\r\n|\n]'; + + return "{^(?:{$startSepQuoted}){$newline}*(.*?){$newline}+(?:{$endSepQuoted}){$newline}*(.*)$}s"; + } } diff --git a/src/FrontMatterChain.php b/src/FrontMatterChain.php index abcacdc..b5fcf82 100644 --- a/src/FrontMatterChain.php +++ b/src/FrontMatterChain.php @@ -12,6 +12,7 @@ namespace Webuni\FrontMatter; +use InvalidArgumentException; use Webuni\FrontMatter\Pug\PugCommentFrontMatter; use Webuni\FrontMatter\Twig\TwigCommentFrontMatter; @@ -24,14 +25,16 @@ public function __construct(iterable $adapters) { foreach ($adapters as $adapter) { if (!$adapter instanceof FrontMatterInterface) { - throw new \InvalidArgumentException('Adapter should be instance of '.FrontMatterInterface::class); + throw new InvalidArgumentException('Adapter should be instance of '.FrontMatterInterface::class); } $this->adapters[] = $adapter; } if (empty($this->adapters)) { - throw new \InvalidArgumentException('It is necessary add at least one front matter adapter '.FrontMatterInterface::class); + throw new InvalidArgumentException( + 'It is necessary add at least one front matter adapter '.FrontMatterInterface::class + ); } } diff --git a/src/Pug/PugCommentFrontMatter.php b/src/Pug/PugCommentFrontMatter.php index 2910dcd..509f882 100644 --- a/src/Pug/PugCommentFrontMatter.php +++ b/src/Pug/PugCommentFrontMatter.php @@ -23,6 +23,7 @@ final class PugCommentFrontMatter { private function __construct() { + // prevent any instantiation } public static function createWithEndComment(ProcessorInterface $processor = null): FrontMatter diff --git a/src/Twig/DataToTwigConvertor.php b/src/Twig/DataToTwigConvertor.php index b5e8706..9c30466 100644 --- a/src/Twig/DataToTwigConvertor.php +++ b/src/Twig/DataToTwigConvertor.php @@ -12,6 +12,8 @@ namespace Webuni\FrontMatter\Twig; +use DateTimeInterface; + class DataToTwigConvertor { /** @var callable */ @@ -24,7 +26,6 @@ public function __invoke(array $data): string return (string) $convertor($data); } - protected function __construct(callable $convertor) { $this->convertor = $convertor; @@ -37,7 +38,7 @@ protected function __construct(callable $convertor) */ public static function nothing(): self { - return new self(function (array $data) { + return new self(function () { return ''; }); } @@ -55,7 +56,9 @@ public static function vars(bool $force = true): self if (is_int($key)) { continue; } - $content .= "{% set $key = " . ($force ? '' : "$key is defined ? $key : ") . self::valueToTwig($value) . " %}\n"; + + $value = ($force ? '' : "$key is defined ? $key : ") . self::valueToTwig($value); + $content .= "{% set {$key} = {$value} %}\n"; } return $content; @@ -72,7 +75,9 @@ public static function vars(bool $force = true): self public static function var(string $name, bool $force = true): self { return new self(function (array $data) use ($name, $force) { - return "{% set $name = " . ($force ? '' : "$name is defined ? $name : ") . self::valueToTwig($data) . "%}\n"; + $value = ($force ? '' : "$name is defined ? $name : ") . self::valueToTwig($data); + + return "{% set {$name} = {$value} %}\n"; }); } @@ -83,7 +88,7 @@ public static function var(string $name, bool $force = true): self */ protected static function valueToTwig($value): string { - if ($value instanceof \DateTimeInterface) { + if ($value instanceof DateTimeInterface) { return '(' . $value->getTimestamp() . "|date_modify('0sec'))"; } diff --git a/src/Twig/FrontMatterLoader.php b/src/Twig/FrontMatterLoader.php index 95ba053..7db03bf 100644 --- a/src/Twig/FrontMatterLoader.php +++ b/src/Twig/FrontMatterLoader.php @@ -27,7 +27,11 @@ class FrontMatterLoader implements LoaderInterface /** @var DataToTwigConvertor */ private $convertor; - public function __construct(FrontMatterInterface $parser, LoaderInterface $loader, DataToTwigConvertor $convertor = null) + public function __construct( + FrontMatterInterface $parser, + LoaderInterface $loader, + DataToTwigConvertor $convertor = null + ) { $this->loader = $loader; $this->parser = $parser; diff --git a/src/Twig/TwigCommentFrontMatter.php b/src/Twig/TwigCommentFrontMatter.php index 457b25f..1d644a4 100644 --- a/src/Twig/TwigCommentFrontMatter.php +++ b/src/Twig/TwigCommentFrontMatter.php @@ -23,6 +23,7 @@ final class TwigCommentFrontMatter { private function __construct() { + // prevent any instantiation } public static function create(ProcessorInterface $processor = null): FrontMatter diff --git a/tests/FrontMatterChainTest.php b/tests/FrontMatterChainTest.php index 5344066..72067c1 100644 --- a/tests/FrontMatterChainTest.php +++ b/tests/FrontMatterChainTest.php @@ -34,7 +34,9 @@ protected function setUp(): void public function testEmptyAdapters(): void { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('It is necessary add at least one front matter adapter '.FrontMatterInterface::class); + $this->expectExceptionMessage( + 'It is necessary add at least one front matter adapter '.FrontMatterInterface::class + ); new FrontMatterChain([]); } diff --git a/tests/FrontMatterTest.php b/tests/FrontMatterTest.php index 0ff0f27..8a42b7b 100644 --- a/tests/FrontMatterTest.php +++ b/tests/FrontMatterTest.php @@ -38,7 +38,12 @@ public function testYaml(string $string, array $data, string $content, bool $has /** * @dataProvider getSeparator */ - public function testYamlWithCustomSeparator(string $string, array $data, string $content, bool $hasFrontMatter): void + public function testYamlWithCustomSeparator( + string $string, + array $data, + string $content, + bool $hasFrontMatter + ): void { $frontMatter = new FrontMatter(null, ''); $document = $frontMatter->parse($string); diff --git a/tests/Twig/DataToTwigConvertorTest.php b/tests/Twig/DataToTwigConvertorTest.php index a1173ae..26f727f 100644 --- a/tests/Twig/DataToTwigConvertorTest.php +++ b/tests/Twig/DataToTwigConvertorTest.php @@ -34,35 +34,21 @@ public function testNothing(): void public function testVars(): void { $convertor = DataToTwigConvertor::vars(); - $twig = '{% set foo = "bar" %} -{% set number = 1234 %} -{% set pi = 3.14159 %} -{% set date = (1464307200|date_modify(\'0sec\')) %} -{% set empty = null %} -{% set multiline = "Multiple\nLine\nString\n" %} -{% set object = {key: "value", datetime: (1605185652|date_modify(\'0sec\')), values: {0: "one", 1: "two", }, } %} -'; + $twig = file_get_contents(__DIR__.'/templates/vars.twig'); self::assertEquals($twig, $convertor($this->data)); } public function testOptionalVars(): void { $convertor = DataToTwigConvertor::vars(false); - $twig = '{% set foo = foo is defined ? foo : "bar" %} -{% set number = number is defined ? number : 1234 %} -{% set pi = pi is defined ? pi : 3.14159 %} -{% set date = date is defined ? date : (1464307200|date_modify(\'0sec\')) %} -{% set empty = empty is defined ? empty : null %} -{% set multiline = multiline is defined ? multiline : "Multiple\nLine\nString\n" %} -{% set object = object is defined ? object : {key: "value", datetime: (1605185652|date_modify(\'0sec\')), values: {0: "one", 1: "two", }, } %} -'; + $twig = file_get_contents(__DIR__.'/templates/optionalvars.twig'); self::assertEquals($twig, $convertor($this->data)); } public function testVar(): void { $convertor = DataToTwigConvertor::var('parameters'); - $twig = '{% set parameters = {foo: "bar", number: 1234, pi: 3.14159, date: (1464307200|date_modify(\'0sec\')), empty: null, multiline: "Multiple\nLine\nString\n", object: {key: "value", datetime: (1605185652|date_modify(\'0sec\')), values: {0: "one", 1: "two", }, }, }%}'."\n"; + $twig = file_get_contents(__DIR__.'/templates/var.twig'); self::assertEquals($twig, $convertor($this->data)); } } diff --git a/tests/Twig/templates/optionalvars.twig b/tests/Twig/templates/optionalvars.twig new file mode 100644 index 0000000..44629d9 --- /dev/null +++ b/tests/Twig/templates/optionalvars.twig @@ -0,0 +1,7 @@ +{% set foo = foo is defined ? foo : "bar" %} +{% set number = number is defined ? number : 1234 %} +{% set pi = pi is defined ? pi : 3.14159 %} +{% set date = date is defined ? date : (1464307200|date_modify('0sec')) %} +{% set empty = empty is defined ? empty : null %} +{% set multiline = multiline is defined ? multiline : "Multiple\nLine\nString\n" %} +{% set object = object is defined ? object : {key: "value", datetime: (1605185652|date_modify('0sec')), values: {0: "one", 1: "two", }, } %} diff --git a/tests/Twig/templates/var.twig b/tests/Twig/templates/var.twig new file mode 100644 index 0000000..4ec0630 --- /dev/null +++ b/tests/Twig/templates/var.twig @@ -0,0 +1 @@ +{% set parameters = {foo: "bar", number: 1234, pi: 3.14159, date: (1464307200|date_modify('0sec')), empty: null, multiline: "Multiple\nLine\nString\n", object: {key: "value", datetime: (1605185652|date_modify('0sec')), values: {0: "one", 1: "two", }, }, } %} diff --git a/tests/Twig/templates/vars.twig b/tests/Twig/templates/vars.twig new file mode 100644 index 0000000..ab694a9 --- /dev/null +++ b/tests/Twig/templates/vars.twig @@ -0,0 +1,7 @@ +{% set foo = "bar" %} +{% set number = 1234 %} +{% set pi = 3.14159 %} +{% set date = (1464307200|date_modify('0sec')) %} +{% set empty = null %} +{% set multiline = "Multiple\nLine\nString\n" %} +{% set object = {key: "value", datetime: (1605185652|date_modify('0sec')), values: {0: "one", 1: "two", }, } %}