First commit

This commit is contained in:
Cody Cook 2024-04-29 19:04:51 -07:00
commit d5bb2f19fa
117 changed files with 68604 additions and 0 deletions

View file

@ -0,0 +1,96 @@
<?php
/*
* This file is part of the Yosymfony\Toml package.
*
* (c) YoSymfony <http://github.com/yosymfony>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Yosymfony\Toml\tests;
use PHPUnit\Framework\TestCase;
use Yosymfony\Toml\KeyStore;
class KeyStoreTest extends TestCase
{
private $keyStore;
public function setUp()
{
$this->keyStore = new KeyStore();
}
public function testIsValidKeyMustReturnTrueWhenTheKeyDoesNotExist()
{
$this->assertTrue($this->keyStore->isValidKey('a'));
}
public function testIsValidKeyMustReturnFalseWhenDuplicateKeys()
{
$this->keyStore->addKey('a');
$this->assertFalse($this->keyStore->isValidKey('a'));
}
public function testIsValidTableKeyMustReturnTrueWhenTheTableKeyDoesNotExist()
{
$this->assertTrue($this->keyStore->isValidTableKey('a'));
}
public function testIsValidTableKeyMustReturnTrueWhenSuperTableIsNotDireclyDefined()
{
$this->keyStore->addTableKey('a.b');
$this->keyStore->addKey('c');
$this->assertTrue($this->keyStore->isValidTableKey('a'));
}
public function testIsValidTableKeyMustReturnFalseWhenDuplicateTableKeys()
{
$this->keyStore->addTableKey('a');
$this->assertFalse($this->keyStore->isValidTableKey('a'));
}
public function testIsValidTableKeyMustReturnFalseWhenThereIsAKeyWithTheSameName()
{
$this->keyStore->addTableKey('a');
$this->keyStore->addKey('b');
$this->assertFalse($this->keyStore->isValidTableKey('a.b'));
}
public function testIsValidArrayTableKeyMustReturnFalseWhenThereIsAPreviousKeyWithTheSameName()
{
$this->keyStore->addKey('a');
$this->assertFalse($this->keyStore->isValidArrayTableKey('a'));
}
public function testIsValidArrayTableKeyMustReturnFalseWhenThereIsAPreviousTableWithTheSameName()
{
$this->keyStore->addTableKey('a');
$this->assertFalse($this->keyStore->isValidArrayTableKey('a'));
}
public function testIsValidTableKeyMustReturnFalseWhenAttemptingToDefineATableKeyEqualToPreviousDefinedArrayTable()
{
$this->keyStore->addArrayTableKey('a');
$this->keyStore->addArrayTableKey('a.b');
$this->assertFalse($this->keyStore->isValidTableKey('a.b'));
}
public function testIsValidTableKeyMustReturnTrueWithTablesInsideArrayOfTables()
{
$this->keyStore->addArrayTableKey('a');
$this->keyStore->addTableKey('a.b');
$this->keyStore->addArrayTableKey('a');
$this->assertTrue($this->keyStore->isValidTableKey('a.b'));
}
}

View file

@ -0,0 +1,299 @@
<?php
/*
* This file is part of the Yosymfony\Toml package.
*
* (c) YoSymfony <http://github.com/yosymfony>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Yosymfony\Toml\tests;
use PHPUnit\Framework\TestCase;
use Yosymfony\Toml\Lexer;
class LexerTest extends TestCase
{
private $lexer;
public function setUp()
{
$this->lexer = new Lexer();
}
public function testTokenizeMustRecognizeEqualToken()
{
$ts = $this->lexer->tokenize('=');
$this->assertTrue($ts->isNext('T_EQUAL'));
}
public function testTokenizeMustRecognizeBooleanTokenWhenThereIsATrueValue()
{
$ts = $this->lexer->tokenize('true');
$this->assertTrue($ts->isNext('T_BOOLEAN'));
}
public function testTokenizeMustRecognizeBooleanTokenWhenThereIsAFalseValue()
{
$ts = $this->lexer->tokenize('false');
$this->assertTrue($ts->isNext('T_BOOLEAN'));
}
public function testTokenizeMustRecognizeUnquotedKeyToken()
{
$ts = $this->lexer->tokenize('title');
$this->assertTrue($ts->isNext('T_UNQUOTED_KEY'));
}
public function testTokenizeMustRecognizeIntegerTokenWhenThereIsAPositiveNumber()
{
$ts = $this->lexer->tokenize('25');
$this->assertTrue($ts->isNext('T_INTEGER'));
}
public function testTokenizeMustRecognizeIntegerTokenWhenThereIsANegativeNumber()
{
$ts = $this->lexer->tokenize('-25');
$this->assertTrue($ts->isNext('T_INTEGER'));
}
public function testTokenizeMustRecognizeIntegerTokenWhenThereIsNumberWithUnderscoreSeparator()
{
$ts = $this->lexer->tokenize('2_5');
$this->assertTrue($ts->isNext('T_INTEGER'));
}
public function testTokenizeMustRecognizeFloatTokenWhenThereIsAFloatNumber()
{
$ts = $this->lexer->tokenize('2.5');
$this->assertTrue($ts->isNext('T_FLOAT'));
}
public function testTokenizeMustRecognizeFloatTokenWhenThereIsAFloatNumberWithUnderscoreSeparator()
{
$ts = $this->lexer->tokenize('9_224_617.445_991_228_313');
$this->assertTrue($ts->isNext('T_FLOAT'));
}
public function testTokenizeMustRecognizeFloatTokenWhenThereIsANegativeFloatNumber()
{
$ts = $this->lexer->tokenize('-2.5');
$this->assertTrue($ts->isNext('T_FLOAT'));
}
public function testTokenizeMustRecognizeFloatTokenWhenThereIsANumberWithExponent()
{
$ts = $this->lexer->tokenize('5e+22');
$this->assertTrue($ts->isNext('T_FLOAT'));
}
public function testTokenizeMustRecognizeFloatTokenWhenThereIsANumberWithExponentAndUnderscoreSeparator()
{
$ts = $this->lexer->tokenize('1e1_000');
$this->assertTrue($ts->isNext('T_FLOAT'));
}
public function testTokenizeMustRecognizeFloatTokenWhenThereIsAFloatNumberWithExponent()
{
$ts = $this->lexer->tokenize('6.626e-34');
$this->assertTrue($ts->isNext('T_FLOAT'));
}
public function testTokenizeMustRecognizeDataTimeTokenWhenThereIsRfc3339Datetime()
{
$ts = $this->lexer->tokenize('1979-05-27T07:32:00Z');
$this->assertTrue($ts->isNext('T_DATE_TIME'));
}
public function testTokenizeMustRecognizeDataTimeTokenWhenThereIsRfc3339DatetimeWithOffset()
{
$ts = $this->lexer->tokenize('1979-05-27T00:32:00-07:00');
$this->assertTrue($ts->isNext('T_DATE_TIME'));
}
public function testTokenizeMustRecognizeDataTimeTokenWhenThereIsRfc3339DatetimeWithOffsetSecondFraction()
{
$ts = $this->lexer->tokenize('1979-05-27T00:32:00.999999-07:00');
$this->assertTrue($ts->isNext('T_DATE_TIME'));
}
public function testTokenizeMustRecognizeQuotationMark()
{
$ts = $this->lexer->tokenize('"');
$this->assertTrue($ts->isNext('T_QUOTATION_MARK'));
}
public function testTokenizeMustRecognize3QuotationMark()
{
$ts = $this->lexer->tokenize('"""');
$this->assertTrue($ts->isNextSequence(['T_3_QUOTATION_MARK', 'T_EOS']));
}
public function testTokenizeMustRecognizeApostrophe()
{
$ts = $this->lexer->tokenize("'");
$this->assertTrue($ts->isNext('T_APOSTROPHE'));
}
public function testTokenizeMustRecognize3Apostrophe()
{
$ts = $this->lexer->tokenize("'''");
$this->assertTrue($ts->isNext('T_3_APOSTROPHE'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsBackspace()
{
$ts = $this->lexer->tokenize('\b');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsTab()
{
$ts = $this->lexer->tokenize('\t');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsLinefeed()
{
$ts = $this->lexer->tokenize('\n');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsFormfeed()
{
$ts = $this->lexer->tokenize('\f');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsCarriageReturn()
{
$ts = $this->lexer->tokenize('\r');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsQuote()
{
$ts = $this->lexer->tokenize('\"');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsBackslash()
{
$ts = $this->lexer->tokenize('\\\\');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsUnicodeUsingFourCharacters()
{
$ts = $this->lexer->tokenize('\u00E9');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeEscapedCharacterWhenThereIsUnicodeUsingEightCharacters()
{
$ts = $this->lexer->tokenize('\U00E90000');
$this->assertTrue($ts->isNext('T_ESCAPED_CHARACTER'));
}
public function testTokenizeMustRecognizeBasicUnescapedString()
{
$ts = $this->lexer->tokenize('@text');
$this->assertTrue($ts->isNextSequence([
'T_BASIC_UNESCAPED',
'T_EOS'
]));
}
public function testTokenizeMustRecognizeHash()
{
$ts = $this->lexer->tokenize('#');
$this->assertTrue($ts->isNext('T_HASH'));
}
public function testTokenizeMustRecognizeEscape()
{
$ts = $this->lexer->tokenize('\\');
$this->assertTrue($ts->isNextSequence(['T_ESCAPE', 'T_EOS']));
}
public function testTokenizeMustRecognizeEscapeAndEscapedCharacter()
{
$ts = $this->lexer->tokenize('\\ \b');
$this->assertTrue($ts->isNextSequence([
'T_ESCAPE',
'T_SPACE',
'T_ESCAPED_CHARACTER',
'T_EOS'
]));
}
public function testTokenizeMustRecognizeLeftSquareBraket()
{
$ts = $this->lexer->tokenize('[');
$this->assertTrue($ts->isNext('T_LEFT_SQUARE_BRAKET'));
}
public function testTokenizeMustRecognizeRightSquareBraket()
{
$ts = $this->lexer->tokenize(']');
$this->assertTrue($ts->isNext('T_RIGHT_SQUARE_BRAKET'));
}
public function testTokenizeMustRecognizeDot()
{
$ts = $this->lexer->tokenize('.');
$this->assertTrue($ts->isNext('T_DOT'));
}
public function testTokenizeMustRecognizeLeftCurlyBrace()
{
$ts = $this->lexer->tokenize('{');
$this->assertTrue($ts->isNext('T_LEFT_CURLY_BRACE'));
}
public function testTokenizeMustRecognizeRightCurlyBrace()
{
$ts = $this->lexer->tokenize('}');
$this->assertTrue($ts->isNext('T_RIGHT_CURLY_BRACE'));
}
}

View file

@ -0,0 +1,575 @@
<?php
/*
* This file is part of the Yosymfony\Toml package.
*
* (c) YoSymfony <http://github.com/yosymfony>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Yosymfony\Toml\tests;
use PHPUnit\Framework\TestCase;
use Yosymfony\Toml\Parser;
use Yosymfony\Toml\Lexer;
class ParserInvalidTest extends TestCase
{
private $parser;
public function setUp()
{
$this->parser = new Parser(new Lexer());
}
public function tearDown()
{
$this->parser = null;
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_EQUAL" at line 1 with value "=".
*/
public function testKeyEmpty()
{
$this->parser->parse('= 1');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_HASH" at line 1 with value "#".
*/
public function testParseMustFailWhenKeyHash()
{
$this->parser->parse('a# = 1');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_NEWLINE" at line 1
*/
public function testParseMustFailWhenKeyNewline()
{
$this->parser->parse("a\n= 1");
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage The key "dupe" has already been defined previously.
*/
public function testDuplicateKeys()
{
$toml = <<<'toml'
dupe = false
dupe = true
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_SPACE" at line 1
*/
public function testParseMustFailWhenKeyOpenBracket()
{
$this->parser->parse('[abc = 1');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_EOS" at line 1
*/
public function testParseMustFailWhenKeySingleOpenBracket()
{
$this->parser->parse('[');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "b".
*/
public function testParseMustFailWhenKeySpace()
{
$this->parser->parse('a b = 1');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_SPACE" at line 2 with value " ".
*/
public function testParseMustFailWhenKeyStartBracket()
{
$this->parser->parse("[a]\n[xyz = 5\n[b]");
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_EQUAL" at line 1 with value "=".
*/
public function testParseMustFailWhenKeyTwoEquals()
{
$this->parser->parse('key= = 1');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "the".
*/
public function testParseMustFailWhenTextAfterInteger()
{
$this->parser->parse('answer = 42 the ultimate answer?');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Invalid integer number: leading zeros are not allowed. Token: "T_INTEGER" line: 1 value "042".
*/
public function testParseMustFailWhenIntegerLeadingZeros()
{
$this->parser->parse('answer = 042');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "_42".
*/
public function testParseMustFailWhenIntegerLeadingUnderscore()
{
$this->parser->parse('answer = _42');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Invalid integer number: underscore must be surrounded by at least one digit.
*/
public function testParseMustFailWhenIntegerFinalUnderscore()
{
$this->parser->parse('answer = 42_');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Invalid integer number: leading zeros are not allowed. Token: "T_INTEGER" line: 1 value "0_42".
*/
public function testParseMustFailWhenIntegerLeadingZerosWithUnderscore()
{
$this->parser->parse('answer = 0_42');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_DOT" at line 1 with value ".".
*/
public function testParseMustFailWhenFloatNoLeadingZero()
{
$toml = <<<'toml'
answer = .12345
neganswer = -.12345
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_DOT" at line 1 with value ".".
*/
public function testParseMustFailWhenFloatNoTrailingDigits()
{
$toml = <<<'toml'
answer = 1.
neganswer = -1.
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "_1".
*/
public function testParseMustFailWhenFloatLeadingUnderscore()
{
$this->parser->parse('number = _1.01');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Invalid float number: underscore must be surrounded by at least one digit.
*/
public function testParseMustFailWhenFloatFinalUnderscore()
{
$this->parser->parse('number = 1.01_');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Invalid float number: underscore must be surrounded by at least one digit.
*/
public function testParseMustFailWhenFloatUnderscorePrefixE()
{
$this->parser->parse('number = 1_e6');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "e_6".
*/
public function testParseMustFailWhenFloatUnderscoreSufixE()
{
$this->parser->parse('number = 1e_6');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_INTEGER" at line 1 with value "-7".
*/
public function testParseMustFailWhenDatetimeMalformedNoLeads()
{
$this->parser->parse('no-leads = 1987-7-05T17:45:00Z');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "T17".
*/
public function testParseMustFailWhenDatetimeMalformedNoSecs()
{
$this->parser->parse('no-secs = 1987-07-05T17:45Z');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_INTEGER" at line 1 with value "17".
*/
public function testParseMustFailWhenDatetimeMalformedNoT()
{
$this->parser->parse('no-t = 1987-07-0517:45:00Z');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_INTEGER" at line 1 with value "-07".
*/
public function testParseMustFailWhenDatetimeMalformedWithMilli()
{
$this->parser->parse('with-milli = 1987-07-5T17:45:00.12Z');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_ESCAPE" at line 1 with value "\". This character is not valid.
*/
public function testParseMustFailWhenBasicStringHasBadByteEscape()
{
$this->parser->parse('naughty = "\xAg"');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_ESCAPE" at line 1 with value "\". This character is not valid.
*/
public function testParseMustFailWhenBasicStringHasBadEscape()
{
$this->parser->parse('invalid-escape = "This string has a bad \a escape character."');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_ESCAPE" at line 1 with value "\". This character is not valid.
*/
public function testParseMustFailWhenBasicStringHasByteEscapes()
{
$this->parser->parse('answer = "\x33"');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_EOS" at line 1 with value "". This character is not valid.
*/
public function testParseMustFailWhenBasicStringIsNotClose()
{
$this->parser->parse('no-ending-quote = "One time, at band camp');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "No". Expected T_NEWLINE or T_EOS.
*/
public function testParseMustFailWhenThereIsTextAfterBasicString()
{
$this->parser->parse('string = "Is there life after strings?" No.');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Data types cannot be mixed in an array. Value: "1".
*/
public function testParseMustFailWhenThereIsAnArrayWithMixedTypesArraysAndInts()
{
$this->parser->parse('arrays-and-ints = [1, ["Arrays are not integers."]]');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Data types cannot be mixed in an array. Value: "1.1".
*/
public function testParseMustFailWhenThereIsAnArrayWithMixedTypesIntsAndFloats()
{
$this->parser->parse('ints-and-floats = [1, 1.1]');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Data types cannot be mixed in an array. Value: "42".
*/
public function testParseMustFailWhenThereIsAnArrayWithMixedTypesStringsAndInts()
{
$this->parser->parse('strings-and-ints = ["hi", 42]');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 2 with value "No".
*/
public function testParseMustFailWhenAppearsTextAfterArrayEntries()
{
$toml = <<<'toml'
array = [
"Is there life after an array separator?", No
"Entry"
]
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 2 with value "No".
*/
public function testParseMustFailWhenAppearsTextBeforeArraySeparator()
{
$toml = <<<'toml'
array = [
"Is there life before an array separator?" No,
"Entry"
]
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 3 with value "I".
*/
public function testParseMustFailWhenAppearsTextInArray()
{
$toml = <<<'toml'
array = [
"Entry 1",
I don't belong,
"Entry 2",
]
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage The key "fruit.type" has already been defined previously.
*/
public function testParseMustFailWhenDuplicateKeyTable()
{
$toml = <<<'toml'
[fruit]
type = "apple"
[fruit.type]
apple = "yes"
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage The key "a" has already been defined previously.
*/
public function testParseMustFailWhenDuplicateTable()
{
$toml = <<<'toml'
[a]
[a]
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_RIGHT_SQUARE_BRAKET" at line 1 with value "]".
*/
public function testParseMustFailWhenTableEmpty()
{
$this->parser->parse('[]');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_SPACE" at line 1 with value " ".
*/
public function testParseMustFailWhenTableWhitespace()
{
$this->parser->parse('[invalid key]');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_DOT" at line 1 with value ".".
*/
public function testParseMustFailWhenEmptyImplicitTable()
{
$this->parser->parse('[naughty..naughty]');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_HASH" at line 1 with value "#".
*/
public function testParseMustFailWhenTableWithPound()
{
$this->parser->parse("[key#group]\nanswer = 42");
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "this".
*/
public function testParseMustFailWhenTextAfterTable()
{
$this->parser->parse('[error] this shouldn\'t be here');
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_LEFT_SQUARE_BRAKET" at line 1 with value "[".
*/
public function testParseMustFailWhenTableNestedBracketsOpen()
{
$toml = <<<'toml'
[a[b]
zyx = 42
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_UNQUOTED_KEY" at line 1 with value "b".
*/
public function testParseMustFailWhenTableNestedBracketsClose()
{
$toml = <<<'toml'
[a]b]
zyx = 42
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_NEWLINE" at line 1
*/
public function testParseMustFailWhenInlineTableWithNewline()
{
$toml = <<<'toml'
name = { first = "Tom",
last = "Preston-Werner"
}
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage The key "fruit.variety" has already been defined previously.
*/
public function testParseMustFailWhenTableArrayWithSomeNameOfTable()
{
$toml = <<<'toml'
[[fruit]]
name = "apple"
[[fruit.variety]]
name = "red delicious"
# This table conflicts with the previous table
[fruit.variety]
name = "granny smith"
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_RIGHT_SQUARE_BRAKET" at line 1 with value "]".
*/
public function testParseMustFailWhenTableArrayMalformedEmpty()
{
$toml = <<<'toml'
[[]]
name = "Born to Run"
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage Syntax error: unexpected token "T_NEWLINE" at line 1
*/
public function testParseMustFailWhenTableArrayMalformedBracket()
{
$toml = <<<'toml'
[[albums]
name = "Born to Run"
toml;
$this->parser->parse($toml);
}
/**
* @expectedException Yosymfony\ParserUtils\SyntaxErrorException
* @expectedExceptionMessage The array of tables "albums" has already been defined as previous table
*/
public function testParseMustFailWhenTableArrayImplicit()
{
$toml = <<<'toml'
# This test is a bit tricky. It should fail because the first use of
# `[[albums.songs]]` without first declaring `albums` implies that `albums`
# must be a table. The alternative would be quite weird. Namely, it wouldn't
# comply with the TOML spec: "Each double-bracketed sub-table will belong to
# the most *recently* defined table element *above* it."
#
# This is in contrast to the *valid* test, table-array-implicit where
# `[[albums.songs]]` works by itself, so long as `[[albums]]` isn't declared
# later. (Although, `[albums]` could be.)
[[albums.songs]]
name = "Glory Days"
[[albums]]
name = "Born in the USA"
toml;
$this->parser->parse($toml);
}
}

View file

@ -0,0 +1,936 @@
<?php
/*
* This file is part of the Yosymfony\Toml package.
*
* (c) YoSymfony <http://github.com/yosymfony>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Yosymfony\Toml\tests;
use PHPUnit\Framework\TestCase;
use Yosymfony\Toml\Parser;
use Yosymfony\Toml\Lexer;
class ParserTest extends TestCase
{
private $parser;
public function setUp()
{
$this->parser = new Parser(new Lexer());
}
public function tearDown()
{
$this->parser = null;
}
public function testParseMustReturnAnEmptyArrayWhenEmptyInput()
{
$array = $this->parser->parse('');
$this->assertEquals([], $array);
}
public function testParseMustParseBooleans()
{
$toml = <<<'toml'
t = true
f = false
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
't' => true,
'f' => false,
], $array);
}
public function testParseMustParseIntegers()
{
$toml = <<<'toml'
answer = 42
neganswer = -42
positive = +90
underscore = 1_2_3_4_5
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'answer' => 42,
'neganswer' => -42,
'positive' => 90,
'underscore' => 12345,
], $array);
}
public function testParseMustParseLongIntegers()
{
$toml = <<<'toml'
answer = 9223372036854775807
neganswer = -9223372036854775808
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'answer' => 9223372036854775807,
'neganswer' => -9223372036854775808,
], $array);
}
public function testParseMustParseFloats()
{
$toml = <<<'toml'
pi = 3.14
negpi = -3.14
positive = +1.01
exponent1 = 5e+22
exponent2 = 1e6
exponent3 = -2E-2
exponent4 = 6.626e-34
underscore = 6.6_26e-3_4
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'pi' => 3.14,
'negpi' => -3.14,
'positive' => 1.01,
'exponent1' => 4.9999999999999996E+22,
'exponent2' => 1000000.0,
'exponent3' => -0.02,
'exponent4' => 6.6259999999999998E-34,
'underscore' => 6.6259999999999998E-34,
], $array);
}
public function testParseMustParseLongFloats()
{
$toml = <<<'toml'
longpi = 3.141592653589793
neglongpi = -3.141592653589793
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'longpi' => 3.141592653589793,
'neglongpi' => -3.141592653589793
], $array);
}
public function testParseMustParseBasicStringsWithASimpleString()
{
$array = $this->parser->parse('answer = "You are not drinking enough whisky."');
$this->assertEquals([
'answer' => 'You are not drinking enough whisky.',
], $array);
}
public function testParseMustParseAnEmptyString()
{
$array = $this->parser->parse('answer = ""');
$this->assertEquals([
'answer' => '',
], $array);
}
public function testParseMustParseStringsWithEscapedCharacters() : void
{
$toml = <<<'toml'
backspace = "This string has a \b backspace character."
tab = "This string has a \t tab character."
newline = "This string has a \n new line character."
formfeed = "This string has a \f form feed character."
carriage = "This string has a \r carriage return character."
quote = "This string has a \" quote character."
backslash = "This string has a \\ backslash character."
notunicode1 = "This string does not have a unicode \\u escape."
notunicode2 = "This string does not have a unicode \\u0075 escape."
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'backspace' => "This string has a \b backspace character.",
'tab' => "This string has a \t tab character.",
'newline' => "This string has a \n new line character.",
'formfeed' => "This string has a \f form feed character.",
'carriage' => "This string has a \r carriage return character.",
'quote' => 'This string has a " quote character.',
'backslash' => 'This string has a \\ backslash character.',
'notunicode1' => 'This string does not have a unicode \\u escape.',
'notunicode2' => 'This string does not have a unicode \\u0075 escape.',
], $array);
}
public function testParseMustParseStringsWithPound()
{
$toml = <<<'toml'
pound = "We see no # comments here."
poundcomment = "But there are # some comments here." # Did I # mess you up?
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'pound' => 'We see no # comments here.',
'poundcomment' => 'But there are # some comments here.'
], $array);
}
public function testParseMustParseWithUnicodeCharacterEscaped()
{
$toml = <<<'toml'
answer4 = "\u03B4"
answer8 = "\U000003B4"
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'answer4' => json_decode('"\u03B4"'),
'answer8' => json_decode('"\u0000\u03B4"'),
], $array);
}
public function testParseMustParseStringWithALiteralUnicodeCharacter()
{
$array = $this->parser->parse('answer = "δ"');
$this->assertEquals([
'answer' => 'δ',
], $array);
}
public function testParseMustParseMultilineStrings()
{
$toml = <<<'toml'
multiline_empty_one = """"""
multiline_empty_two = """
"""
multiline_empty_three = """\
"""
multiline_empty_four = """\
\
\
"""
equivalent_one = "The quick brown fox jumps over the lazy dog."
equivalent_two = """
The quick brown \
fox jumps over \
the lazy dog."""
equivalent_three = """\
The quick brown \
fox jumps over \
the lazy dog.\
"""
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'multiline_empty_one' => '',
'multiline_empty_two' => '',
'multiline_empty_three' => '',
'multiline_empty_four' => '',
'equivalent_one' => 'The quick brown fox jumps over the lazy dog.',
'equivalent_two' => 'The quick brown fox jumps over the lazy dog.',
'equivalent_three' => 'The quick brown fox jumps over the lazy dog.',
], $array);
}
public function testParseMustParseLiteralStrings()
{
$toml = <<<'toml'
backspace = 'This string has a \b backspace character.'
tab = 'This string has a \t tab character.'
newline = 'This string has a \n new line character.'
formfeed = 'This string has a \f form feed character.'
carriage = 'This string has a \r carriage return character.'
slash = 'This string has a \/ slash character.'
backslash = 'This string has a \\ backslash character.'
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'backspace' => 'This string has a \b backspace character.',
'tab' => 'This string has a \t tab character.',
'newline' => 'This string has a \n new line character.',
'formfeed' => 'This string has a \f form feed character.',
'carriage' => 'This string has a \r carriage return character.',
'slash' => 'This string has a \/ slash character.',
'backslash' => 'This string has a \\\\ backslash character.',
], $array);
}
public function testParseMustParseMultilineLiteralStrings()
{
$toml = <<<'toml'
oneline = '''This string has a ' quote character.'''
firstnl = '''
This string has a ' quote character.'''
multiline = '''
This string
has ' a quote character
and more than
one newline
in it.'''
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'oneline' => "This string has a ' quote character.",
'firstnl' => "This string has a ' quote character.",
'multiline' => "This string\nhas ' a quote character\nand more than\none newline\nin it.",
], $array);
}
public function testDatetime()
{
$toml = <<<'toml'
bestdayever = 1987-07-05T17:45:00Z
bestdayever2 = 1979-05-27T00:32:00-07:00
bestdayever3 = 1979-05-27T00:32:00.999999-07:00
bestdayever4 = 1979-05-27T07:32:00
bestdayever5 = 1979-05-27T00:32:00.999999
bestdayever6 = 1979-05-27
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'bestdayever' => new \Datetime('1987-07-05T17:45:00Z'),
'bestdayever2' => new \Datetime('1979-05-27T00:32:00-07:00'),
'bestdayever3' => new \Datetime('1979-05-27T00:32:00.999999-07:00'),
'bestdayever4' => new \Datetime('1979-05-27T07:32:00'),
'bestdayever5' => new \Datetime('1979-05-27T00:32:00.999999'),
'bestdayever6' => new \Datetime('1979-05-27'),
], $array);
}
public function testParseMustParseArraysWithNoSpaces()
{
$array = $this->parser->parse('ints = [1,2,3]');
$this->assertEquals([
'ints' => [1,2,3],
], $array);
}
public function testParseMustParseHeterogeneousArrays()
{
$array = $this->parser->parse('mixed = [[1, 2], ["a", "b"], [1.1, 2.1]]');
$this->assertEquals([
'mixed' => [
[1,2],
['a', 'b'],
[1.1, 2.1],
],
], $array);
}
public function testParseMustParseArraysNested()
{
$array = $this->parser->parse('nest = [["a"], ["b"]]');
$this->assertEquals([
'nest' => [
['a'],
['b']
],
], $array);
}
public function testArrayEmpty()
{
$array = $this->parser->parse('thevoid = [[[[[]]]]]');
$this->assertEquals([
'thevoid' => [
[
[
[
[],
],
],
],
],
], $array);
}
public function testParseMustParseArrays()
{
$toml = <<<'toml'
ints = [1, 2, 3]
floats = [1.1, 2.1, 3.1]
strings = ["a", "b", "c"]
allStrings = ["all", 'strings', """are the same""", '''type''']
MultilineBasicString = ["all", """
Roses are red
Violets are blue""",]
dates = [
1987-07-05T17:45:00Z,
1979-05-27T07:32:00Z,
2006-06-01T11:00:00Z,
]
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'ints' => [1, 2, 3],
'floats' => [1.1, 2.1, 3.1],
'strings' => ['a', 'b', 'c'],
'allStrings' => ['all', 'strings', 'are the same', 'type'],
'MultilineBasicString' => [
'all',
"Roses are red\nViolets are blue",
],
'dates' => [
new \DateTime('1987-07-05T17:45:00Z'),
new \DateTime('1979-05-27T07:32:00Z'),
new \DateTime('2006-06-01T11:00:00Z'),
],
], $array);
}
public function testParseMustParseAKeyWithoutNameSpacesAroundEqualSign()
{
$array = $this->parser->parse('answer=42');
$this->assertEquals([
'answer' => 42,
], $array);
}
public function testParseMustParseKeyWithSpace()
{
$array = $this->parser->parse('"a b" = 1');
$this->assertNotNull($array);
$this->assertEquals([
'a b' => 1,
], $array);
}
public function testParseMustParseKeyWithSpecialCharacters()
{
$array = $this->parser->parse('"~!@$^&*()_+-`1234567890[]|/?><.,;:\'" = 1');
$this->assertEquals([
'~!@$^&*()_+-`1234567890[]|/?><.,;:\'' => 1,
], $array);
}
public function testParseMustParseBareIntegerKeys()
{
$toml = <<<'toml'
[sequence]
-1 = 'detect person'
0 = 'say hello'
1 = 'chat'
10 = 'say bye'
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'sequence' => [
'-1' => 'detect person',
'0' => 'say hello',
'1' => 'chat',
'10' => 'say bye'
]
], $array);
}
public function testParseMustParseAnEmptyTable()
{
$array = $this->parser->parse('[a]');
$this->assertEquals([
'a' => [],
], $array);
}
public function testParseMustParseATableWithAWhiteSpaceInTheName()
{
$array = $this->parser->parse('["valid key"]');
$this->assertEquals([
'valid key' => [],
], $array);
}
public function testParseMustParseATableAQuotedName()
{
$toml = <<<'toml'
[dog."tater.man"]
type = "pug"
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'dog' => [
'tater.man' => [
'type' => 'pug',
],
],
], $array);
}
public function testParseMustParseATableWithAPoundInTheName()
{
$toml = <<<'toml'
["key#group"]
answer = 42
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'key#group' => [
'answer' => 42,
],
], $array);
}
public function testParseMustParseATableAndASubtableEmpties()
{
$toml = <<<'toml'
[a]
[a.b]
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'a' => [
'b' => [],
],
], $array);
}
public function testParseMustParseATableWithImplicitGroups()
{
$toml = <<<'toml'
[a.b.c]
answer = 42
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'a' => [
'b' => [
'c' => [
'answer' => 42,
],
],
],
], $array);
}
public function testParseMustParseAImplicitAndExplicitAfterTable()
{
$toml = <<<'toml'
[a.b.c]
answer = 42
[a]
better = 43
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'a' => [
'better' => 43,
'b' => [
'c' => [
'answer' => 42,
],
],
],
], $array);
}
public function testParseMustParseImplicitAndExplicitTableBefore()
{
$toml = <<<'toml'
[a]
better = 43
[a.b.c]
answer = 42
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'a' => [
'better' => 43,
'b' => [
'c' => [
'answer' => 42,
],
],
],
], $array);
}
public function testParseMustParseInlineTableEmpty()
{
$array = $this->parser->parse('name = {}');
$this->assertEquals([
'name' => [],
], $array);
}
public function testParseMustParseInlineTableOneElement()
{
$array = $this->parser->parse('name = { first = "Tom" }');
$this->assertEquals([
'name' => [
'first' => 'Tom'
],
], $array);
}
public function testParseMustParseAnInlineTableDefinedInATable()
{
$toml = <<<'toml'
[tab1]
key1 = {name='Donald Duck'}
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'tab1' => [
'key1' => [
'name' => 'Donald Duck'
],
],
], $array);
}
public function testParseMustParseInlineTableExamples()
{
$toml = <<<'toml'
name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }
strings = { key1 = """
Roses are red
Violets are blue""", key2 = """
The quick brown \
fox jumps over \
the lazy dog.""" }
inline = { x = 1, y = { a = 2, "b.deep" = 'my value' } }
another = {number = 1}
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'name' => [
'first' => 'Tom',
'last' => 'Preston-Werner',
],
'point' => [
'x' => 1,
'y' => 2,
],
'strings' => [
'key1' => "Roses are red\nViolets are blue",
'key2' => 'The quick brown fox jumps over the lazy dog.',
],
'inline' => [
'x' => 1,
'y' => [
'a' => 2,
'b.deep' => 'my value',
],
],
'another' => [
'number' => 1,
],
], $array);
}
public function testParseMustParseTableArrayImplicit()
{
$toml = <<<'toml'
[[albums.songs]]
name = "Glory Days"
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'albums' => [
'songs' => [
[
'name' => 'Glory Days'
],
],
],
], $array);
}
public function testParseMustParseTableArrayOne()
{
$toml = <<<'toml'
[[people]]
first_name = "Bruce"
last_name = "Springsteen"
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'people' => [
[
'first_name' => 'Bruce',
'last_name' => 'Springsteen',
],
],
], $array);
}
public function testParseMustParseTableArrayMany()
{
$toml = <<<'toml'
[[people]]
first_name = "Bruce"
last_name = "Springsteen"
[[people]]
first_name = "Eric"
last_name = "Clapton"
[[people]]
first_name = "Bob"
last_name = "Seger"
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'people' => [
[
'first_name' => 'Bruce',
'last_name' => 'Springsteen',
],
[
'first_name' => 'Eric',
'last_name' => 'Clapton',
],
[
'first_name' => 'Bob',
'last_name' => 'Seger',
],
],
], $array);
}
public function testParseMustParseTableArrayNest()
{
$toml = <<<'toml'
[[albums]]
name = "Born to Run"
[[albums.songs]]
name = "Jungleland"
[[albums.songs]]
name = "Meeting Across the River"
[[albums]]
name = "Born in the USA"
[[albums.songs]]
name = "Glory Days"
[[albums.songs]]
name = "Dancing in the Dark"
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'albums' => [
[
'name' => 'Born to Run',
'songs' => [
['name' => 'Jungleland'],
['name' => 'Meeting Across the River'],
],
],
[
'name' => 'Born in the USA',
'songs' => [
['name' => 'Glory Days'],
['name' => 'Dancing in the Dark'],
],
],
],
], $array);
}
/**
* @see https://github.com/yosymfony/toml/issues/12
*/
public function testParseMustParseATableAndArrayOfTables()
{
$toml = <<<'toml'
[fruit]
name = "apple"
[[fruit.variety]]
name = "red delicious"
[[fruit.variety]]
name = "granny smith"
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'fruit' => [
'name' => 'apple',
'variety' => [
['name' => 'red delicious'],
['name' => 'granny smith'],
],
],
], $array);
}
/**
* @see https://github.com/yosymfony/toml/issues/23
*/
public function testParseMustParseTablesContainedWithinArrayTables()
{
$toml = <<<'toml'
[[tls]]
entrypoints = ["https"]
[tls.certificate]
certFile = "certs/foo.crt"
keyFile = "keys/foo.key"
[[tls]]
entrypoints = ["https"]
[tls.certificate]
certFile = "certs/bar.crt"
keyFile = "keys/bar.key"
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'tls' => [
[
'entrypoints' => ['https'],
'certificate' => [
'certFile' => 'certs/foo.crt',
'keyFile' => 'keys/foo.key',
],
],
[
'entrypoints' => ['https'],
'certificate' => [
'certFile' => 'certs/bar.crt',
'keyFile' => 'keys/bar.key',
],
],
],
], $array);
}
public function testParseMustParseCommentsEverywhere()
{
$toml = <<<'toml'
# Top comment.
# Top comment.
# Top comment.
# [no-extraneous-groups-please]
[group] # Comment
answer = 42 # Comment
# no-extraneous-keys-please = 999
# Inbetween comment.
more = [ # Comment
# What about multiple # comments?
# Can you handle it?
#
# Evil.
# Evil.
42, 42, # Comments within arrays are fun.
# What about multiple # comments?
# Can you handle it?
#
# Evil.
# Evil.
# ] Did I fool you?
] # Hopefully not.
toml;
$array = $this->parser->parse($toml);
$this->assertNotNull($array);
$this->assertArrayHasKey('answer', $array['group']);
$this->assertArrayHasKey('more', $array['group']);
$this->assertEquals($array['group']['answer'], 42);
$this->assertEquals($array['group']['more'][0], 42);
$this->assertEquals($array['group']['more'][1], 42);
}
public function testParseMustParseASimpleExample()
{
$toml = <<<'toml'
best-day-ever = 1987-07-05T17:45:00Z
emptyName = ""
[numtheory]
boring = false
perfection = [6, 28, 496]
toml;
$array = $this->parser->parse($toml);
$this->assertEquals([
'best-day-ever' => new \DateTime('1987-07-05T17:45:00Z'),
'emptyName' => '',
'numtheory' => [
'boring' => false,
'perfection' => [6, 28, 496],
],
], $array);
}
}

View file

@ -0,0 +1,71 @@
<?php
/*
* This file is part of the Yosymfony Toml.
*
* (c) YoSymfony <http://github.com/yosymfony>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Yosymfony\Toml\tests;
use PHPUnit\Framework\TestCase;
use Yosymfony\Toml\TomlArray;
class TomlArrayTest extends TestCase
{
/** @var TomlArray */
private $tomlArray;
public function setUp()
{
$this->tomlArray = new TomlArray();
}
public function tearDown()
{
$this->tomlArray = null;
}
public function testGetArrayMustReturnTheKeyValueAdded() : void
{
$this->tomlArray->addKeyValue('company', 'acme');
$this->assertEquals([
'company' => 'acme'
], $this->tomlArray->getArray());
}
public function testGetArrayMustReturnTheTableWithTheKeyValue() : void
{
$this->tomlArray->addTableKey('companyData');
$this->tomlArray->addKeyValue('company', 'acme');
$this->assertEquals([
'companyData' => [
'company' => 'acme'
],
], $this->tomlArray->getArray());
}
public function testGetArrayMustReturnAnArrayOfTables() : void
{
$this->tomlArray->addArrayTableKey('companyData');
$this->tomlArray->addKeyValue('company', 'acme1');
$this->tomlArray->addArrayTableKey('companyData');
$this->tomlArray->addKeyValue('company', 'acme2');
$this->assertEquals([
'companyData' => [
[
'company' => 'acme1'
],
[
'company' => 'acme2'
],
]
], $this->tomlArray->getArray());
}
}

View file

@ -0,0 +1,174 @@
<?php
/*
* This file is part of the Yosymfony\Toml package.
*
* (c) YoSymfony <http://github.com/yosymfony>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Yosymfony\Toml\tests;
use PHPUnit\Framework\TestCase;
use Yosymfony\Toml\TomlBuilder;
class TomlBuilderInvalidTest extends TestCase
{
private $builder;
public function setUp() : void
{
$this->builder = new TomlBuilder();
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage A key, table name or array of table name cannot be empty or null.
*/
public function testAddValueMustFailWhenEmptyKey()
{
$this->builder->addValue('', 'value');
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage A key, table name or array of table name cannot be empty or null.
*/
public function testAddTableMustFailWhenEmptyKey()
{
$this->builder->addTable('');
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage A key, table name or array of table name cannot be empty or null.
*/
public function testAddArrayOfTableMustFailWhenEmptyKey()
{
$this->builder->addArrayOfTable('');
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage A key, table name or array of table name cannot be empty or null.
*/
public function testAddValueMustFailWhenKeyWithJustWhiteSpaces()
{
$whiteSpaceKey = ' ';
$this->builder->addValue($whiteSpaceKey, 'value');
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage A key, table name or array of table name cannot be empty or null.
*/
public function testAddTableMustFailWhenKeyWithJustWhiteSpaces()
{
$whiteSpaceKey = ' ';
$this->builder->addTable($whiteSpaceKey);
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage A key, table name or array of table name cannot be empty or null.
*/
public function testAddArrayOfTableMustFailWhenKeyWithJustWhiteSpaces()
{
$whiteSpaceKey = ' ';
$this->builder->addArrayOfTable($whiteSpaceKey);
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage Data types cannot be mixed in an array. Key: "strings-and-ints".
*/
public function testAddValueMustFailWhenMixedTypes()
{
$this->builder->addValue('strings-and-ints', ["uno", 1]);
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage The table key "a" has already been defined previously.
*/
public function testAddTableMustFailWhenDuplicateTables()
{
$this->builder->addTable('a')
->addTable('a');
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage The table key "fruit.type" has already been defined previously.
*/
public function testAddTableMustFailWhenDuplicateKeyTable()
{
$this->builder->addTable('fruit')
->addValue('type', 'apple')
->addTable('fruit.type');
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage The key "dupe" has already been defined previously.
*/
public function testAddValueMustFailWhenDuplicateKeys()
{
$this->builder->addValue('dupe', false)
->addValue('dupe', true);
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage A key, table name or array of table name cannot be empty or null. Table: "naughty..naughty".
*/
public function testEmptyImplicitKeyGroup()
{
$this->builder->addTable('naughty..naughty');
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage Data type not supporter at the key: "theNull".
*/
public function testAddValueMustFailWithNullValue()
{
$this->builder->addValue('theNull', null);
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage Data type not supporter at the key: "theNewClass".
*/
public function testAddValueMustFailWithUnsuportedValueType()
{
$this->builder->addValue('theNewClass', new class {
});
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage The key "albums" has been defined as a implicit table from a previous array of tables.
*/
public function testaddArrayOfTableMustFailWhenThereIsATableArrayImplicit()
{
$this->builder->addArrayOfTable('albums.songs')
->addValue('name', 'Glory Days')
->addArrayOfTable('albums')
->addValue('name', 'Born in the USA');
}
/**
* @expectedException Yosymfony\Toml\Exception\DumpException
* @expectedExceptionMessage Only unquoted keys are allowed in this implementation. Key: "valid key".
*/
public function testAddTableMustFailWithNoUnquotedKeys()
{
$this->builder->addTable('valid key');
}
}

View file

@ -0,0 +1,208 @@
<?php
/*
* This file is part of the Yosymfony\Toml package.
*
* (c) YoSymfony <http://github.com/yosymfony>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Yosymfony\Toml\tests;
use PHPUnit\Framework\TestCase;
use Yosymfony\Toml\TomlBuilder;
use Yosymfony\Toml\Toml;
class TomlBuilderTest extends TestCase
{
public function testExample()
{
$tb = new TomlBuilder();
$result = $tb->addComment('Toml file')
->addTable('data.string')
->addValue('name', 'Toml', 'This is your name')
->addValue('newline', "This string has a \n new line character.")
->addValue('winPath', 'C:\\Users\\nodejs\\templates')
->addValue('unicode', 'unicode character: '.json_decode('"\u03B4"'))
->addTable('data.bool')
->addValue('t', true)
->addValue('f', false)
->addTable('data.integer')
->addValue('positive', 25, 'Comment inline.')
->addValue('negative', -25)
->addTable('data.float')
->addValue('positive', 25.25)
->addValue('negative', -25.25)
->addTable('data.datetime')
->addValue('datetime', new \Datetime())
->addComment('Related to arrays')
->addTable('data.array')
->addValue('simple', array(1, 2, 3))
->addValue('multiple', array(array(1, 2), array('abc', 'def'), array(1.1, 1.2), array(true, false), array(new \Datetime())))
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testArrayEmpty()
{
$tb = new TomlBuilder();
$result = $tb->addComment('Toml file')
->addValue('thevoid', array())
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testImplicitAndExplicitAfter()
{
$tb = new TomlBuilder();
$result = $tb->addTable('a.b.c')
->addValue('answer', 42)
->addTable('a')
->addValue('better', 43)
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testImplicitAndExplicitBefore()
{
$tb = new TomlBuilder();
$result = $tb->addTable('a')
->addValue('better', 43)
->addTable('a.b.c')
->addValue('answer', 42)
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testTableEmpty()
{
$tb = new TomlBuilder();
$result = $tb->addTable('a')
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testTableSubEmpty()
{
$tb = new TomlBuilder();
$result = $tb->addTable('a')
->addTable('a.b')
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testKeyWhitespace()
{
$tb = new TomlBuilder();
$result = $tb->addValue('valid key', 2)
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testStringEscapesDoubleQuote()
{
$tb = new TomlBuilder();
$result = $tb->addValue('backspace', "This string has a \b backspace character.")
->addValue('tab', "This string has a \t tab character.")
->addValue('newline', "This string has a \n new line character.")
->addValue('formfeed', "This string has a \f form feed character.")
->addValue('carriage', "This string has a \r carriage return character.")
->addValue('quote', 'This string has a " quote character.')
->addValue('slash', "This string has a / slash character.")
->addValue('backslash', 'This string has a \\ backslash character.')
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testKeyLiteralString()
{
$tb = new TomlBuilder();
$result = $tb->addValue('regex', "@<\i\c*\s*>")
->getTomlString();
$array = Toml::Parse($result);
$this->assertNotNull($array);
$this->assertEquals('<\i\c*\s*>', $array['regex']);
}
public function testKeyLiteralStringEscapingAt()
{
$tb = new TomlBuilder();
$result = $tb->addValue('regex', "@@<\i\c*\s*>")
->getTomlString();
$array = Toml::Parse($result);
$this->assertNotNull($array);
$this->assertEquals('@<\i\c*\s*>', $array['regex']);
}
public function testKeySpecialChars()
{
$tb = new TomlBuilder();
$result = $tb->addValue('~!@$^&*()_+-`1234567890[]|/?><.,;:\'', 1)
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testStringEscapesSingleQuote()
{
$tb = new TomlBuilder();
$result = $tb->addValue('backspace', 'This string has a \b backspace character.')
->addValue('tab', 'This string has a \t tab character.')
->addValue('newline', 'This string has a \n new line character.')
->addValue('formfeed', 'This string has a \f form feed character.')
->addValue('carriage', 'This string has a \r carriage return character.')
->addValue('quote', 'This string has a \" quote character.')
->addValue('slash', 'This string has a \/ slash character.')
->addValue('backslash', 'This string has a \\ backslash character.')
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
public function testArrayOfTables()
{
$tb = new TomlBuilder();
$result = $tb->addArrayOfTable('fruit')
->addValue('name', 'apple')
->addArrayOfTable('fruit.variety')
->addValue('name', 'red delicious')
->addArrayOfTable('fruit.variety')
->addValue('name', 'granny smith')
->addArrayOfTable('fruit')
->addValue('name', 'banana')
->addArrayOfTable('fruit.variety')
->addValue('name', 'plantain')
->getTomlString();
$this->assertNotNull(Toml::Parse($result));
}
}

View file

@ -0,0 +1,75 @@
<?php
/*
* This file is part of the Yosymfony\Toml package.
*
* (c) YoSymfony <http://github.com/yosymfony>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Yosymfony\Toml\tests;
use PHPUnit\Framework\TestCase;
use Yosymfony\Toml\Toml;
class TomlTest extends TestCase
{
public function testParseMustParseAString()
{
$array = Toml::parse('data = "question"');
$this->assertEquals([
'data' => 'question',
], $array);
}
public function testParseMustReturnEmptyArrayWhenStringEmpty()
{
$array = Toml::parse('');
$this->assertNull($array);
}
public function testParseFileMustParseFile()
{
$filename = __DIR__.'/fixtures/simple.toml';
$array = Toml::parseFile($filename);
$this->assertEquals([
'name' => 'Víctor',
], $array);
}
public function testParseMustReturnAnObjectWhenArgumentResultAsObjectIsTrue()
{
$actual = Toml::parse('name = "Víctor"', true);
$expected = new \stdClass();
$expected->name = 'Víctor';
$this->assertEquals($expected, $actual);
}
public function testParseFileMustReturnAnObjectWhenArgumentResultAsObjectIsTrue()
{
$filename = __DIR__.'/fixtures/simple.toml';
$actual = Toml::parseFile($filename, true);
$expected = new \stdClass();
$expected->name = 'Víctor';
$this->assertEquals($expected, $actual);
}
/**
* @expectedException Yosymfony\Toml\Exception\ParseException
*/
public function testParseFileMustFailWhenFilenameDoesNotExists()
{
$filename = __DIR__.'/fixtures/does-not-exists.toml';
Toml::parseFile($filename);
}
}

View file

@ -0,0 +1 @@
name = "Víctor"