diff --git a/composer.json b/composer.json index 76c5d10..58d9282 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,8 @@ }, "require": { "php": "^8.2", - "symfony/dotenv": "^6.1" + "symfony/dotenv": "^6.1", + "symfony/yaml": "^6.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.5", diff --git a/src/Configuration/YamlConfigurationFileReader.php b/src/Configuration/YamlConfigurationFileReader.php new file mode 100644 index 0000000..c97819b --- /dev/null +++ b/src/Configuration/YamlConfigurationFileReader.php @@ -0,0 +1,46 @@ + $hashTable */ + return new HashTableConfiguration($hashTable, $pathDelimiter); + } +} diff --git a/tests/Configuration/YamlConfigurationFileReaderTest.php b/tests/Configuration/YamlConfigurationFileReaderTest.php new file mode 100644 index 0000000..2157db7 --- /dev/null +++ b/tests/Configuration/YamlConfigurationFileReaderTest.php @@ -0,0 +1,71 @@ +reader = new YamlConfigurationFileReader(); + } + + public function testEmptyPathDelimiterThrowsException(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Path delimiter cannot be empty'); + /** @psalm-suppress InvalidArgument Purposely testing an empty path delimiter */ + $this->reader->readConfiguration(__DIR__ . '/files/configuration.yaml', ''); + } + + public function testReadingConfigurationCreatesConfigurationFromContentsOfYamlFile(): void + { + $configuration = $this->reader->readConfiguration(__DIR__ . '/files/configuration.yaml'); + $this->assertSame('bar', $configuration->getString('foo')); + } + + public function testReadingConfigurationWithCustomDelimiterAllowsAccessWithThatDelimiter(): void + { + $configuration = $this->reader->readConfiguration(__DIR__ . '/files/configuration-delimiter.yaml', ':'); + $this->assertSame('baz', $configuration->getString('foo:bar')); + } + + public function testReadingInvalidYamlThrowsException(): void + { + $path = __DIR__ . '/files/invalid-configuration.yaml'; + $this->expectException(InvalidConfigurationFileException::class); + $this->expectExceptionMessage("Invalid YAML in $path"); + $this->reader->readConfiguration($path); + } + + public function testReadingNonExistentPathThrowsException(): void + { + $this->expectException(InvalidConfigurationFileException::class); + $this->expectExceptionMessage('/doesnotexist does not exist'); + $this->reader->readConfiguration('/doesnotexist'); + } + + public function testReadingYamlThatDoesNotMapToAssociativeArrayThrowsException(): void + { + $path = __DIR__ . '/files/non-hash-table.yaml'; + $this->expectException(InvalidConfigurationFileException::class); + $this->expectExceptionMessage("YAML in $path does not parse to an associative array"); + $this->reader->readConfiguration($path); + } +} diff --git a/tests/Configuration/files/configuration-delimiter.yaml b/tests/Configuration/files/configuration-delimiter.yaml new file mode 100644 index 0000000..2c4e162 --- /dev/null +++ b/tests/Configuration/files/configuration-delimiter.yaml @@ -0,0 +1,2 @@ +foo: + bar: baz diff --git a/tests/Configuration/files/configuration.yaml b/tests/Configuration/files/configuration.yaml new file mode 100644 index 0000000..20e9ff3 --- /dev/null +++ b/tests/Configuration/files/configuration.yaml @@ -0,0 +1 @@ +foo: bar diff --git a/tests/Configuration/files/invalid-configuration.yaml b/tests/Configuration/files/invalid-configuration.yaml new file mode 100644 index 0000000..78dc3ea --- /dev/null +++ b/tests/Configuration/files/invalid-configuration.yaml @@ -0,0 +1 @@ +": diff --git a/tests/Configuration/files/non-hash-table.yaml b/tests/Configuration/files/non-hash-table.yaml new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/tests/Configuration/files/non-hash-table.yaml @@ -0,0 +1 @@ +foo