tempFile = tempnam(sys_get_temp_dir(), 'icinga-ini-writer-test'); $this->tempFile2 = tempnam(sys_get_temp_dir(), 'icinga-ini-writer-test-2'); } public function tearDown(): void { parent::tearDown(); unlink($this->tempFile); unlink($this->tempFile2); } public function testWhetherPointInSectionIsNotNormalized() { $writer = new IniWriter( Config::fromArray( array( 'section' => array( 'foo.bar' => 1337 ), 'section.with.multiple.dots' => array( 'some more.nested stuff' => 'With more values' ) ) ), $this->tempFile ); $writer->write(); $config = Config::fromIni($this->tempFile)->toArray(); $this->assertTrue(array_key_exists('section.with.multiple.dots', $config), 'Section names not normalized'); } public function testWhetherNestedPropertiesAreInserted() { $target = $this->writeConfigToTemporaryFile(''); $config = Config::fromArray(array('a' => array('b' => 'c'))); $writer = new IniWriter($config, $target); $writer->write(); $newConfig = Config::fromIni($target); $this->assertInstanceOf( 'Icinga\Data\ConfigObject', $newConfig->getSection('a'), 'IniWriter does not insert nested properties' ); $this->assertEquals( 'c', $newConfig->getSection('a')->get('b'), 'IniWriter does not insert nested properties' ); } public function testWhetherSectionOrderIsUpdated() { $config = <<<'EOD' [one] key1 = "1" key2 = "2" [two] a.b = "c" d.e = "f" [three] key = "value" foo.bar = "raboof" EOD; $reverted = <<<'EOD' [three] key = "value" foo.bar = "raboof" [two] a.b = "c" d.e = "f" [one] key1 = "1" key2 = "2" EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter( Config::fromArray( array( 'three' => array( 'foo.bar' => 'raboof', 'key' => 'value' ), 'two' => array( 'd.e' => 'f', 'a.b' => 'c' ), 'one' => array( 'key2' => '2', 'key1' => '1' ) ) ), $target ); $this->assertEquals( trim($reverted), trim($writer->render()), 'IniWriter does not preserve section and/or property order' ); } public function testWhetherCommentOrderIsUpdated() { $config = <<<'EOD' ; comment 1 [one] ; comment 2 [two] EOD; $reverted = <<<'EOD' ; comment 2 [two] ; comment 1 [one] EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter( Config::fromArray( array( 'two' => array(), 'one' => array() ) ), $target ); $this->assertEquals( trim($reverted), trim($writer->render()), 'IniWriter does not preserve section and/or property order' ); } public function testWhetherCommentsOnEmptyLinesArePreserved() { $config = <<<'EOD' ; some interesting comment [blarg] key = "value" ; some dangling comment ; boring comment EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter(Config::fromArray(array('blarg' => array('key' => 'value'))), $target); $this->assertEquals( trim($config), trim($writer->render()), 'IniWriter does not preserve comments on empty lines' ); } public function testWhetherCommentsOnPropertyLinesArePreserved() { $config = <<<'EOD' [blarg] foo = "1337" ; I know what a " and a ' is bar = "7331" ; I; tend; to; overact; !1!1!!11!111! ; key = "value" ; some comment for a small sized property xxl = "very loooooooooooooooooooooong" ; my value is very lo... EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter( Config::fromArray( array('blarg' => array( 'foo' => 1337, 'bar' => 7331, 'key' => 'value', 'xxl' => 'very loooooooooooooooooooooong' )) ), $target ); $this->assertEquals( trim($config), trim($writer->render()), 'IniWriter does not preserve comments on property lines' ); } public function testWhetherCommentsOnEmptySectionLinesArePreserved() { $config = <<<'EOD' [section] ; some interesting comment, in a section key = "value" EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter(Config::fromArray(array('section' => array('key' => 'value'))), $target); $this->assertEquals( trim($config), trim($writer->render()), 'IniWriter does not preserve comments on empty section lines' ); } public function testWhetherCommentsOnSectionPropertyLinesArePreserved() { $config = <<<'EOD' [section] foo = "1337" ; I know what a " and a ' is bar = "7331" ; I; tend; to; overact; !1!1!!11!111! ; key = "value" ; some comment for a small sized property xxl = "very loooooooooooooooooooooong" ; my value is very lo... EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter( Config::fromArray( array( 'section' => array( 'foo' => 1337, 'bar' => 7331, 'key' => 'value', 'xxl' => 'very loooooooooooooooooooooong' ) ) ), $target ); $this->assertEquals( trim($config), trim($writer->render()), 'IniWriter does not preserve comments on property lines' ); } public function testWhetherLinebreaksAreProcessed() { $target = $this->writeConfigToTemporaryFile(''); $writer = new IniWriter( Config::fromArray( array( 'section' => array( 'foo' => 'linebreak in line', 'linebreak inkey' => 'blarg' ) ) ), $target ); $rendered = $writer->render(); $this->assertMatchesRegularExpression( '~linebreak\\\\nin line~', $rendered, 'newlines in values are not escaped' ); $this->assertEquals( 4, count(explode("\n", $rendered)), 'generated config should not contain more than three line breaks' ); } public function testSectionNameEscaping() { $config = <<<'EOD' [section \;comment] foo = "bar" [section \"quotes\"] foo = "bar" [section with \\] foo = "bar" [section with newline] foo = "bar" EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter( Config::fromArray( array( 'section ;comment' => array('foo' => 'bar'), 'section "quotes"' => array('foo' => 'bar'), 'section with \\' => array('foo' => 'bar'), 'section with' . PHP_EOL . 'newline' => array('foo' => 'bar') ) ), $target ); $this->assertEquals( trim($config), trim($writer->render()), 'IniWriter does not handle special chars in section names properly.' ); } public function testWhetherBracketsAreIllegalInSectionNames() { $this->expectException(\Icinga\Exception\ConfigurationError::class); $config = Config::fromArray(['section [brackets]' => []]); (new IniWriter($config, $this->tempFile))->write(); } public function testDirectiveValueEscaping() { $config = <<<'EOD' [section] key1 = "value with \"quotes\"" key2 = "value with \\" EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter( Config::fromArray( array( 'section' => array( 'key1' => 'value with "quotes"', 'key2' => 'value with \\' ) ) ), $target ); $this->assertEquals( trim($config), trim($writer->render()), 'IniWriter does not handle special chars in directives properly.' ); } public function testSectionDeleted() { $config = <<<'EOD' [section 1] guarg = "1" [section 2] foo = "1337" foo2 = "baz" foo3 = "nope" foo4 = "bar" [section 3] guard = "2" EOD; $deleted = <<<'EOD' [section 1] guarg = "1" [section 3] guard = "2" EOD; $target = $this->writeConfigToTemporaryFile($config); $writer = new IniWriter( Config::fromArray(array( 'section 1' => array('guarg' => 1), 'section 3' => array('guard' => 2) )), $target ); $this->assertEquals( trim($deleted), trim($writer->render()), 'IniWriter does not delete sections properly' ); } /** * Write a INI-configuration string to a temporary file and return its path * * @param string $config The config string to write * * @return string The path to the temporary file */ protected function writeConfigToTemporaryFile($config) { file_put_contents($this->tempFile, $config); return $this->tempFile; } public function testWhetherNullValuesGetPersisted() { $config = Config::fromArray(array()); $section = $config->getSection('garbage'); $section->foobar = null; $config->setSection('garbage', $section); $iniWriter = new IniWriter($config, '/dev/null'); $this->assertStringNotContainsString( 'foobar', $iniWriter->render(), 'IniWriter persists section keys with null values' ); } public function testWhetherEmptyValuesGetPersisted() { $config = Config::fromArray(array()); $section = $config->getSection('garbage'); $section->foobar = ''; $config->setSection('garbage', $section); $iniWriter = new IniWriter($config, '/dev/null'); $this->assertStringContainsString( 'foobar', $iniWriter->render(), 'IniWriter doesn\'t persist section keys with empty values' ); } public function testExplicitRemove() { $filename = tempnam(sys_get_temp_dir(), 'iw2'); $config = Config::fromArray(array('garbage' => array('foobar' => 'lolcat'))); $iniWriter = new IniWriter($config, $filename); $iniWriter->write(); $section = $config->getSection('garbage'); $section->foobar = null; $iniWriter = new IniWriter($config, $filename); $this->assertStringNotContainsString( 'foobar', $iniWriter->render(), 'IniWriter doesn\'t remove section keys with null values' ); unlink($filename); } }