RFC8259 8259

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +61 -0
  3. data/.rspec +4 -0
  4. data/.yardopts +2 -0
  5. data/Gemfile +58 -0
  6. data/LICENSE.txt +40 -0
  7. data/README.txt +1 -0
  8. data/RFC8259 +899 -0
  9. data/RFC8259.gemspec +89 -0
  10. data/Rakefile +86 -0
  11. data/lib/RFC8259.rb +94 -0
  12. data/lib/RFC8259/array.rb +136 -0
  13. data/lib/RFC8259/dumper.rb +255 -0
  14. data/lib/RFC8259/false.rb +79 -0
  15. data/lib/RFC8259/null.rb +79 -0
  16. data/lib/RFC8259/number.rb +149 -0
  17. data/lib/RFC8259/object.rb +137 -0
  18. data/lib/RFC8259/parser.ry +275 -0
  19. data/lib/RFC8259/string.rb +226 -0
  20. data/lib/RFC8259/true.rb +79 -0
  21. data/lib/RFC8259/value.rb +96 -0
  22. data/lib/RFC8259/version.rb +46 -0
  23. data/spec/RFC8259_spec.rb +305 -0
  24. data/spec/acceptance/README.txt +66 -0
  25. data/spec/acceptance/invalid/0001-ws/0001-verical-tab.txt +1 -0
  26. data/spec/acceptance/invalid/0001-ws/0002-null.txt +0 -0
  27. data/spec/acceptance/invalid/0001-ws/0003-space-in-number-1.txt +1 -0
  28. data/spec/acceptance/invalid/0001-ws/0004-space-in-number-2.txt +1 -0
  29. data/spec/acceptance/invalid/0001-ws/0005-space-in-number-3.txt +1 -0
  30. data/spec/acceptance/invalid/0001-ws/0006-space-in-number-4.txt +1 -0
  31. data/spec/acceptance/invalid/0001-ws/0007-space-in-number-5.txt +1 -0
  32. data/spec/acceptance/invalid/0001-ws/0008-space-in-number-6.txt +1 -0
  33. data/spec/acceptance/invalid/0001-ws/0009-space-in-literal.txt +1 -0
  34. data/spec/acceptance/invalid/0001-ws/0010-Unicode-LINE_SEPARATOR.txt +1 -0
  35. data/spec/acceptance/invalid/0002-comments/0001-C-style.txt +1 -0
  36. data/spec/acceptance/invalid/0002-comments/0002-C-plusplus-style.txt +2 -0
  37. data/spec/acceptance/invalid/0002-comments/0003-sh-style.txt +2 -0
  38. data/spec/acceptance/invalid/0002-comments/0004-python-docstring.txt +3 -0
  39. data/spec/acceptance/invalid/0002-comments/0005-SQL-style.txt +2 -0
  40. data/spec/acceptance/invalid/0002-comments/0006-BASIC-style.txt +2 -0
  41. data/spec/acceptance/invalid/0003-literals/0001-FALSE.txt +1 -0
  42. data/spec/acceptance/invalid/0003-literals/0002-NULL.txt +1 -0
  43. data/spec/acceptance/invalid/0003-literals/0003-TRUE.txt +1 -0
  44. data/spec/acceptance/invalid/0003-literals/0004-NUL.txt +1 -0
  45. data/spec/acceptance/invalid/0003-literals/0005-nil.txt +1 -0
  46. data/spec/acceptance/invalid/0003-literals/0006-undef.txt +1 -0
  47. data/spec/acceptance/invalid/0003-literals/0007-modifier.txt +1 -0
  48. data/spec/acceptance/invalid/0003-literals/0008-undefined.txt +1 -0
  49. data/spec/acceptance/invalid/0004-numbers/0001-omit-zero.txt +1 -0
  50. data/spec/acceptance/invalid/0004-numbers/0002-minus-dot.txt +1 -0
  51. data/spec/acceptance/invalid/0004-numbers/0003-missing-frac.txt +1 -0
  52. data/spec/acceptance/invalid/0004-numbers/0004-missing-exp.txt +1 -0
  53. data/spec/acceptance/invalid/0004-numbers/0005-octal.txt +1 -0
  54. data/spec/acceptance/invalid/0004-numbers/0006-hexadecimal.txt +1 -0
  55. data/spec/acceptance/invalid/0004-numbers/0007-comma.txt +1 -0
  56. data/spec/acceptance/invalid/0004-numbers/0008-perl-underscore.txt +1 -0
  57. data/spec/acceptance/invalid/0004-numbers/0009-NaN.txt +1 -0
  58. data/spec/acceptance/invalid/0004-numbers/0010-Inf.txt +1 -0
  59. data/spec/acceptance/invalid/0004-numbers/0011-Infinity.txt +1 -0
  60. data/spec/acceptance/invalid/0005-strings/0000-NUL.txt +0 -0
  61. data/spec/acceptance/invalid/0005-strings/0001-not-terminated.txt +1 -0
  62. data/spec/acceptance/invalid/0005-strings/0002-single-quote.txt +1 -0
  63. data/spec/acceptance/invalid/0005-strings/0003-back-quote.txt +1 -0
  64. data/spec/acceptance/invalid/0005-strings/0004-carriage-return.txt +1 -0
  65. data/spec/acceptance/invalid/0005-strings/0005-line-feed.txt +2 -0
  66. data/spec/acceptance/invalid/0005-strings/0006-unknown-escape-a.txt +1 -0
  67. data/spec/acceptance/invalid/0005-strings/0007-unknown-escape-perl-style.txt +1 -0
  68. data/spec/acceptance/invalid/0005-strings/0008-unknown-escape-C-style.txt +1 -0
  69. data/spec/acceptance/invalid/0005-strings/0009-unknown-escape-ruby-style.txt +1 -0
  70. data/spec/acceptance/invalid/0005-strings/0010-escape-too-short.txt +1 -0
  71. data/spec/acceptance/invalid/0005-strings/0011-C-string-concat.txt +1 -0
  72. data/spec/acceptance/invalid/0005-strings/0012-perl-string-concat.txt +1 -0
  73. data/spec/acceptance/invalid/0005-strings/0013-Java-string-concat.txt +1 -0
  74. data/spec/acceptance/invalid/0006-encodings/0001-CESU-8.txt +1 -0
  75. data/spec/acceptance/invalid/0006-encodings/0002-Windows-31J.txt +1 -0
  76. data/spec/acceptance/invalid/0006-encodings/0003-EBCDIC.txt +1 -0
  77. data/spec/acceptance/invalid/0006-encodings/0004-overlong-utf8.txt +1 -0
  78. data/spec/acceptance/invalid/0007-arrays/0001-lacks-open.txt +1 -0
  79. data/spec/acceptance/invalid/0007-arrays/0002-lacks-close.txt +1 -0
  80. data/spec/acceptance/invalid/0007-arrays/0003-interleaving-parens.txt +1 -0
  81. data/spec/acceptance/invalid/0007-arrays/0004-dangling-comma.txt +1 -0
  82. data/spec/acceptance/invalid/0007-arrays/0005-missing-comma.txt +1 -0
  83. data/spec/acceptance/invalid/0007-arrays/0006-colon-instead-of-comma.txt +1 -0
  84. data/spec/acceptance/invalid/0008-hashes/0001-key-missing.txt +1 -0
  85. data/spec/acceptance/invalid/0008-hashes/0002-value-missing.txt +1 -0
  86. data/spec/acceptance/invalid/0008-hashes/0003-true-key.txt +1 -0
  87. data/spec/acceptance/invalid/0008-hashes/0004-false-key.txt +1 -0
  88. data/spec/acceptance/invalid/0008-hashes/0005-null-key.txt +1 -0
  89. data/spec/acceptance/invalid/0008-hashes/0006-numeric-key.txt +1 -0
  90. data/spec/acceptance/invalid/0008-hashes/0007-array-key.txt +1 -0
  91. data/spec/acceptance/invalid/0008-hashes/0008-hash-key.txt +1 -0
  92. data/spec/acceptance/invalid/0008-hashes/0009-key-not-escaped.txt +4 -0
  93. data/spec/acceptance/invalid/0009-javascriptisms/0001-JSONP.txt +1 -0
  94. data/spec/acceptance/invalid/0009-javascriptisms/0002-new-Array.txt +3 -0
  95. data/spec/acceptance/invalid/0009-javascriptisms/0003-new-Date.txt +1 -0
  96. data/spec/acceptance/invalid/0009-javascriptisms/0004-new-Error.txt +1 -0
  97. data/spec/acceptance/invalid/0009-javascriptisms/0005-Math.txt +1 -0
  98. data/spec/acceptance/invalid/0009-javascriptisms/0006-regular-expression.txt +1 -0
  99. data/spec/acceptance/invalid/0009-javascriptisms/0007-function.txt +7 -0
  100. data/spec/acceptance/invalid/0009-javascriptisms/0008-this.txt +1 -0
  101. data/spec/acceptance/invalid/0009-javascriptisms/0009-plusplus.txt +3 -0
  102. data/spec/acceptance/invalid/0009-javascriptisms/0010-ternary-operator.txt +1 -0
  103. data/spec/acceptance/valid/0001-ws/0001-space.json +1 -0
  104. data/spec/acceptance/valid/0001-ws/0002-tab.json +1 -0
  105. data/spec/acceptance/valid/0001-ws/0003-lf.json +1 -0
  106. data/spec/acceptance/valid/0001-ws/0004-cr.json +1 -0
  107. data/spec/acceptance/valid/0001-ws/0005-before.json +1 -0
  108. data/spec/acceptance/valid/0001-ws/0006-after.json +1 -0
  109. data/spec/acceptance/valid/0001-ws/0007-around-comma.json +3 -0
  110. data/spec/acceptance/valid/0001-ws/0008-around-colon.json +3 -0
  111. data/spec/acceptance/valid/0002-bare-values/0001-false.json +1 -0
  112. data/spec/acceptance/valid/0002-bare-values/0002-null.json +1 -0
  113. data/spec/acceptance/valid/0002-bare-values/0003-true.json +1 -0
  114. data/spec/acceptance/valid/0002-bare-values/0004-number.json +1 -0
  115. data/spec/acceptance/valid/0002-bare-values/0005-string.json +1 -0
  116. data/spec/acceptance/valid/0003-literals/0001-false.json +1 -0
  117. data/spec/acceptance/valid/0003-literals/0002-null.json +1 -0
  118. data/spec/acceptance/valid/0003-literals/0003-true.json +1 -0
  119. data/spec/acceptance/valid/0004-numbers/0000-zero.json +1 -0
  120. data/spec/acceptance/valid/0004-numbers/0001-one.json +1 -0
  121. data/spec/acceptance/valid/0004-numbers/0002-two.json +1 -0
  122. data/spec/acceptance/valid/0004-numbers/0003-three.json +1 -0
  123. data/spec/acceptance/valid/0004-numbers/0004-four.json +1 -0
  124. data/spec/acceptance/valid/0004-numbers/0005-five.json +1 -0
  125. data/spec/acceptance/valid/0004-numbers/0006-six.json +1 -0
  126. data/spec/acceptance/valid/0004-numbers/0007-seven.json +1 -0
  127. data/spec/acceptance/valid/0004-numbers/0008-eight.json +1 -0
  128. data/spec/acceptance/valid/0004-numbers/0009-nine.json +1 -0
  129. data/spec/acceptance/valid/0004-numbers/0010-ten.json +1 -0
  130. data/spec/acceptance/valid/0004-numbers/0011-minus.json +1 -0
  131. data/spec/acceptance/valid/0004-numbers/0012-fraction.json +1 -0
  132. data/spec/acceptance/valid/0004-numbers/0013-exponent.json +1 -0
  133. data/spec/acceptance/valid/0004-numbers/0014-exponent-minus.json +1 -0
  134. data/spec/acceptance/valid/0004-numbers/0015-exponent-plus.json +1 -0
  135. data/spec/acceptance/valid/0004-numbers/0016-complex.json +1 -0
  136. data/spec/acceptance/valid/0004-numbers/0017-DBL_MAX.json +1 -0
  137. data/spec/acceptance/valid/0004-numbers/0018-DBL_MIN.json +1 -0
  138. data/spec/acceptance/valid/0004-numbers/0019-subnormal-number.json +1 -0
  139. data/spec/acceptance/valid/0004-numbers/0020-1E400.json +1 -0
  140. data/spec/acceptance/valid/0004-numbers/0021-pi.json +1 -0
  141. data/spec/acceptance/valid/0004-numbers/0022-UINT32_MAX.json +1 -0
  142. data/spec/acceptance/valid/0004-numbers/0023-UINT64_MAX.json +1 -0
  143. data/spec/acceptance/valid/0004-numbers/0024-INT64_MIN.json +1 -0
  144. data/spec/acceptance/valid/0004-numbers/0025-high-resolution-zero.json +1 -0
  145. data/spec/acceptance/valid/0004-numbers/0026-high-resolution-100.json +1 -0
  146. data/spec/acceptance/valid/0005-strings/0001-empty.json +1 -0
  147. data/spec/acceptance/valid/0005-strings/0002-basic-latin.json +1 -0
  148. data/spec/acceptance/valid/0005-strings/0003-escapes.json +1 -0
  149. data/spec/acceptance/valid/0005-strings/0004-raw-unicode.json +1 -0
  150. data/spec/acceptance/valid/0005-strings/0005-escaped-unicode.json +1 -0
  151. data/spec/acceptance/valid/0005-strings/0006-escaped-NUL.json +1 -0
  152. data/spec/acceptance/valid/0005-strings/0007-escaped-invalid-unicode-still-valid-as-json.json +1 -0
  153. data/spec/acceptance/valid/0005-strings/0008-ruby-json-gem-cant-handle-this.json +1 -0
  154. data/spec/acceptance/valid/0005-strings/0009-unescaped-invalid-javascript-still-valid-as-json.json +1 -0
  155. data/spec/acceptance/valid/0005-strings/0010-escaped-separated-surrogate.json +1 -0
  156. data/spec/acceptance/valid/0005-strings/0011-escaped-surrogate-then-normal.json +1 -0
  157. data/spec/acceptance/valid/0006-m17n/0001-genesis.json +6 -0
  158. data/spec/acceptance/valid/0006-m17n/0002-heart-sutra.json +5 -0
  159. data/spec/acceptance/valid/0006-m17n/0003-escaped-valid-surrogate-pair.json +1 -0
  160. data/spec/acceptance/valid/0006-m17n/0004-unescaped-valid-supplementary-multilingual-plane.json +1 -0
  161. data/spec/acceptance/valid/0007-arrays/0000-empty.json +1 -0
  162. data/spec/acceptance/valid/0007-arrays/0001-one-element.json +1 -0
  163. data/spec/acceptance/valid/0007-arrays/0002-multiple-elements.json +33 -0
  164. data/spec/acceptance/valid/0007-arrays/0003-various-types.json +1 -0
  165. data/spec/acceptance/valid/0007-arrays/0004-nested.json +17 -0
  166. data/spec/acceptance/valid/0008-hashes/0000-empty.json +1 -0
  167. data/spec/acceptance/valid/0008-hashes/0001-onekey.json +1 -0
  168. data/spec/acceptance/valid/0008-hashes/0002-many-keys.json +5 -0
  169. data/spec/acceptance/valid/0008-hashes/0003-empty-key.json +3 -0
  170. data/spec/acceptance/valid/0008-hashes/0004-true-value.json +3 -0
  171. data/spec/acceptance/valid/0008-hashes/0005-false-value.json +3 -0
  172. data/spec/acceptance/valid/0008-hashes/0006-null-value.json +3 -0
  173. data/spec/acceptance/valid/0008-hashes/0007-string-value.json +3 -0
  174. data/spec/acceptance/valid/0008-hashes/0008-numeric-value.json +3 -0
  175. data/spec/acceptance/valid/0008-hashes/0009-array-value.json +8 -0
  176. data/spec/acceptance/valid/0008-hashes/0010-hash-value.json +20 -0
  177. data/spec/acceptance/valid/0008-hashes/0011-duplicate-key.json +4 -0
  178. data/spec/acceptance/valid/0008-hashes/0012-duplicate-key-in-different-representations.json +4 -0
  179. data/spec/acceptance/valid/0009-complicated/0001-jsonschema.json +46 -0
  180. data/spec/acceptance/valid/0009-complicated/0002-example-in-RFC7159-section-13.json +14 -0
  181. data/spec/acceptance/valid/0009-complicated/0003-example-in-RFC7159-section-13.json +22 -0
  182. data/spec/spec_helper.rb +60 -0
  183. metadata +530 -0
