JsonParserTest.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /*
  3. * This file is part of the JSON Lint package.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. use Seld\JsonLint\JsonParser;
  11. use Seld\JsonLint\ParsingException;
  12. class JsonParserTest extends PHPUnit_Framework_TestCase
  13. {
  14. protected $json = array(
  15. '42', '42.3', '0.3', '-42', '-42.3', '-0.3',
  16. '2e1', '2E1', '-2e1', '-2E1', '2E+2', '2E-2', '-2E+2', '-2E-2',
  17. 'true', 'false', 'null', '""', '[]', '{}', '"string"',
  18. '["a", "sdfsd"]',
  19. '{"foo":"bar", "bar":"baz", "":"buz"}',
  20. '{"":"foo", "_empty_":"bar"}',
  21. '"\u00c9v\u00e9nement"',
  22. '"http:\/\/foo.com"',
  23. '"zo\\\\mg"',
  24. '{"test":"\u00c9v\u00e9nement"}',
  25. '["\u00c9v\u00e9nement"]',
  26. '"foo/bar"',
  27. '{"test":"http:\/\/foo\\\\zomg"}',
  28. '["http:\/\/foo\\\\zomg"]',
  29. '{"":"foo"}',
  30. '{"a":"b", "b":"c"}',
  31. );
  32. /**
  33. * @dataProvider provideValidStrings
  34. */
  35. public function testParsesValidStrings($input)
  36. {
  37. $parser = new JsonParser();
  38. $this->assertEquals(json_decode($input), $parser->parse($input));
  39. }
  40. public function provideValidStrings()
  41. {
  42. $strings = array();
  43. foreach ($this->json as $input) {
  44. $strings[] = array($input);
  45. }
  46. return $strings;
  47. }
  48. public function testErrorOnTrailingComma()
  49. {
  50. $parser = new JsonParser();
  51. try {
  52. $parser->parse('{
  53. "foo":"bar",
  54. }');
  55. } catch (ParsingException $e) {
  56. $this->assertContains('It appears you have an extra trailing comma', $e->getMessage());
  57. }
  58. }
  59. public function testErrorOnInvalidQuotes()
  60. {
  61. $parser = new JsonParser();
  62. try {
  63. $parser->parse('{
  64. "foo": \'bar\',
  65. }');
  66. } catch (ParsingException $e) {
  67. $this->assertContains('Invalid string, it appears you used single quotes instead of double quotes', $e->getMessage());
  68. }
  69. }
  70. public function testErrorOnUnescapedBackslash()
  71. {
  72. $parser = new JsonParser();
  73. try {
  74. $parser->parse('{
  75. "foo": "bar\z",
  76. }');
  77. } catch (ParsingException $e) {
  78. $this->assertContains('Invalid string, it appears you have an unescaped backslash at: \z', $e->getMessage());
  79. }
  80. }
  81. public function testErrorOnUnterminatedString()
  82. {
  83. $parser = new JsonParser();
  84. try {
  85. $parser->parse('{"bar": "foo}');
  86. } catch (ParsingException $e) {
  87. $this->assertContains('Invalid string, it appears you forgot to terminated the string, or attempted to write a multiline string which is invalid', $e->getMessage());
  88. }
  89. }
  90. public function testErrorOnMultilineString()
  91. {
  92. $parser = new JsonParser();
  93. try {
  94. $parser->parse('{"bar": "foo
  95. bar"}');
  96. } catch (ParsingException $e) {
  97. $this->assertContains('Invalid string, it appears you forgot to terminated the string, or attempted to write a multiline string which is invalid', $e->getMessage());
  98. }
  99. }
  100. public function testParsesMultiInARow()
  101. {
  102. $parser = new JsonParser();
  103. foreach ($this->json as $input) {
  104. $this->assertEquals(json_decode($input), $parser->parse($input));
  105. }
  106. }
  107. public function testDetectsKeyOverrides()
  108. {
  109. $parser = new JsonParser();
  110. try {
  111. $parser->parse('{"a":"b", "a":"c"}', JsonParser::DETECT_KEY_CONFLICTS);
  112. $this->fail('Duplicate keys should not be allowed');
  113. } catch (ParsingException $e) {
  114. $this->assertContains('Duplicate key: a', $e->getMessage());
  115. }
  116. }
  117. public function testDetectsKeyOverridesWithEmpty()
  118. {
  119. $parser = new JsonParser();
  120. try {
  121. $parser->parse('{"":"b", "_empty_":"a"}', JsonParser::DETECT_KEY_CONFLICTS);
  122. $this->fail('Duplicate keys should not be allowed');
  123. } catch (ParsingException $e) {
  124. $this->assertContains('Duplicate key: _empty_', $e->getMessage());
  125. }
  126. }
  127. public function testDuplicateKeys()
  128. {
  129. $parser = new JsonParser();
  130. $result = $parser->parse('{"a":"b", "a":"c", "a":"d"}', JsonParser::ALLOW_DUPLICATE_KEYS);
  131. $this->assertThat($result,
  132. $this->logicalAnd(
  133. $this->arrayHasKey('a'),
  134. $this->arrayHasKey('a.1'),
  135. $this->arrayHasKey('a.2')
  136. )
  137. );
  138. }
  139. public function testDuplicateKeysWithEmpty()
  140. {
  141. $parser = new JsonParser();
  142. $result = $parser->parse('{"":"a", "_empty_":"b"}', JsonParser::ALLOW_DUPLICATE_KEYS);
  143. $this->assertThat($result,
  144. $this->logicalAnd(
  145. $this->arrayHasKey('_empty_'),
  146. $this->arrayHasKey('_empty_.1')
  147. )
  148. );
  149. }
  150. }