Skip to content

Commit c14c3ae

Browse files
JanTvrdikdg
authored andcommitted
improved tests
1 parent 529966c commit c14c3ae

File tree

2 files changed

+212
-28
lines changed

2 files changed

+212
-28
lines changed

tests/Neon/Decoder.array.phpt

+9
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,12 @@ Assert::same(array(
202202
-
203203
a
204204
"));
205+
206+
207+
Assert::same( array(
208+
'one' => NULL,
209+
'two' => NULL,
210+
), Neon::decode('
211+
one:
212+
two:
213+
') );

tests/Neon/Decoder.scalar.phpt

+203-28
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,206 @@ use Nette\Neon\Neon,
1111
require __DIR__ . '/../bootstrap.php';
1212

1313

14-
Assert::null( Neon::decode('') );
15-
Assert::null( Neon::decode(' ') );
16-
Assert::same( 0, Neon::decode('0') );
17-
Assert::same( 0.0, Neon::decode('0.0') );
18-
Assert::same( 1, Neon::decode('1') );
19-
Assert::same( -1.2, Neon::decode('-1.2') );
20-
Assert::same( -120.0, Neon::decode('-1.2e2') );
21-
Assert::true( Neon::decode('true') );
22-
Assert::null( Neon::decode('null') );
23-
Assert::same( 'the"string#literal', Neon::decode('the"string#literal') );
24-
Assert::same( 'the"string', Neon::decode('the"string #literal') );
25-
Assert::same( "the'string #literal", Neon::decode('"the\'string #literal"') );
26-
Assert::same( 'the"string #literal', Neon::decode("'the\"string #literal'") );
27-
Assert::same( 'the"string #literal', Neon::decode('"the\\"string #literal"') );
28-
Assert::same( '@', Neon::decode('"\u0040"') );
29-
Assert::same( "\xC4\x9B", Neon::decode('"\u011B"') );
30-
Assert::same( "\xf0\x90\x90\x81", Neon::decode('"\uD801\uDC01"') ); // U+10401 encoded as surrogate pair
31-
Assert::same( '<literal> <literal>', Neon::decode('<literal> <literal>') );
32-
Assert::same( "", Neon::decode("''") );
33-
Assert::same( "", Neon::decode('""') );
34-
Assert::same( ':a', Neon::decode(':a') );
35-
Assert::same( 'x', Neon::decode('x') );
36-
Assert::same( "x", Neon::decode("\nx\n") );
37-
Assert::same( "x", Neon::decode(" x") );
38-
Assert::same( "@x", Neon::decode("@x") );
39-
Assert::same( "@true", Neon::decode("@true") );
40-
Assert::same( 'a', Neon::decode('a ') );
41-
Assert::same( 'a', Neon::decode("\xEF\xBB\xBFa") );
14+
$dataSet = array(
15+
// https://tools.ietf.org/html/rfc7159
16+
'RFC JSON' => array(
17+
// numbers
18+
array("0", 0),
19+
array("1", 1),
20+
array("0.1", 0.1),
21+
array("1.1", 1.1),
22+
array("1.100000", 1.1),
23+
array("1.111111", 1.111111),
24+
array("-0", -0),
25+
array("-1", -1),
26+
array("-0.1", -0.1),
27+
array("-1.1", -1.1),
28+
array("-1.100000", -1.1),
29+
array("-1.111111", -1.111111),
30+
array("1.1e1", 11.0),
31+
array("1.1e+1", 11.0),
32+
array("1.1e-1", 0.11),
33+
array("1.1E1", 11.0),
34+
array("1.1E+1", 11.0),
35+
array("1.1E-1", 0.11),
36+
37+
// literals
38+
array("null", NULL),
39+
array("true", TRUE),
40+
array("false", FALSE),
41+
42+
// strings
43+
array("''", ''),
44+
array('""', ''),
45+
array('"foo"', "foo"),
46+
array('"f\\no"', "f\no"),
47+
array('"\\b\\f\\n\\r\\t\\"\\/\\\\"', "\x08\f\n\r\t\"/\\"),
48+
array('"\u0040"', "@"),
49+
array('"\u011B"', "\xC4\x9B"),
50+
array('"\uD801\uDC01"', "\xf0\x90\x90\x81"), // U+10401 encoded as surrogate pair
51+
),
52+
53+
// JSON parser implementation in PHP (json_decode); extends RFC JSON
54+
'PHP JSON' => array(
55+
// extended numbers syntax (only on top level)
56+
array('0777', 777),
57+
array('00000777', 777),
58+
array('0xff', 0xff),
59+
array('.1', 0.1),
60+
array('-.1', -0.1),
61+
62+
// extended numbers syntax (everywhere)
63+
array('[1.]', array(1.0)),
64+
array('[1.e1]', array(10.0)),
65+
array('[-1.]', array(-1.0)),
66+
array('[-1.e-1]', array(-0.1)),
67+
68+
// empty input
69+
array('', NULL),
70+
array(' ', NULL),
71+
),
72+
73+
// Nette Object Notation; extends PHP JSON
74+
'NEON' => array(
75+
// extended numbers syntax (everywhere)
76+
array('[0777]', array(777)),
77+
array('[00000777]', array(777)),
78+
array('[0xff]', array(0xff)),
79+
array('[.1]', array(0.1)),
80+
array('[-.1]', array(-0.1)),
81+
82+
// more literals
83+
array('Null', NULL),
84+
array('NULL', NULL),
85+
array('True', TRUE),
86+
array('TRUE', TRUE),
87+
array('yes', TRUE),
88+
array('Yes', TRUE),
89+
array('YES', TRUE),
90+
array('on', TRUE),
91+
array('On', TRUE),
92+
array('ON', TRUE),
93+
array('False', FALSE),
94+
array('FALSE', FALSE),
95+
array('no', FALSE),
96+
array('No', FALSE),
97+
array('NO', FALSE),
98+
array('off', FALSE),
99+
array('Off', FALSE),
100+
array('OFF', FALSE),
101+
102+
// extended string syntax
103+
array('"\\x42 hex escape"', "\x42 hex escape"),
104+
array("'single \\n quote'", "single \\n quote"),
105+
106+
// strings without quotes
107+
array('a', 'a'),
108+
array('abc', 'abc'),
109+
array("\nabc\n", 'abc'),
110+
array(' abc ', 'abc'),
111+
array(':abc', ':abc'),
112+
113+
array('the"string#literal', 'the"string#literal'),
114+
array('the"string #literal', 'the"string'),
115+
array('<literal> <literal>', '<literal> <literal>'),
116+
117+
array('true ""', 'true ""'),
118+
array('false ""', 'false ""'),
119+
array('null ""', 'null ""'),
120+
121+
array('@x', '@x'),
122+
array('@true', '@true'),
123+
124+
array('42 px', '42 px'),
125+
array('42 .2', '42 .2'),
126+
array('42 2', '42 2'),
127+
array('42 e1', '42 e1'),
128+
array('--1', '--1'),
129+
array('-1e', '-1e'),
130+
array('1e+-1', '1e+-1'),
131+
132+
// object keys without quotes
133+
array("{true: 42}", array('true' => 42)),
134+
array("{false: 42}", array('false' => 42)),
135+
array("{null: 42}", array('null' => 42)),
136+
array("{yes: 42}", array('yes' => 42)),
137+
array("{on: 42}", array('on' => 42)),
138+
array("{no: 42}", array('no' => 42)),
139+
array("{off: 42}", array('off' => 42)),
140+
array("{42: 42}", array(42 => 42)),
141+
array("{0: 42}", array(0 => 42)),
142+
array("{-1: 42}", array(-1 => 42)),
143+
144+
// edge
145+
array('"the\'string #literal"', "the'string #literal"),
146+
array("'the\"string #literal'", 'the"string #literal'),
147+
array('"the\\"string #literal"', 'the"string #literal'),
148+
array('a ', 'a'), // backtrack limit
149+
150+
// BOM
151+
array("\xEF\xBB\xBFa", 'a'),
152+
),
153+
154+
// inputs with invalid syntax, but still valid UTF-8
155+
'invalid syntax' => array(
156+
array('"\\a invalid escape"'),
157+
array('"\\v invalid escape"'),
158+
array('"\\u202 invalid escape"'),
159+
array('"\\012 invalid escape"'),
160+
array('"\\\' invalid escape"'),
161+
162+
array('"Unterminated string'),
163+
array('"Unterminated string\\"'),
164+
array('"Unterminated string\\\\\\"'),
165+
166+
array('"42" ""'),
167+
array('"" ""'),
168+
array('[] ""'),
169+
array('[true] ""'),
170+
array('{} ""'),
171+
array('{"x":true} ""'),
172+
array('"Garbage""After string"'),
173+
array('function () { return 0; }'),
174+
array("[1, 2"),
175+
array('{"x": 3'),
176+
array('1e--1]'),
177+
),
178+
179+
// RFC JSON with valid syntax which can not be encoded in UTF-8
180+
'invalid encoding' => array(
181+
array('"XXX\uD801YYY\uDC01ZZZ"', 'XXXYYYZZZ'), // lead and tail surrogates alone
182+
array('"XXX\uD801\uD801YYY"', 'XXXYYY'), // two lead surrogates
183+
array('"XXX\uDC01\uDC01YYY"', 'XXXYYY'), // two tail surrogates
184+
),
185+
186+
// inputs which are not valid UTF-8, but silently ignored
187+
'ignored invalid encoding' => array(
188+
array("'\xc3\x28'"), // Invalid 2 Octet Sequence
189+
array("'\xa0\xa1'"), // Invalid Sequence Identifier
190+
array("'\xe2\x28\xa1'"), // Invalid 3 Octet Sequence (in 2nd Octet)
191+
array("'\xe2\x82\x28'"), // Invalid 3 Octet Sequence (in 3rd Octet)
192+
array("'\xf0\x28\x8c\xbc'"), // Invalid 4 Octet Sequence (in 2nd Octet)
193+
array("'\xf0\x90\x28\xbc'"), // Invalid 4 Octet Sequence (in 3rd Octet)
194+
array("'\xf0\x28\x8c\x28'"), // Invalid 4 Octet Sequence (in 4th Octet)
195+
array("'\xf8\xa1\xa1\xa1\xa1'"), // Valid 5 Octet Sequence (but not Unicode!)
196+
array("'\xfc\xa1\xa1\xa1\xa1\xa1'"), // Valid 6 Octet Sequence (but not Unicode!)
197+
array("'\xed\xa0\x80'"), // invalid code point (U+D800)
198+
array("'\xf0\x82\x82\xac'"), // overlong encoding of U+20AC (euro sign)
199+
),
200+
);
201+
202+
203+
foreach (array_merge($dataSet['RFC JSON'], $dataSet['PHP JSON'], $dataSet['NEON']) as $set) {
204+
echo "$set[0]\n";
205+
Assert::same($set[1], Neon::decode($set[0]));
206+
}
207+
208+
foreach ($dataSet['ignored invalid encoding'] as $set) {
209+
Assert::same(substr($set[0], 1, -1), Neon::decode($set[0]));
210+
}
211+
212+
foreach (array_merge($dataSet['invalid syntax'], $dataSet['invalid encoding']) as $set) {
213+
Assert::exception(function () use ($set) {
214+
Neon::decode($set[0]);
215+
}, 'Nette\Neon\Exception');
216+
}

0 commit comments

Comments
 (0)