@@ -0,0 +1,305 @@
1
+ #! /your/favourite/path/to/rspec
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # - Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ #
12
+ # - Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in
14
+ # the documentation and/or other materials provided with the
15
+ # distribution.
16
+ #
17
+ # - Neither the name of Internet Society, IETF or IETF Trust, nor the
18
+ # names of specific contributors, may be used to endorse or promote
19
+ # products derived from this software without specific prior written
20
+ # permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+
34
+ require_relative 'spec_helper'
35
+ require 'pathname'
36
+
37
+ describe RFC8259 do
38
+ this_dir = Pathname.new __dir__
39
+
40
+ describe '.load' do
41
+ the_dir = this_dir + 'acceptance/valid'
42
+ the_dir.find do |f|
43
+ case f.extname when '.json'
44
+ it "should accept: #{f.basename}" do
45
+ expect do
46
+ f.open encoding: Encoding::UTF_8 do |fp|
47
+ RFC8259.load fp
48
+ end
49
+ end.to_not raise_exception
50
+ end
51
+ end
52
+ end
53
+
54
+ the_dir = this_dir + 'acceptance/invalid'
55
+ the_dir.find do |f|
56
+ case f.extname when '.txt'
57
+ it "should reject: #{f.basename}" do
58
+ expect do
59
+ f.open do |fp|
60
+ RFC8259.load fp
61
+ end
62
+ end.to raise_exception
63
+ end
64
+ end
65
+ end
66
+
67
+ [
68
+ Encoding::UTF_16BE,
69
+ Encoding::UTF_16LE,
70
+ Encoding::UTF_32BE,
71
+ Encoding::UTF_32LE,
72
+ ].each do |enc|
73
+ the_dir = this_dir + 'acceptance'
74
+ the_dir.find do |f|
75
+ case f.extname when '.json', '.txt'
76
+ it "should reject: #{enc}-encoded #{f.basename}" do
77
+ expect do
78
+ f.open "rb", external_encoding: Encoding::UTF_8, internal_encoding: enc do |fp|
79
+ RFC8259.load fp
80
+ end
81
+ end.to raise_exception(Encoding::CompatibilityError)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '.dump' do
89
+ the_dir = this_dir + 'acceptance/valid'
90
+ the_dir.find do |f|
91
+ case f.extname when '.json'
92
+ it "should round-trip: #{f.basename}" do
93
+ str1 = f.read encoding: Encoding::UTF_8
94
+ obj = RFC8259.load str1
95
+ str2 = RFC8259.dump obj
96
+ # not interested in indents
97
+ expect(str2.gsub(/\s+/, '')).to eq(str1.gsub(/\s+/, ''))
98
+ end
99
+ end
100
+ end
101
+
102
+ context 'from something outside JSON world' do
103
+ {
104
+ false => 'false',
105
+ true => 'true',
106
+ nil => 'null',
107
+ 0 => '0',
108
+ 0.5 => '0.5', # 0.5 has no error
109
+ 'foo' => '"foo"',
110
+ "\"\\\/\b\f\n\r\t"=> '"\"\\\/\b\f\n\r\t"',
111
+ "\xED\xBA\xAD".force_encoding('utf-8') => '"\\uDEAD"', # invalid UTF8 to be valid escaped UTF8
112
+ 'foo'.encode('utf-32le') => '"foo"',
113
+ "\xDE\xAD".force_encoding('utf-16be') => '"\\uDEAD"',
114
+ [] => '[ ]',
115
+ [0] => '[ 0 ]',
116
+ [0,1] => '[ 0, 1 ]',
117
+ {} => '{ }',
118
+ {'1'=>1} => '{ "1": 1 }',
119
+ {''=>''} => '{ "": "" }',
120
+ (0.0/0.0) => false,
121
+ (1.0/0.0) => false,
122
+ BigDecimal("NaN") => false,
123
+ // => false,
124
+ 0..1 => false,
125
+ {{}=>{}} => false,
126
+ {[]=>[]} => false,
127
+ {1=>1} => false,
128
+ {nil=>nil} => false,
129
+ Object.new => false,
130
+ Class.new => false,
131
+ Proc.new {} => false,
132
+ }.each_pair do |src, expected|
133
+ if expected
134
+ it { expect(RFC8259.dump src).to eq(expected) }
135
+ else
136
+ it { expect{RFC8259.dump src}.to raise_exception }
137
+ end
138
+ end
139
+
140
+ it 'raises for loops' do
141
+ expect do
142
+ RFC8259.dump [].tap {|i| i << i }
143
+ end.to raise_exception(Errno::ELOOP)
144
+ end
145
+ end
146
+ end
147
+
148
+ context 'versus', skip: true do
149
+ the_dir = this_dir + 'acceptance/valid'
150
+ the_targets = Array.new
151
+ the_dir.find do |f|
152
+ case f.extname when '.json'
153
+ begin
154
+ f.open 'r:utf-8' do |fp|
155
+ RFC8259.load fp, plain:true
156
+ end
157
+ rescue RuntimeError
158
+ # there are cases JSON can't be represented in PORO
159
+ # we ignore them here.
160
+ else
161
+ the_targets.push f
162
+ end
163
+ end
164
+ end
165
+ the_dir = this_dir + 'acceptance/invalid'
166
+ the_invalids = Array.new
167
+ the_dir.find do |f|
168
+ case f.extname when '.txt'
169
+ the_invalids.push f
170
+ end
171
+ end
172
+
173
+ require 'json'
174
+ require 'oj'
175
+ require 'yajl'
176
+ targets = {
177
+ JSON => {
178
+ load: -> str {
179
+ JSON.parse str
180
+ },
181
+ dump: -> obj {
182
+ begin
183
+ ret = JSON.generate obj
184
+ rescue
185
+ raise "JSON (not us) failed: #{$!.inspect}"
186
+ else
187
+ unless ret.valid_encoding?
188
+ raise "JSON (not us) is broken: generated #{ret.dump}"
189
+ end
190
+ return ret
191
+ end
192
+ },
193
+ },
194
+
195
+ Oj => {
196
+ load: -> str {
197
+ Oj.load str
198
+ },
199
+ dump: -> obj {
200
+ begin
201
+ ret = Oj.dump obj
202
+ rescue
203
+ raise "Oj (not us) failed: #{$!.inspect}"
204
+ else
205
+ unless ret.valid_encoding?
206
+ raise "Oj (not us) is broken: generated #{ret.dump}"
207
+ end
208
+ return ret
209
+ end
210
+ },
211
+ },
212
+
213
+ Yajl => {
214
+ load: -> str {
215
+ Yajl::Parser.parse str, allow_comments: false, symbolize_keys: false
216
+ },
217
+ dump: -> obj {
218
+ begin
219
+ ret = Yajl::Encoder.encode obj
220
+ rescue
221
+ raise "Yajl (not us) failed: #{$!.inspect}"
222
+ else
223
+ unless ret.valid_encoding?
224
+ raise "Yajl (not us) is broken: generated #{ret.dump}"
225
+ end
226
+ return ret
227
+ end
228
+ },
229
+ },
230
+ }
231
+
232
+ targets.each_pair do |klass, howto|
233
+ describe klass do
234
+ the_invalids.each do |f|
235
+ it "should reject: #{f.basename}" do
236
+ begin
237
+ theirs = f.open 'r:utf-8' do |fp|
238
+ howto[:load].(fp.read)
239
+ end
240
+ rescue
241
+ # ok
242
+ else
243
+ pending "#{klass} (not us) failed to reject: #{theirs.inspect}"
244
+ end
245
+ end
246
+ end
247
+
248
+ the_targets.each do |f|
249
+ context f.basename do
250
+ before :all do
251
+ str = f.open 'r:utf-8' do |fp| fp.read end
252
+ @ours = RFC8259.load str, plain: true
253
+ begin
254
+ @theirs = howto[:load].(str)
255
+ rescue
256
+ pending "#{klass} (not us) failed to accept: #{$!.inspect}"
257
+ end
258
+ # JSON.load sometimes generates Infinity and that's not JSONable
259
+ case @theirs when Array
260
+ case @theirs[0] when Float
261
+ if @theirs[0].infinite?
262
+ pending "#{klass} (not us) generates non-JSONables: #{@theirs.inspect}"
263
+ end
264
+ end
265
+ end
266
+ end
267
+
268
+ it "compare load" do
269
+ if @ours != @theirs
270
+ pending "They load differently: \n#{@ours.inspect} versus \n#{@theirs.inspect}"
271
+ end
272
+ end
273
+
274
+ it "compare dump ours" do
275
+ ours = RFC8259.dump @ours
276
+ theirs = howto[:dump].(@ours) rescue pending($!.message)
277
+ if ours.gsub(/\s+/, '') != theirs.gsub(/\s+/, '')
278
+ pending "They dump differently: \n#{ours.dump} versus \n#{theirs.dump}"
279
+ end
280
+ end
281
+
282
+ it "compare dump theirs" do
283
+ ours = RFC8259.dump @theirs
284
+ theirs = (howto[:dump].(@theirs) rescue pending($!.message))
285
+ if ours.gsub(/\s+/, '') != theirs.gsub(/\s+/, '')
286
+ pending "They dump differently: \n#{ours.dump} versus \n#{theirs.dump}"
287
+ end
288
+ end
289
+ end
290
+ end
291
+ end
292
+ end
293
+ end
294
+ end
295
+
296
+ #
297
+ # Local Variables:
298
+ # mode: ruby
299
+ # coding: utf-8-unix
300
+ # indent-tabs-mode: t
301
+ # tab-width: 3
302
+ # ruby-indent-level: 3
303
+ # fill-column: 79
304
+ # default-justification: full
305
+ # End:
@@ -0,0 +1,66 @@
1
+ This directory contains various JSON and quasi-JSON texts. The files
2
+ under "valid" directory are believed to be valid JSON texts, while
3
+ those under "invalid" are believed to be invalid. And the author of
4
+ this library believe that there is no instance of text that exhibits
5
+ Russell's paradox -like behaviour, where one cannot say if that text
6
+ (if any) is valid or invalid.
7
+
8
+ All files under this directory, including this file itself, are
9
+ written by me, Urabe Shyouhei <shyouhei@ruby-lang.org>. You can
10
+ safely copy & paste them to your project to test your own JSON parser.
11
+
12
+ I repeat the license of this project below, just in case you separate
13
+ this test suite form the library.
14
+
15
+ ----------------------------------------------------------------------
16
+
17
+ Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
18
+
19
+ Redistribution and use in source and binary forms, with or without
20
+ modification, are permitted provided that the following conditions are
21
+ met:
22
+
23
+ - Redistributions of source code must retain the above copyright
24
+ notice, this list of conditions and the following disclaimer.
25
+
26
+ - Redistributions in binary form must reproduce the above copyright
27
+ notice, this list of conditions and the following disclaimer in
28
+ the documentation and/or other materials provided with the
29
+ distribution.
30
+
31
+ - Neither the name of Internet Society, IETF or IETF Trust, nor the
32
+ names of specific contributors, may be used to endorse or promote
33
+ products derived from this software without specific prior written
34
+ permission.
35
+
36
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37
+ “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
39
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
40
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
+
48
+ ----------------------------------------------------------------------
49
+
50
+ P.S. For those who copy & paste the test cases to your own parser:
51
+
52
+ - In convenience for your own parser, most (not all) files starts
53
+ with '[' and ends with ']'. This is because that should also pass
54
+ older JSON spec (RFC4627).
55
+
56
+ - RFC7159 requests us, with using the strongest word (“MUST”) that
57
+ all the valid examples are to be accepted. On the other hand the
58
+ RFC _allows_ you to extend the grammar to, say, accept JavaScript
59
+ comments and so on. So failure in parsing valid examples are
60
+ fatal, but accepting invalid examples might not.
61
+
62
+ - RFC7159 tells no so much about semantics. For instance it does
63
+ not define object equality. It does not even define the character
64
+ set of parsed JSON strings (it DOES define the encoding of
65
+ generated JSON text themselves though).
66
+
@@ -0,0 +1 @@
1
+ ["Here you are U+0208 ->",
"<- (might be invisible in github) and is invalid"]
@@ -0,0 +1 @@
1
+ [/* comments are invalid in JSON */]
@@ -0,0 +1,2 @@
1
+ [// comments are invalid in JSON
2
+ ]
@@ -0,0 +1,2 @@
1
+ [# comments are invalid in JSON
2
+ ]
@@ -0,0 +1,3 @@
1
+ ["""
2
+ comments are invalid in JSON
3
+ """]
@@ -0,0 +1,2 @@
1
+ [-- comments are invalid in JSON
2
+ ]
@@ -0,0 +1,2 @@
1
+ [' comments are invalid in JSON
2
+ ]