diff --git a/Parser/JsonParser.php b/Parser/JsonParser.php
new file mode 100644
index 0000000..000ec5c
--- /dev/null
+++ b/Parser/JsonParser.php
@@ -0,0 +1,121 @@
+prettyPrint(json_encode($data));
+ }
+
+ /**
+ * Returns pretty printed JSON string.
+ * Custom implementation for compatibility with PHP < 5.4 and custom spacing.
+ *
+ * @param string $json JSON data to be pretty printed
+ * @param string $spacer Spacer used e.g. ' ' or "\t"
+ * @param int $spacing Multiplicand for spacer (count)
+ * @param bool $newLineAtEof Whether to write a nl at end of file or not
+ *
+ * @return string Pretty printed JSON data
+ */
+ protected function prettyPrint($json, $spacer = ' ', $spacing = 2, $newLineAtEof = true)
+ {
+ $result = '';
+ $level = 0;
+ $in_quotes = false;
+ $in_escape = false;
+ $ends_line_level = null;
+ $json_length = strlen($json);
+
+ for ($i = 0; $i < $json_length; ++$i) {
+ $char = $json[$i];
+ $new_line_level = null;
+ $post = '';
+ if ($ends_line_level !== null) {
+ $new_line_level = $ends_line_level;
+ $ends_line_level = null;
+ }
+ if ($in_escape) {
+ $in_escape = false;
+ } elseif ($char === '"') {
+ $in_quotes = !$in_quotes;
+ } elseif (!$in_quotes) {
+ switch ($char) {
+ case '}':
+ case ']':
+ $level--;
+ $ends_line_level = null;
+ $new_line_level = $level;
+ break;
+
+ case '{':
+ case '[':
+ $level++;
+ case ',':
+ $ends_line_level = $level;
+ break;
+
+ case ':':
+ $post = ' ';
+ break;
+
+ case ' ':
+ case "\t":
+ case "\n":
+ case "\r":
+ $char = '';
+ $ends_line_level = $new_line_level;
+ $new_line_level = null;
+ break;
+ }
+ } elseif ($char === '\\') {
+ $in_escape = true;
+ }
+ if ($new_line_level !== null) {
+ $result .= "\n".str_repeat(str_repeat($spacer, $spacing), $new_line_level);
+ }
+ $result .= $char.$post;
+ }
+
+ $result = trim($result);
+
+ if (true === $newLineAtEof) {
+ $result .= "\n";
+ }
+
+ return $result;
+ }
+}
diff --git a/Parser/ParserInterface.php b/Parser/ParserInterface.php
new file mode 100644
index 0000000..f7f0ce4
--- /dev/null
+++ b/Parser/ParserInterface.php
@@ -0,0 +1,18 @@
+io = $io;
+ $this->parser = $parser;
+ $this->io = $io;
}
+ /**
+ * Processes single operations for a passed parameter file configuration.
+ *
+ * @throws ParseException|\InvalidArgumentException|\RuntimeException
+ */
public function processFile(array $config)
{
$config = $this->processConfig($config);
- $realFile = $config['file'];
+ $realFile = $config['file'];
$parameterKey = $config['parameter-key'];
$exists = is_file($realFile);
- $yamlParser = new Parser();
-
$action = $exists ? 'Updating' : 'Creating';
$this->io->write(sprintf('%s the "%s" file', $action, $realFile));
// Find the expected params
- $expectedValues = $yamlParser->parse(file_get_contents($config['dist-file']));
+ $expectedValues = $this->parser->parse(file_get_contents($config['dist-file']));
+
if (!isset($expectedValues[$parameterKey])) {
throw new \InvalidArgumentException(sprintf('The top-level key %s is missing.', $parameterKey));
}
@@ -39,12 +62,12 @@ public function processFile(array $config)
// find the actual params
$actualValues = array_merge(
- // Preserve other top-level keys than `$parameterKey` in the file
+ // Preserve other top-level keys than `$parameterKey` in the file
$expectedValues,
array($parameterKey => array())
);
if ($exists) {
- $existingValues = $yamlParser->parse(file_get_contents($realFile));
+ $existingValues = $this->parser->parse(file_get_contents($realFile));
if ($existingValues === null) {
$existingValues = array();
}
@@ -56,19 +79,24 @@ public function processFile(array $config)
$actualValues[$parameterKey] = $this->processParams($config, $expectedParams, (array) $actualValues[$parameterKey]);
- if (!is_dir($dir = dirname($realFile))) {
- mkdir($dir, 0755, true);
+ if (!is_dir($dir = dirname($realFile)) && (!@mkdir($dir, 0755, true) && !is_dir($dir))) {
+ throw new \RuntimeException(
+ sprintf('Error while creating directory "%s". Check path and permissions.', $dir)
+ );
}
- file_put_contents($realFile, "# This file is auto-generated during the composer install\n" . Yaml::dump($actualValues, 99));
+ $this->writeFile($realFile, $actualValues);
}
- private function processConfig(array $config)
+ /**
+ * @param array $config
+ *
+ * @return array
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function processConfig(array $config)
{
- if (empty($config['file'])) {
- throw new \InvalidArgumentException('The extra.incenteev-parameters.file setting is required to use this script handler.');
- }
-
if (empty($config['dist-file'])) {
$config['dist-file'] = $config['file'].'.dist';
}
@@ -84,10 +112,10 @@ private function processConfig(array $config)
return $config;
}
- private function processParams(array $config, array $expectedParams, array $actualParams)
+ protected function processParams(array $config, array $expectedParams, array $actualParams)
{
// Grab values for parameters that were renamed
- $renameMap = empty($config['rename-map']) ? array() : (array) $config['rename-map'];
+ $renameMap = empty($config['rename-map']) ? array() : (array) $config['rename-map'];
$actualParams = array_replace($actualParams, $this->processRenamedValues($renameMap, $actualParams));
$keepOutdatedParams = false;
@@ -107,7 +135,16 @@ private function processParams(array $config, array $expectedParams, array $actu
return $this->getParams($expectedParams, $actualParams);
}
- private function getEnvValues(array $envMap)
+ /**
+ * Parses environments variables by map and resolves correct types.
+ * As environment variables can only be strings, they are also parsed to allow specifying null, false,
+ * true or numbers easily.
+ *
+ * @param array $envMap Map used to map data from environment variable name to parameter name.
+ *
+ * @return array
+ */
+ protected function getEnvValues(array $envMap)
{
$params = array();
foreach ($envMap as $param => $env) {
@@ -137,6 +174,18 @@ private function processRenamedValues(array $renameMap, array $actualParams)
return $actualParams;
}
+ /**
+ * Returns the current set of parameters.
+ * If IO mode non interactive it simply sets the expected values, otherwise it asks user for defining missing
+ * parameters.
+ *
+ * @param array $expectedParams Parameters required
+ * @param array $actualParams Parameters defined already
+ *
+ * @return array Updated set of parameters
+ *
+ * @throws \RuntimeException
+ */
private function getParams(array $expectedParams, array $actualParams)
{
// Simply use the expectedParams value as default for the missing params.
@@ -146,7 +195,7 @@ private function getParams(array $expectedParams, array $actualParams)
$isStarted = false;
- foreach ($expectedParams as $key => $message) {
+ foreach ($expectedParams as $key => $value) {
if (array_key_exists($key, $actualParams)) {
continue;
}
@@ -156,7 +205,8 @@ private function getParams(array $expectedParams, array $actualParams)
$this->io->write('Some parameters are missing. Please provide them.');
}
- $default = Inline::dump($message);
+ $default = Inline::dump($value);
+
$value = $this->io->ask(sprintf('%s (%s): ', $key, $default), $default);
$actualParams[$key] = Inline::parse($value);
@@ -164,4 +214,14 @@ private function getParams(array $expectedParams, array $actualParams)
return $actualParams;
}
+
+ /**
+ * Persists configuration.
+ *
+ * @param string $file Filename to persist configuration to.
+ * @param array $configuration Configuration to persist.
+ *
+ * @return bool TRUE after successful persisting the file, otherwise FALSE
+ */
+ abstract protected function writeFile($file, array $configuration);
}
diff --git a/Processor/JsonProcessor.php b/Processor/JsonProcessor.php
new file mode 100644
index 0000000..e11b22c
--- /dev/null
+++ b/Processor/JsonProcessor.php
@@ -0,0 +1,19 @@
+parser->dump($configuration)
+ );
+ }
+}
diff --git a/Processor/YamlProcessor.php b/Processor/YamlProcessor.php
new file mode 100644
index 0000000..a57c3b0
--- /dev/null
+++ b/Processor/YamlProcessor.php
@@ -0,0 +1,21 @@
+getComposer()->getPackage()->getExtra();
@@ -24,14 +66,60 @@ public static function buildParameters(Event $event)
$configs = array($configs);
}
- $processor = new Processor($event->getIO());
-
foreach ($configs as $config) {
if (!is_array($config)) {
throw new \InvalidArgumentException('The extra.incenteev-parameters setting must be an array of configuration objects.');
}
+ if (!array_key_exists('file', $config)) {
+ throw new \InvalidArgumentException('The extra.incenteev-parameters.file setting is required to use this script handler.');
+ }
+
+ $type = self::retrieveConfigurationTypeByFile($config['file']);
+
+ if (self::CONFIGURATION_FORMAT_YAML === $type) {
+ $processor = new YamlProcessor($event->getIO(), new YamlParser());
+ } elseif (self::FILE_EXTENSION_JSON === $type) {
+ $processor = new JsonProcessor($event->getIO(), new JsonParser());
+ } else {
+ throw new \OutOfBoundsException(
+ sprintf(
+ 'Configuration format in file "%s" can not be handled. Currently supported: "%s"',
+ $config['file'],
+ var_export(self::$handable, true)
+ )
+ );
+ }
+
$processor->processFile($config);
}
}
+
+ /**
+ * Returns type of configuration by files extension.
+ * Files with extension ".yml" will be resolved to type YAML, extension ".json" will be resolved to type JSON
+ *
+ * @param string $file File to parse extension from
+ *
+ * @return string Type of configuration, either self::CONFIGURATION_FORMAT_YAML or self::CONFIGURATION_FORMAT_JSON
+ */
+ private static function retrieveConfigurationTypeByFile($file)
+ {
+ $info = new \SplFileInfo($file);
+ $extension = strtolower($info->getExtension());
+
+ switch ($extension) {
+ case self::FILE_EXTENSION_YAML:
+ $type = self::CONFIGURATION_FORMAT_YAML;
+ break;
+ case self::FILE_EXTENSION_JSON:
+ $type = self::CONFIGURATION_FORMAT_JSON;
+ break;
+ default:
+ $type = null;
+ break;
+ }
+
+ return $type;
+ }
}
diff --git a/Tests/JsonProcessorTest.php b/Tests/JsonProcessorTest.php
new file mode 100644
index 0000000..921f586
--- /dev/null
+++ b/Tests/JsonProcessorTest.php
@@ -0,0 +1,178 @@
+io = $this->prophesize('Composer\IO\IOInterface');
+ $this->processor = new JsonProcessor($this->io->reveal(), new JsonParser());
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ foreach ($this->environmentBackup as $var => $value) {
+ if (false === $value) {
+ putenv($var);
+ } else {
+ putenv($var.'='.$value);
+ }
+ }
+ }
+
+ /**
+ * @dataProvider provideInvalidConfiguration
+ */
+ public function testInvalidConfiguration(array $config, $exceptionMessage)
+ {
+ chdir(__DIR__);
+
+ $this->setExpectedException('InvalidArgumentException', $exceptionMessage);
+
+ $this->processor->processFile($config);
+ }
+
+ public function provideInvalidConfiguration()
+ {
+ return array(
+ 'missing default dist file' => array(
+ array(
+ 'file' => 'fixtures/json/invalid/missing.json',
+ ),
+ 'The dist file "fixtures/json/invalid/missing.json.dist" does not exist. Check your dist-file config or create it.',
+ ),
+ 'missing custom dist file' => array(
+ array(
+ 'file' => 'fixtures/json/invalid/missing.json',
+ 'dist-file' => 'fixtures/json/invalid/non-existent.dist.json',
+ ),
+ 'The dist file "fixtures/json/invalid/non-existent.dist.json" does not exist. Check your dist-file config or create it.',
+ ),
+ 'missing top level key in dist file' => array(
+ array(
+ 'file' => 'fixtures/json/invalid/missing_top_level.json',
+ ),
+ 'The top-level key parameters is missing.',
+ ),
+ 'invalid values in the existing file' => array(
+ array(
+ 'file' => 'fixtures/json/invalid/invalid_existing_values.json',
+ ),
+ 'The existing "fixtures/json/invalid/invalid_existing_values.json" file does not contain an array',
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideParameterHandlingTestCases
+ */
+ public function testParameterHandling($testCaseName)
+ {
+ $dataDir = __DIR__.'/fixtures/json/testcases/'.$testCaseName;
+
+ $testCase = array_replace_recursive(
+ array(
+ 'title' => 'unknown test',
+ 'config' => array(
+ 'file' => 'parameters.json',
+ ),
+ 'dist-file' => 'parameters.json.dist',
+ 'environment' => array(),
+ 'interactive' => false,
+ ),
+ (array) Yaml::parse(file_get_contents($dataDir.'/setup.yml'))
+ );
+
+ $workingDir = sys_get_temp_dir().'/incenteev_parameter_handler';
+ $exists = $this->initializeTestCase($testCase, $dataDir, $workingDir);
+
+ $message = sprintf('%s the "%s" file', $exists ? 'Updating' : 'Creating', $testCase['config']['file']);
+ $this->io->write($message)->shouldBeCalled();
+
+ $this->setInteractionExpectations($testCase);
+
+ $this->processor->processFile($testCase['config']);
+
+ $this->assertFileEquals($dataDir.'/expected.json', $workingDir.'/'.$testCase['config']['file'], $testCase['title']);
+ }
+
+ private function initializeTestCase(array $testCase, $dataDir, $workingDir)
+ {
+ $fs = new Filesystem();
+
+ if (is_dir($workingDir)) {
+ $fs->remove($workingDir);
+ }
+
+ $fs->copy($dataDir.'/dist.json', $workingDir.'/'.$testCase['dist-file']);
+
+ if ($exists = file_exists($dataDir.'/existing.json')) {
+ $fs->copy($dataDir.'/existing.json', $workingDir.'/'.$testCase['config']['file']);
+ }
+
+ foreach ($testCase['environment'] as $var => $value) {
+ $this->environmentBackup[$var] = getenv($var);
+ putenv($var.'='.$value);
+ }
+
+ chdir($workingDir);
+
+ return $exists;
+ }
+
+ private function setInteractionExpectations(array $testCase)
+ {
+ $this->io->isInteractive()->willReturn($testCase['interactive']);
+
+ if (!$testCase['interactive']) {
+ return;
+ }
+
+ if (!empty($testCase['requested_params'])) {
+ $this->io->write('Some parameters are missing. Please provide them.')->shouldBeCalledTimes(1);
+ }
+
+ foreach ($testCase['requested_params'] as $param => $settings) {
+ $this->io->ask(sprintf('%s (%s): ', $param, $settings['default']), $settings['default'])
+ ->willReturn($settings['input'])
+ ->shouldBeCalled();
+ }
+ }
+
+ public function provideParameterHandlingTestCases()
+ {
+ $tests = array();
+
+ foreach (glob(__DIR__.'/fixtures/json/testcases/*/') as $folder) {
+ $tests[] = array(basename($folder));
+ }
+
+ return $tests;
+ }
+}
diff --git a/Tests/ScriptHandlerTest.php b/Tests/ScriptHandlerTest.php
index b77e76a..44b8ec5 100644
--- a/Tests/ScriptHandlerTest.php
+++ b/Tests/ScriptHandlerTest.php
@@ -7,8 +7,19 @@
class ScriptHandlerTest extends ProphecyTestCase
{
+ /**
+ * @var \Composer\Script\Event
+ */
private $event;
+
+ /**
+ * @var \Composer\IO\IOInterface
+ */
private $io;
+
+ /**
+ * @var \Composer\Package\PackageInterface
+ */
private $package;
protected function setUp()
@@ -18,6 +29,7 @@ protected function setUp()
$this->event = $this->prophesize('Composer\Script\Event');
$this->io = $this->prophesize('Composer\IO\IOInterface');
$this->package = $this->prophesize('Composer\Package\PackageInterface');
+ /* @var $composer \Composer\Composer */
$composer = $this->prophesize('Composer\Composer');
$composer->getPackage()->willReturn($this->package);
diff --git a/Tests/ProcessorTest.php b/Tests/YamlProcessorTest.php
similarity index 77%
rename from Tests/ProcessorTest.php
rename to Tests/YamlProcessorTest.php
index babf44a..226d31f 100644
--- a/Tests/ProcessorTest.php
+++ b/Tests/YamlProcessorTest.php
@@ -2,18 +2,26 @@
namespace Incenteev\ParameterHandler\Tests;
-use Incenteev\ParameterHandler\Processor;
+use Incenteev\ParameterHandler\Parser\YamlParser;
+use Incenteev\ParameterHandler\Processor\YamlProcessor;
use Prophecy\PhpUnit\ProphecyTestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Yaml\Yaml;
-class ProcessorTest extends ProphecyTestCase
+class YamlProcessorTest extends ProphecyTestCase
{
+ /**
+ * @var \Composer\IO\IOInterface
+ */
private $io;
+
+ /**
+ * @var array
+ */
private $environmentBackup = array();
/**
- * @var Processor
+ * @var YamlProcessor
*/
private $processor;
@@ -22,7 +30,7 @@ protected function setUp()
parent::setUp();
$this->io = $this->prophesize('Composer\IO\IOInterface');
- $this->processor = new Processor($this->io->reveal());
+ $this->processor = new YamlProcessor($this->io->reveal(), new YamlParser());
}
protected function tearDown()
@@ -53,34 +61,30 @@ public function testInvalidConfiguration(array $config, $exceptionMessage)
public function provideInvalidConfiguration()
{
return array(
- 'no file' => array(
- array(),
- 'The extra.incenteev-parameters.file setting is required to use this script handler.',
- ),
'missing default dist file' => array(
array(
- 'file' => 'fixtures/invalid/missing.yml',
+ 'file' => 'fixtures/yaml/invalid/missing.yml',
),
- 'The dist file "fixtures/invalid/missing.yml.dist" does not exist. Check your dist-file config or create it.',
+ 'The dist file "fixtures/yaml/invalid/missing.yml.dist" does not exist. Check your dist-file config or create it.',
),
'missing custom dist file' => array(
array(
- 'file' => 'fixtures/invalid/missing.yml',
- 'dist-file' => 'fixtures/invalid/non-existent.dist.yml',
+ 'file' => 'fixtures/yaml/invalid/missing.yml',
+ 'dist-file' => 'fixtures/yaml/invalid/non-existent.dist.yml',
),
- 'The dist file "fixtures/invalid/non-existent.dist.yml" does not exist. Check your dist-file config or create it.',
+ 'The dist file "fixtures/yaml/invalid/non-existent.dist.yml" does not exist. Check your dist-file config or create it.',
),
'missing top level key in dist file' => array(
array(
- 'file' => 'fixtures/invalid/missing_top_level.yml',
+ 'file' => 'fixtures/yaml/invalid/missing_top_level.yml',
),
'The top-level key parameters is missing.',
),
'invalid values in the existing file' => array(
array(
- 'file' => 'fixtures/invalid/invalid_existing_values.yml',
+ 'file' => 'fixtures/yaml/invalid/invalid_existing_values.yml',
),
- 'The existing "fixtures/invalid/invalid_existing_values.yml" file does not contain an array',
+ 'The existing "fixtures/yaml/invalid/invalid_existing_values.yml" file does not contain an array',
),
);
}
@@ -90,7 +94,7 @@ public function provideInvalidConfiguration()
*/
public function testParameterHandling($testCaseName)
{
- $dataDir = __DIR__.'/fixtures/testcases/'.$testCaseName;
+ $dataDir = __DIR__.'/fixtures/yaml/testcases/'.$testCaseName;
$testCase = array_replace_recursive(
array(
@@ -135,7 +139,7 @@ private function initializeTestCase(array $testCase, $dataDir, $workingDir)
foreach ($testCase['environment'] as $var => $value) {
$this->environmentBackup[$var] = getenv($var);
putenv($var.'='.$value);
- };
+ }
chdir($workingDir);
@@ -165,7 +169,7 @@ public function provideParameterHandlingTestCases()
{
$tests = array();
- foreach (glob(__DIR__.'/fixtures/testcases/*/') as $folder) {
+ foreach (glob(__DIR__.'/fixtures/yaml/testcases/*/') as $folder) {
$tests[] = array(basename($folder));
}
diff --git a/Tests/fixtures/json/invalid/invalid_existing_values.json b/Tests/fixtures/json/invalid/invalid_existing_values.json
new file mode 100644
index 0000000..250c317
--- /dev/null
+++ b/Tests/fixtures/json/invalid/invalid_existing_values.json
@@ -0,0 +1 @@
+not valid json
\ No newline at end of file
diff --git a/Tests/fixtures/json/invalid/invalid_existing_values.json.dist b/Tests/fixtures/json/invalid/invalid_existing_values.json.dist
new file mode 100644
index 0000000..e797330
--- /dev/null
+++ b/Tests/fixtures/json/invalid/invalid_existing_values.json.dist
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "bar"
+ }
+}
diff --git a/Tests/fixtures/json/invalid/missing_top_level.json.dist b/Tests/fixtures/json/invalid/missing_top_level.json.dist
new file mode 100644
index 0000000..e63d37b
--- /dev/null
+++ b/Tests/fixtures/json/invalid/missing_top_level.json.dist
@@ -0,0 +1,3 @@
+{
+ "foo": "bar"
+}
diff --git a/Tests/fixtures/json/testcases/custom_dist_file/dist.json b/Tests/fixtures/json/testcases/custom_dist_file/dist.json
new file mode 100644
index 0000000..4d3059b
--- /dev/null
+++ b/Tests/fixtures/json/testcases/custom_dist_file/dist.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "bar",
+ "boolean": false
+ }
+}
diff --git a/Tests/fixtures/json/testcases/custom_dist_file/existing.json b/Tests/fixtures/json/testcases/custom_dist_file/existing.json
new file mode 100644
index 0000000..869e880
--- /dev/null
+++ b/Tests/fixtures/json/testcases/custom_dist_file/existing.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "boolean": false
+ }
+}
diff --git a/Tests/fixtures/json/testcases/custom_dist_file/expected.json b/Tests/fixtures/json/testcases/custom_dist_file/expected.json
new file mode 100644
index 0000000..869e880
--- /dev/null
+++ b/Tests/fixtures/json/testcases/custom_dist_file/expected.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "boolean": false
+ }
+}
diff --git a/Tests/fixtures/json/testcases/custom_dist_file/setup.yml b/Tests/fixtures/json/testcases/custom_dist_file/setup.yml
new file mode 100644
index 0000000..d3d7fd9
--- /dev/null
+++ b/Tests/fixtures/json/testcases/custom_dist_file/setup.yml
@@ -0,0 +1,6 @@
+title: Existing values are kept
+
+config:
+ dist-file: parameters.dist.json
+
+dist-file: parameters.dist.json
diff --git a/Tests/fixtures/json/testcases/custom_key/dist.json b/Tests/fixtures/json/testcases/custom_key/dist.json
new file mode 100644
index 0000000..6dd3e6c
--- /dev/null
+++ b/Tests/fixtures/json/testcases/custom_key/dist.json
@@ -0,0 +1,11 @@
+{
+ "config": {
+ "foo": "bar",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/json/testcases/custom_key/existing.json b/Tests/fixtures/json/testcases/custom_key/existing.json
new file mode 100644
index 0000000..52e0335
--- /dev/null
+++ b/Tests/fixtures/json/testcases/custom_key/existing.json
@@ -0,0 +1,11 @@
+{
+ "config": {
+ "foo": "existing_foo",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/json/testcases/custom_key/expected.json b/Tests/fixtures/json/testcases/custom_key/expected.json
new file mode 100644
index 0000000..52e0335
--- /dev/null
+++ b/Tests/fixtures/json/testcases/custom_key/expected.json
@@ -0,0 +1,11 @@
+{
+ "config": {
+ "foo": "existing_foo",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/testcases/custom_key/setup.yml b/Tests/fixtures/json/testcases/custom_key/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/custom_key/setup.yml
rename to Tests/fixtures/json/testcases/custom_key/setup.yml
diff --git a/Tests/fixtures/json/testcases/existent/dist.json b/Tests/fixtures/json/testcases/existent/dist.json
new file mode 100644
index 0000000..beb78e9
--- /dev/null
+++ b/Tests/fixtures/json/testcases/existent/dist.json
@@ -0,0 +1,11 @@
+{
+ "parameters": {
+ "foo": "bar",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/json/testcases/existent/existing.json b/Tests/fixtures/json/testcases/existent/existing.json
new file mode 100644
index 0000000..b4d4064
--- /dev/null
+++ b/Tests/fixtures/json/testcases/existent/existing.json
@@ -0,0 +1,11 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/json/testcases/existent/expected.json b/Tests/fixtures/json/testcases/existent/expected.json
new file mode 100644
index 0000000..b4d4064
--- /dev/null
+++ b/Tests/fixtures/json/testcases/existent/expected.json
@@ -0,0 +1,11 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/testcases/existent/setup.yml b/Tests/fixtures/json/testcases/existent/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent/setup.yml
rename to Tests/fixtures/json/testcases/existent/setup.yml
diff --git a/Tests/fixtures/json/testcases/existent_empty/dist.json b/Tests/fixtures/json/testcases/existent_empty/dist.json
new file mode 100644
index 0000000..e797330
--- /dev/null
+++ b/Tests/fixtures/json/testcases/existent_empty/dist.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "bar"
+ }
+}
diff --git a/Tests/fixtures/testcases/existent_empty/existing.yml b/Tests/fixtures/json/testcases/existent_empty/existing.json
similarity index 100%
rename from Tests/fixtures/testcases/existent_empty/existing.yml
rename to Tests/fixtures/json/testcases/existent_empty/existing.json
diff --git a/Tests/fixtures/json/testcases/existent_empty/expected.json b/Tests/fixtures/json/testcases/existent_empty/expected.json
new file mode 100644
index 0000000..e797330
--- /dev/null
+++ b/Tests/fixtures/json/testcases/existent_empty/expected.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "bar"
+ }
+}
diff --git a/Tests/fixtures/testcases/existent_empty/setup.yml b/Tests/fixtures/json/testcases/existent_empty/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent_empty/setup.yml
rename to Tests/fixtures/json/testcases/existent_empty/setup.yml
diff --git a/Tests/fixtures/json/testcases/existent_without_key/dist.json b/Tests/fixtures/json/testcases/existent_without_key/dist.json
new file mode 100644
index 0000000..e797330
--- /dev/null
+++ b/Tests/fixtures/json/testcases/existent_without_key/dist.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "bar"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/existent_without_key/existing.json b/Tests/fixtures/json/testcases/existent_without_key/existing.json
new file mode 100644
index 0000000..cbd009c
--- /dev/null
+++ b/Tests/fixtures/json/testcases/existent_without_key/existing.json
@@ -0,0 +1,3 @@
+{
+ "foobar": "baz"
+}
diff --git a/Tests/fixtures/json/testcases/existent_without_key/expected.json b/Tests/fixtures/json/testcases/existent_without_key/expected.json
new file mode 100644
index 0000000..daf3967
--- /dev/null
+++ b/Tests/fixtures/json/testcases/existent_without_key/expected.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "bar"
+ },
+ "foobar": "baz"
+}
diff --git a/Tests/fixtures/testcases/existent_without_key/setup.yml b/Tests/fixtures/json/testcases/existent_without_key/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent_without_key/setup.yml
rename to Tests/fixtures/json/testcases/existent_without_key/setup.yml
diff --git a/Tests/fixtures/json/testcases/extra_keys/dist.json b/Tests/fixtures/json/testcases/extra_keys/dist.json
new file mode 100644
index 0000000..11d2fd9
--- /dev/null
+++ b/Tests/fixtures/json/testcases/extra_keys/dist.json
@@ -0,0 +1,7 @@
+{
+ "parameters": {
+ "foo": "bar",
+ "boolean": false
+ },
+ "extra_key": "a new extra key"
+}
diff --git a/Tests/fixtures/json/testcases/extra_keys/existing.json b/Tests/fixtures/json/testcases/extra_keys/existing.json
new file mode 100644
index 0000000..a5e6df1
--- /dev/null
+++ b/Tests/fixtures/json/testcases/extra_keys/existing.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "existing_foo"
+ },
+ "another_key": "foo"
+}
diff --git a/Tests/fixtures/json/testcases/extra_keys/expected.json b/Tests/fixtures/json/testcases/extra_keys/expected.json
new file mode 100644
index 0000000..d6ea26f
--- /dev/null
+++ b/Tests/fixtures/json/testcases/extra_keys/expected.json
@@ -0,0 +1,8 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "boolean": false
+ },
+ "extra_key": "a new extra key",
+ "another_key": "foo"
+}
diff --git a/Tests/fixtures/testcases/extra_keys/setup.yml b/Tests/fixtures/json/testcases/extra_keys/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/extra_keys/setup.yml
rename to Tests/fixtures/json/testcases/extra_keys/setup.yml
diff --git a/Tests/fixtures/json/testcases/interaction_existent/dist.json b/Tests/fixtures/json/testcases/interaction_existent/dist.json
new file mode 100644
index 0000000..839fab3
--- /dev/null
+++ b/Tests/fixtures/json/testcases/interaction_existent/dist.json
@@ -0,0 +1,7 @@
+{
+ "parameters": {
+ "foo": "bar",
+ "boolean": false,
+ "another": null
+ }
+}
diff --git a/Tests/fixtures/json/testcases/interaction_existent/existing.json b/Tests/fixtures/json/testcases/interaction_existent/existing.json
new file mode 100644
index 0000000..57437bc
--- /dev/null
+++ b/Tests/fixtures/json/testcases/interaction_existent/existing.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "existing_foo"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/interaction_existent/expected.json b/Tests/fixtures/json/testcases/interaction_existent/expected.json
new file mode 100644
index 0000000..fd746b9
--- /dev/null
+++ b/Tests/fixtures/json/testcases/interaction_existent/expected.json
@@ -0,0 +1,7 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "boolean": false,
+ "another": "null"
+ }
+}
diff --git a/Tests/fixtures/testcases/interaction_existent/setup.yml b/Tests/fixtures/json/testcases/interaction_existent/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_existent/setup.yml
rename to Tests/fixtures/json/testcases/interaction_existent/setup.yml
diff --git a/Tests/fixtures/json/testcases/interaction_non_existent/dist.json b/Tests/fixtures/json/testcases/interaction_non_existent/dist.json
new file mode 100644
index 0000000..3412193
--- /dev/null
+++ b/Tests/fixtures/json/testcases/interaction_non_existent/dist.json
@@ -0,0 +1,7 @@
+{
+ "parameters": {
+ "boolean": false,
+ "another": "test",
+ "nested": "nested"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/interaction_non_existent/expected.json b/Tests/fixtures/json/testcases/interaction_non_existent/expected.json
new file mode 100644
index 0000000..6c251bb
--- /dev/null
+++ b/Tests/fixtures/json/testcases/interaction_non_existent/expected.json
@@ -0,0 +1,14 @@
+{
+ "parameters": {
+ "boolean": true,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": [
+ "foo",
+ "test",
+ null
+ ]
+ }
+ }
+}
diff --git a/Tests/fixtures/testcases/interaction_non_existent/setup.yml b/Tests/fixtures/json/testcases/interaction_non_existent/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_non_existent/setup.yml
rename to Tests/fixtures/json/testcases/interaction_non_existent/setup.yml
diff --git a/Tests/fixtures/json/testcases/interaction_with_environment/dist.json b/Tests/fixtures/json/testcases/interaction_with_environment/dist.json
new file mode 100644
index 0000000..3412193
--- /dev/null
+++ b/Tests/fixtures/json/testcases/interaction_with_environment/dist.json
@@ -0,0 +1,7 @@
+{
+ "parameters": {
+ "boolean": false,
+ "another": "test",
+ "nested": "nested"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/interaction_with_environment/expected.json b/Tests/fixtures/json/testcases/interaction_with_environment/expected.json
new file mode 100644
index 0000000..904b4ff
--- /dev/null
+++ b/Tests/fixtures/json/testcases/interaction_with_environment/expected.json
@@ -0,0 +1,14 @@
+{
+ "parameters": {
+ "boolean": true,
+ "nested": {
+ "foo": "env_foo",
+ "bar": [
+ "env",
+ "test",
+ null
+ ]
+ },
+ "another": null
+ }
+}
diff --git a/Tests/fixtures/testcases/interaction_with_environment/setup.yml b/Tests/fixtures/json/testcases/interaction_with_environment/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_with_environment/setup.yml
rename to Tests/fixtures/json/testcases/interaction_with_environment/setup.yml
diff --git a/Tests/fixtures/json/testcases/keep_outdated/dist.json b/Tests/fixtures/json/testcases/keep_outdated/dist.json
new file mode 100644
index 0000000..e797330
--- /dev/null
+++ b/Tests/fixtures/json/testcases/keep_outdated/dist.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "bar"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/keep_outdated/existing.json b/Tests/fixtures/json/testcases/keep_outdated/existing.json
new file mode 100644
index 0000000..ee8f822
--- /dev/null
+++ b/Tests/fixtures/json/testcases/keep_outdated/existing.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "outdated": "outdated_param"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/keep_outdated/expected.json b/Tests/fixtures/json/testcases/keep_outdated/expected.json
new file mode 100644
index 0000000..ee8f822
--- /dev/null
+++ b/Tests/fixtures/json/testcases/keep_outdated/expected.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "outdated": "outdated_param"
+ }
+}
diff --git a/Tests/fixtures/testcases/keep_outdated/setup.yml b/Tests/fixtures/json/testcases/keep_outdated/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/keep_outdated/setup.yml
rename to Tests/fixtures/json/testcases/keep_outdated/setup.yml
diff --git a/Tests/fixtures/json/testcases/non_existent/dist.json b/Tests/fixtures/json/testcases/non_existent/dist.json
new file mode 100644
index 0000000..beb78e9
--- /dev/null
+++ b/Tests/fixtures/json/testcases/non_existent/dist.json
@@ -0,0 +1,11 @@
+{
+ "parameters": {
+ "foo": "bar",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/json/testcases/non_existent/expected.json b/Tests/fixtures/json/testcases/non_existent/expected.json
new file mode 100644
index 0000000..beb78e9
--- /dev/null
+++ b/Tests/fixtures/json/testcases/non_existent/expected.json
@@ -0,0 +1,11 @@
+{
+ "parameters": {
+ "foo": "bar",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/testcases/non_existent/setup.yml b/Tests/fixtures/json/testcases/non_existent/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/non_existent/setup.yml
rename to Tests/fixtures/json/testcases/non_existent/setup.yml
diff --git a/Tests/fixtures/json/testcases/non_existent_with_environment/dist.json b/Tests/fixtures/json/testcases/non_existent_with_environment/dist.json
new file mode 100644
index 0000000..beb78e9
--- /dev/null
+++ b/Tests/fixtures/json/testcases/non_existent_with_environment/dist.json
@@ -0,0 +1,11 @@
+{
+ "parameters": {
+ "foo": "bar",
+ "boolean": false,
+ "another": null,
+ "nested": {
+ "foo": "bar",
+ "bar": "baz"
+ }
+ }
+}
diff --git a/Tests/fixtures/json/testcases/non_existent_with_environment/expected.json b/Tests/fixtures/json/testcases/non_existent_with_environment/expected.json
new file mode 100644
index 0000000..bc36e58
--- /dev/null
+++ b/Tests/fixtures/json/testcases/non_existent_with_environment/expected.json
@@ -0,0 +1,15 @@
+{
+ "parameters": {
+ "foo": "foobar",
+ "boolean": true,
+ "another": null,
+ "nested": {
+ "foo": "env_foo",
+ "bar": [
+ "env",
+ "test",
+ null
+ ]
+ }
+ }
+}
diff --git a/Tests/fixtures/testcases/non_existent_with_environment/setup.yml b/Tests/fixtures/json/testcases/non_existent_with_environment/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/non_existent_with_environment/setup.yml
rename to Tests/fixtures/json/testcases/non_existent_with_environment/setup.yml
diff --git a/Tests/fixtures/json/testcases/remove_outdated/dist.json b/Tests/fixtures/json/testcases/remove_outdated/dist.json
new file mode 100644
index 0000000..e797330
--- /dev/null
+++ b/Tests/fixtures/json/testcases/remove_outdated/dist.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "bar"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/remove_outdated/existing.json b/Tests/fixtures/json/testcases/remove_outdated/existing.json
new file mode 100644
index 0000000..ee8f822
--- /dev/null
+++ b/Tests/fixtures/json/testcases/remove_outdated/existing.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "outdated": "outdated_param"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/remove_outdated/expected.json b/Tests/fixtures/json/testcases/remove_outdated/expected.json
new file mode 100644
index 0000000..57437bc
--- /dev/null
+++ b/Tests/fixtures/json/testcases/remove_outdated/expected.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "existing_foo"
+ }
+}
diff --git a/Tests/fixtures/testcases/remove_outdated/setup.yml b/Tests/fixtures/json/testcases/remove_outdated/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/remove_outdated/setup.yml
rename to Tests/fixtures/json/testcases/remove_outdated/setup.yml
diff --git a/Tests/fixtures/json/testcases/renamed/dist.json b/Tests/fixtures/json/testcases/renamed/dist.json
new file mode 100644
index 0000000..2547e1a
--- /dev/null
+++ b/Tests/fixtures/json/testcases/renamed/dist.json
@@ -0,0 +1,9 @@
+{
+ "parameters": {
+ "new": "bar",
+ "new2": "new2",
+ "new3": "test",
+ "new4": "test4",
+ "new5": "test5"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/renamed/existing.json b/Tests/fixtures/json/testcases/renamed/existing.json
new file mode 100644
index 0000000..763a2bc
--- /dev/null
+++ b/Tests/fixtures/json/testcases/renamed/existing.json
@@ -0,0 +1,8 @@
+{
+ "parameters": {
+ "old": "old_value",
+ "new2": "foo",
+ "old2": "bar",
+ "old4": "old4"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/renamed/expected.json b/Tests/fixtures/json/testcases/renamed/expected.json
new file mode 100644
index 0000000..5ec77ae
--- /dev/null
+++ b/Tests/fixtures/json/testcases/renamed/expected.json
@@ -0,0 +1,9 @@
+{
+ "parameters": {
+ "new": "old_value",
+ "new2": "foo",
+ "new3": "test",
+ "new4": "old4",
+ "new5": "old4"
+ }
+}
diff --git a/Tests/fixtures/testcases/renamed/setup.yml b/Tests/fixtures/json/testcases/renamed/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/renamed/setup.yml
rename to Tests/fixtures/json/testcases/renamed/setup.yml
diff --git a/Tests/fixtures/json/testcases/renamed_and_environment/dist.json b/Tests/fixtures/json/testcases/renamed_and_environment/dist.json
new file mode 100644
index 0000000..0ce2ab4
--- /dev/null
+++ b/Tests/fixtures/json/testcases/renamed_and_environment/dist.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "new": "bar",
+ "new2": "new2"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/renamed_and_environment/existing.json b/Tests/fixtures/json/testcases/renamed_and_environment/existing.json
new file mode 100644
index 0000000..cad0abb
--- /dev/null
+++ b/Tests/fixtures/json/testcases/renamed_and_environment/existing.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "old": "old_value",
+ "old2": "old_value2"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/renamed_and_environment/expected.json b/Tests/fixtures/json/testcases/renamed_and_environment/expected.json
new file mode 100644
index 0000000..cb24ebe
--- /dev/null
+++ b/Tests/fixtures/json/testcases/renamed_and_environment/expected.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "new": "new_env_value",
+ "new2": "old_value2"
+ }
+}
diff --git a/Tests/fixtures/testcases/renamed_and_environment/setup.yml b/Tests/fixtures/json/testcases/renamed_and_environment/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/renamed_and_environment/setup.yml
rename to Tests/fixtures/json/testcases/renamed_and_environment/setup.yml
diff --git a/Tests/fixtures/json/testcases/subfolder/dist.json b/Tests/fixtures/json/testcases/subfolder/dist.json
new file mode 100644
index 0000000..4d3059b
--- /dev/null
+++ b/Tests/fixtures/json/testcases/subfolder/dist.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "bar",
+ "boolean": false
+ }
+}
diff --git a/Tests/fixtures/json/testcases/subfolder/existing.json b/Tests/fixtures/json/testcases/subfolder/existing.json
new file mode 100644
index 0000000..869e880
--- /dev/null
+++ b/Tests/fixtures/json/testcases/subfolder/existing.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "boolean": false
+ }
+}
diff --git a/Tests/fixtures/json/testcases/subfolder/expected.json b/Tests/fixtures/json/testcases/subfolder/expected.json
new file mode 100644
index 0000000..869e880
--- /dev/null
+++ b/Tests/fixtures/json/testcases/subfolder/expected.json
@@ -0,0 +1,6 @@
+{
+ "parameters": {
+ "foo": "existing_foo",
+ "boolean": false
+ }
+}
diff --git a/Tests/fixtures/testcases/subfolder/setup.yml b/Tests/fixtures/json/testcases/subfolder/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/subfolder/setup.yml
rename to Tests/fixtures/json/testcases/subfolder/setup.yml
diff --git a/Tests/fixtures/json/testcases/subfolder_created/dist.json b/Tests/fixtures/json/testcases/subfolder_created/dist.json
new file mode 100644
index 0000000..e797330
--- /dev/null
+++ b/Tests/fixtures/json/testcases/subfolder_created/dist.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "bar"
+ }
+}
diff --git a/Tests/fixtures/json/testcases/subfolder_created/expected.json b/Tests/fixtures/json/testcases/subfolder_created/expected.json
new file mode 100644
index 0000000..e797330
--- /dev/null
+++ b/Tests/fixtures/json/testcases/subfolder_created/expected.json
@@ -0,0 +1,5 @@
+{
+ "parameters": {
+ "foo": "bar"
+ }
+}
diff --git a/Tests/fixtures/testcases/subfolder_created/setup.yml b/Tests/fixtures/json/testcases/subfolder_created/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/subfolder_created/setup.yml
rename to Tests/fixtures/json/testcases/subfolder_created/setup.yml
diff --git a/Tests/fixtures/invalid/invalid_existing_values.yml b/Tests/fixtures/yaml/invalid/invalid_existing_values.yml
similarity index 100%
rename from Tests/fixtures/invalid/invalid_existing_values.yml
rename to Tests/fixtures/yaml/invalid/invalid_existing_values.yml
diff --git a/Tests/fixtures/invalid/invalid_existing_values.yml.dist b/Tests/fixtures/yaml/invalid/invalid_existing_values.yml.dist
similarity index 100%
rename from Tests/fixtures/invalid/invalid_existing_values.yml.dist
rename to Tests/fixtures/yaml/invalid/invalid_existing_values.yml.dist
diff --git a/Tests/fixtures/invalid/missing_top_level.yml.dist b/Tests/fixtures/yaml/invalid/missing_top_level.yml.dist
similarity index 100%
rename from Tests/fixtures/invalid/missing_top_level.yml.dist
rename to Tests/fixtures/yaml/invalid/missing_top_level.yml.dist
diff --git a/Tests/fixtures/testcases/custom_dist_file/dist.yml b/Tests/fixtures/yaml/testcases/custom_dist_file/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/custom_dist_file/dist.yml
rename to Tests/fixtures/yaml/testcases/custom_dist_file/dist.yml
diff --git a/Tests/fixtures/testcases/custom_dist_file/existing.yml b/Tests/fixtures/yaml/testcases/custom_dist_file/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/custom_dist_file/existing.yml
rename to Tests/fixtures/yaml/testcases/custom_dist_file/existing.yml
diff --git a/Tests/fixtures/testcases/custom_dist_file/expected.yml b/Tests/fixtures/yaml/testcases/custom_dist_file/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/custom_dist_file/expected.yml
rename to Tests/fixtures/yaml/testcases/custom_dist_file/expected.yml
diff --git a/Tests/fixtures/testcases/custom_dist_file/setup.yml b/Tests/fixtures/yaml/testcases/custom_dist_file/setup.yml
similarity index 100%
rename from Tests/fixtures/testcases/custom_dist_file/setup.yml
rename to Tests/fixtures/yaml/testcases/custom_dist_file/setup.yml
diff --git a/Tests/fixtures/testcases/custom_key/dist.yml b/Tests/fixtures/yaml/testcases/custom_key/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/custom_key/dist.yml
rename to Tests/fixtures/yaml/testcases/custom_key/dist.yml
diff --git a/Tests/fixtures/testcases/custom_key/existing.yml b/Tests/fixtures/yaml/testcases/custom_key/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/custom_key/existing.yml
rename to Tests/fixtures/yaml/testcases/custom_key/existing.yml
diff --git a/Tests/fixtures/testcases/custom_key/expected.yml b/Tests/fixtures/yaml/testcases/custom_key/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/custom_key/expected.yml
rename to Tests/fixtures/yaml/testcases/custom_key/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/custom_key/setup.yml b/Tests/fixtures/yaml/testcases/custom_key/setup.yml
new file mode 100644
index 0000000..6611ac7
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/custom_key/setup.yml
@@ -0,0 +1,5 @@
+title: Using a custom parameter key
+
+config:
+ parameter-key: config
+
diff --git a/Tests/fixtures/testcases/existent/dist.yml b/Tests/fixtures/yaml/testcases/existent/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent/dist.yml
rename to Tests/fixtures/yaml/testcases/existent/dist.yml
diff --git a/Tests/fixtures/testcases/existent/existing.yml b/Tests/fixtures/yaml/testcases/existent/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent/existing.yml
rename to Tests/fixtures/yaml/testcases/existent/existing.yml
diff --git a/Tests/fixtures/testcases/existent/expected.yml b/Tests/fixtures/yaml/testcases/existent/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent/expected.yml
rename to Tests/fixtures/yaml/testcases/existent/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/existent/setup.yml b/Tests/fixtures/yaml/testcases/existent/setup.yml
new file mode 100644
index 0000000..b72f1b5
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/existent/setup.yml
@@ -0,0 +1 @@
+title: Existing values are kept
diff --git a/Tests/fixtures/testcases/existent_empty/dist.yml b/Tests/fixtures/yaml/testcases/existent_empty/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent_empty/dist.yml
rename to Tests/fixtures/yaml/testcases/existent_empty/dist.yml
diff --git a/Tests/fixtures/yaml/testcases/existent_empty/existing.yml b/Tests/fixtures/yaml/testcases/existent_empty/existing.yml
new file mode 100644
index 0000000..e69de29
diff --git a/Tests/fixtures/testcases/existent_empty/expected.yml b/Tests/fixtures/yaml/testcases/existent_empty/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent_empty/expected.yml
rename to Tests/fixtures/yaml/testcases/existent_empty/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/existent_empty/setup.yml b/Tests/fixtures/yaml/testcases/existent_empty/setup.yml
new file mode 100644
index 0000000..dedcd0f
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/existent_empty/setup.yml
@@ -0,0 +1 @@
+title: Existing empty files are valid (Capifony compatibility)
diff --git a/Tests/fixtures/testcases/existent_without_key/dist.yml b/Tests/fixtures/yaml/testcases/existent_without_key/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent_without_key/dist.yml
rename to Tests/fixtures/yaml/testcases/existent_without_key/dist.yml
diff --git a/Tests/fixtures/testcases/existent_without_key/existing.yml b/Tests/fixtures/yaml/testcases/existent_without_key/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent_without_key/existing.yml
rename to Tests/fixtures/yaml/testcases/existent_without_key/existing.yml
diff --git a/Tests/fixtures/testcases/existent_without_key/expected.yml b/Tests/fixtures/yaml/testcases/existent_without_key/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/existent_without_key/expected.yml
rename to Tests/fixtures/yaml/testcases/existent_without_key/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/existent_without_key/setup.yml b/Tests/fixtures/yaml/testcases/existent_without_key/setup.yml
new file mode 100644
index 0000000..3797a0b
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/existent_without_key/setup.yml
@@ -0,0 +1 @@
+title: Existing files without the parameters key are valid
diff --git a/Tests/fixtures/testcases/extra_keys/dist.yml b/Tests/fixtures/yaml/testcases/extra_keys/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/extra_keys/dist.yml
rename to Tests/fixtures/yaml/testcases/extra_keys/dist.yml
diff --git a/Tests/fixtures/testcases/extra_keys/existing.yml b/Tests/fixtures/yaml/testcases/extra_keys/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/extra_keys/existing.yml
rename to Tests/fixtures/yaml/testcases/extra_keys/existing.yml
diff --git a/Tests/fixtures/testcases/extra_keys/expected.yml b/Tests/fixtures/yaml/testcases/extra_keys/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/extra_keys/expected.yml
rename to Tests/fixtures/yaml/testcases/extra_keys/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/extra_keys/setup.yml b/Tests/fixtures/yaml/testcases/extra_keys/setup.yml
new file mode 100644
index 0000000..50666fd
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/extra_keys/setup.yml
@@ -0,0 +1 @@
+title: Extra top level keys are preserved
diff --git a/Tests/fixtures/testcases/interaction_existent/dist.yml b/Tests/fixtures/yaml/testcases/interaction_existent/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_existent/dist.yml
rename to Tests/fixtures/yaml/testcases/interaction_existent/dist.yml
diff --git a/Tests/fixtures/testcases/interaction_existent/existing.yml b/Tests/fixtures/yaml/testcases/interaction_existent/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_existent/existing.yml
rename to Tests/fixtures/yaml/testcases/interaction_existent/existing.yml
diff --git a/Tests/fixtures/testcases/interaction_existent/expected.yml b/Tests/fixtures/yaml/testcases/interaction_existent/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_existent/expected.yml
rename to Tests/fixtures/yaml/testcases/interaction_existent/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/interaction_existent/setup.yml b/Tests/fixtures/yaml/testcases/interaction_existent/setup.yml
new file mode 100644
index 0000000..79664cb
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/interaction_existent/setup.yml
@@ -0,0 +1,11 @@
+title: Existing values are not asked interactively again
+
+interactive: true
+
+requested_params:
+ boolean:
+ default: 'false'
+ input: 'false'
+ another:
+ default: 'null'
+ input: '"null"'
diff --git a/Tests/fixtures/testcases/interaction_non_existent/dist.yml b/Tests/fixtures/yaml/testcases/interaction_non_existent/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_non_existent/dist.yml
rename to Tests/fixtures/yaml/testcases/interaction_non_existent/dist.yml
diff --git a/Tests/fixtures/testcases/interaction_non_existent/expected.yml b/Tests/fixtures/yaml/testcases/interaction_non_existent/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_non_existent/expected.yml
rename to Tests/fixtures/yaml/testcases/interaction_non_existent/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/interaction_non_existent/setup.yml b/Tests/fixtures/yaml/testcases/interaction_non_existent/setup.yml
new file mode 100644
index 0000000..40effce
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/interaction_non_existent/setup.yml
@@ -0,0 +1,14 @@
+title: Missing keys are asked interactively
+
+interactive: true
+
+requested_params:
+ boolean:
+ default: 'false'
+ input: 'true'
+ nested:
+ default: nested
+ input: '{foo: bar, bar: [foo, test, null]}'
+ another:
+ default: test
+ input: 'null'
diff --git a/Tests/fixtures/testcases/interaction_with_environment/dist.yml b/Tests/fixtures/yaml/testcases/interaction_with_environment/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_with_environment/dist.yml
rename to Tests/fixtures/yaml/testcases/interaction_with_environment/dist.yml
diff --git a/Tests/fixtures/testcases/interaction_with_environment/expected.yml b/Tests/fixtures/yaml/testcases/interaction_with_environment/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/interaction_with_environment/expected.yml
rename to Tests/fixtures/yaml/testcases/interaction_with_environment/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/interaction_with_environment/setup.yml b/Tests/fixtures/yaml/testcases/interaction_with_environment/setup.yml
new file mode 100644
index 0000000..80e2585
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/interaction_with_environment/setup.yml
@@ -0,0 +1,17 @@
+title: Values provided by the environment are not asked interactively
+
+config:
+ env-map:
+ boolean: IC_TEST_BOOL
+ nested: IC_TEST_NESTED
+
+environment:
+ IC_TEST_BOOL: 'true'
+ IC_TEST_NESTED: '{foo: env_foo, bar: [env, test, null]}'
+
+interactive: true
+
+requested_params:
+ another:
+ default: test
+ input: 'null'
diff --git a/Tests/fixtures/testcases/keep_outdated/dist.yml b/Tests/fixtures/yaml/testcases/keep_outdated/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/keep_outdated/dist.yml
rename to Tests/fixtures/yaml/testcases/keep_outdated/dist.yml
diff --git a/Tests/fixtures/testcases/keep_outdated/existing.yml b/Tests/fixtures/yaml/testcases/keep_outdated/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/keep_outdated/existing.yml
rename to Tests/fixtures/yaml/testcases/keep_outdated/existing.yml
diff --git a/Tests/fixtures/testcases/keep_outdated/expected.yml b/Tests/fixtures/yaml/testcases/keep_outdated/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/keep_outdated/expected.yml
rename to Tests/fixtures/yaml/testcases/keep_outdated/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/keep_outdated/setup.yml b/Tests/fixtures/yaml/testcases/keep_outdated/setup.yml
new file mode 100644
index 0000000..d3f2eec
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/keep_outdated/setup.yml
@@ -0,0 +1,4 @@
+title: Outdated keys can be kept in the parameters file
+
+config:
+ keep-outdated: true
diff --git a/Tests/fixtures/testcases/non_existent/dist.yml b/Tests/fixtures/yaml/testcases/non_existent/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/non_existent/dist.yml
rename to Tests/fixtures/yaml/testcases/non_existent/dist.yml
diff --git a/Tests/fixtures/testcases/non_existent/expected.yml b/Tests/fixtures/yaml/testcases/non_existent/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/non_existent/expected.yml
rename to Tests/fixtures/yaml/testcases/non_existent/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/non_existent/setup.yml b/Tests/fixtures/yaml/testcases/non_existent/setup.yml
new file mode 100644
index 0000000..9c33d2d
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/non_existent/setup.yml
@@ -0,0 +1 @@
+title: Non existent files are created
diff --git a/Tests/fixtures/testcases/non_existent_with_environment/dist.yml b/Tests/fixtures/yaml/testcases/non_existent_with_environment/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/non_existent_with_environment/dist.yml
rename to Tests/fixtures/yaml/testcases/non_existent_with_environment/dist.yml
diff --git a/Tests/fixtures/testcases/non_existent_with_environment/expected.yml b/Tests/fixtures/yaml/testcases/non_existent_with_environment/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/non_existent_with_environment/expected.yml
rename to Tests/fixtures/yaml/testcases/non_existent_with_environment/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/non_existent_with_environment/setup.yml b/Tests/fixtures/yaml/testcases/non_existent_with_environment/setup.yml
new file mode 100644
index 0000000..684e4de
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/non_existent_with_environment/setup.yml
@@ -0,0 +1,13 @@
+title: Environment variables are used over dist file defaults
+
+config:
+ env-map:
+ boolean: IC_TEST_BOOL
+ foo: IC_TEST_FOO
+ nested: IC_TEST_NESTED
+ another: IC_TEST_NOT_SET
+
+environment:
+ IC_TEST_BOOL: 'true'
+ IC_TEST_FOO: 'foobar'
+ IC_TEST_NESTED: '{foo: env_foo, bar: [env, test, null]}'
diff --git a/Tests/fixtures/testcases/remove_outdated/dist.yml b/Tests/fixtures/yaml/testcases/remove_outdated/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/remove_outdated/dist.yml
rename to Tests/fixtures/yaml/testcases/remove_outdated/dist.yml
diff --git a/Tests/fixtures/testcases/remove_outdated/existing.yml b/Tests/fixtures/yaml/testcases/remove_outdated/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/remove_outdated/existing.yml
rename to Tests/fixtures/yaml/testcases/remove_outdated/existing.yml
diff --git a/Tests/fixtures/testcases/remove_outdated/expected.yml b/Tests/fixtures/yaml/testcases/remove_outdated/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/remove_outdated/expected.yml
rename to Tests/fixtures/yaml/testcases/remove_outdated/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/remove_outdated/setup.yml b/Tests/fixtures/yaml/testcases/remove_outdated/setup.yml
new file mode 100644
index 0000000..183e5cd
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/remove_outdated/setup.yml
@@ -0,0 +1 @@
+title: Outdated keys are removed from the parameters file
diff --git a/Tests/fixtures/testcases/renamed/dist.yml b/Tests/fixtures/yaml/testcases/renamed/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/renamed/dist.yml
rename to Tests/fixtures/yaml/testcases/renamed/dist.yml
diff --git a/Tests/fixtures/testcases/renamed/existing.yml b/Tests/fixtures/yaml/testcases/renamed/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/renamed/existing.yml
rename to Tests/fixtures/yaml/testcases/renamed/existing.yml
diff --git a/Tests/fixtures/testcases/renamed/expected.yml b/Tests/fixtures/yaml/testcases/renamed/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/renamed/expected.yml
rename to Tests/fixtures/yaml/testcases/renamed/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/renamed/setup.yml b/Tests/fixtures/yaml/testcases/renamed/setup.yml
new file mode 100644
index 0000000..153ed8c
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/renamed/setup.yml
@@ -0,0 +1,9 @@
+title: Key can be renamed and the value is reused
+
+config:
+ rename-map:
+ new: old
+ new2: old2
+ new3: old3
+ new4: old4
+ new5: new4 # Cascade renaming
diff --git a/Tests/fixtures/testcases/renamed_and_environment/dist.yml b/Tests/fixtures/yaml/testcases/renamed_and_environment/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/renamed_and_environment/dist.yml
rename to Tests/fixtures/yaml/testcases/renamed_and_environment/dist.yml
diff --git a/Tests/fixtures/testcases/renamed_and_environment/existing.yml b/Tests/fixtures/yaml/testcases/renamed_and_environment/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/renamed_and_environment/existing.yml
rename to Tests/fixtures/yaml/testcases/renamed_and_environment/existing.yml
diff --git a/Tests/fixtures/testcases/renamed_and_environment/expected.yml b/Tests/fixtures/yaml/testcases/renamed_and_environment/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/renamed_and_environment/expected.yml
rename to Tests/fixtures/yaml/testcases/renamed_and_environment/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/renamed_and_environment/setup.yml b/Tests/fixtures/yaml/testcases/renamed_and_environment/setup.yml
new file mode 100644
index 0000000..7c3853f
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/renamed_and_environment/setup.yml
@@ -0,0 +1,11 @@
+title: Environment variables win over renamed keys
+
+config:
+ rename-map:
+ new: old
+ new2: old2
+ env-map:
+ new: IC_TEST_NEW
+
+environment:
+ IC_TEST_NEW: 'new_env_value'
diff --git a/Tests/fixtures/testcases/subfolder/dist.yml b/Tests/fixtures/yaml/testcases/subfolder/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/subfolder/dist.yml
rename to Tests/fixtures/yaml/testcases/subfolder/dist.yml
diff --git a/Tests/fixtures/testcases/subfolder/existing.yml b/Tests/fixtures/yaml/testcases/subfolder/existing.yml
similarity index 100%
rename from Tests/fixtures/testcases/subfolder/existing.yml
rename to Tests/fixtures/yaml/testcases/subfolder/existing.yml
diff --git a/Tests/fixtures/testcases/subfolder/expected.yml b/Tests/fixtures/yaml/testcases/subfolder/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/subfolder/expected.yml
rename to Tests/fixtures/yaml/testcases/subfolder/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/subfolder/setup.yml b/Tests/fixtures/yaml/testcases/subfolder/setup.yml
new file mode 100644
index 0000000..21a4b00
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/subfolder/setup.yml
@@ -0,0 +1,6 @@
+title: Files can be located in subfolders
+
+config:
+ file: 'app/parameters.yml'
+
+dist-file: 'app/parameters.yml.dist'
diff --git a/Tests/fixtures/testcases/subfolder_created/dist.yml b/Tests/fixtures/yaml/testcases/subfolder_created/dist.yml
similarity index 100%
rename from Tests/fixtures/testcases/subfolder_created/dist.yml
rename to Tests/fixtures/yaml/testcases/subfolder_created/dist.yml
diff --git a/Tests/fixtures/testcases/subfolder_created/expected.yml b/Tests/fixtures/yaml/testcases/subfolder_created/expected.yml
similarity index 100%
rename from Tests/fixtures/testcases/subfolder_created/expected.yml
rename to Tests/fixtures/yaml/testcases/subfolder_created/expected.yml
diff --git a/Tests/fixtures/yaml/testcases/subfolder_created/setup.yml b/Tests/fixtures/yaml/testcases/subfolder_created/setup.yml
new file mode 100644
index 0000000..c30049a
--- /dev/null
+++ b/Tests/fixtures/yaml/testcases/subfolder_created/setup.yml
@@ -0,0 +1,7 @@
+title: Files can be located in different folders than the dist and the folder is created
+
+config:
+ file: 'app/parameters.yml'
+ dist-file: 'dist/parameters.yml'
+
+dist-file: 'dist/parameters.yml'
diff --git a/composer.json b/composer.json
index 784ccfd..7b2251c 100644
--- a/composer.json
+++ b/composer.json
@@ -12,12 +12,14 @@
],
"require": {
"php": ">=5.3.3",
- "symfony/yaml": "~2.3|~3.0"
+ "symfony/yaml": "~2.3|~3.0",
+ "seld/jsonlint": "~1.4"
},
"require-dev": {
"composer/composer": "1.0.*@dev",
"phpspec/prophecy-phpunit": "~1.0",
- "symfony/filesystem": "~2.2"
+ "symfony/filesystem": "~2.2",
+ "symfony/var-dumper": "~2.8"
},
"autoload": {
"psr-4": { "Incenteev\\ParameterHandler\\": "" }