crazy_ivan 0.2.0

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 (133) hide show
  1. data/.gitignore +7 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +94 -0
  4. data/Rakefile +92 -0
  5. data/TODO +33 -0
  6. data/VERSION +1 -0
  7. data/bin/crazy_ivan +114 -0
  8. data/crazy_ivan.gemspec +182 -0
  9. data/lib/crazy_ivan.rb +5 -0
  10. data/lib/html_asset_crush.rb +56 -0
  11. data/lib/report_assembler.rb +78 -0
  12. data/lib/test_runner.rb +71 -0
  13. data/templates/css/ci.css +11 -0
  14. data/templates/index.html +105 -0
  15. data/templates/javascript/json-template.js +544 -0
  16. data/templates/javascript/prototype.js +4917 -0
  17. data/test/crazy_ivan_test.rb +4 -0
  18. data/test/test_helper.rb +9 -0
  19. data/vendor/json-1.1.7/CHANGES +119 -0
  20. data/vendor/json-1.1.7/GPL +340 -0
  21. data/vendor/json-1.1.7/README +78 -0
  22. data/vendor/json-1.1.7/RUBY +58 -0
  23. data/vendor/json-1.1.7/Rakefile +270 -0
  24. data/vendor/json-1.1.7/TODO +1 -0
  25. data/vendor/json-1.1.7/VERSION +1 -0
  26. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +52 -0
  27. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +1000 -0
  28. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +1001 -0
  29. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +900 -0
  30. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +901 -0
  31. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +1000 -0
  32. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +1001 -0
  33. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +261 -0
  34. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +1000 -0
  35. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +1001 -0
  36. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +1000 -0
  37. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +1001 -0
  38. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +1000 -0
  39. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +1001 -0
  40. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +262 -0
  41. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +1000 -0
  42. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +1001 -0
  43. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +82 -0
  44. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +34 -0
  45. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +900 -0
  46. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +901 -0
  47. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +81 -0
  48. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +1000 -0
  49. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +1001 -0
  50. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +82 -0
  51. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +1000 -0
  52. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +1001 -0
  53. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +82 -0
  54. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +1000 -0
  55. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +1001 -0
  56. data/vendor/json-1.1.7/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +82 -0
  57. data/vendor/json-1.1.7/benchmarks/generator_benchmark.rb +165 -0
  58. data/vendor/json-1.1.7/benchmarks/parser_benchmark.rb +197 -0
  59. data/vendor/json-1.1.7/bin/edit_json.rb +9 -0
  60. data/vendor/json-1.1.7/bin/prettify_json.rb +75 -0
  61. data/vendor/json-1.1.7/data/example.json +1 -0
  62. data/vendor/json-1.1.7/data/index.html +38 -0
  63. data/vendor/json-1.1.7/data/prototype.js +4184 -0
  64. data/vendor/json-1.1.7/doc-templates/main.txt +283 -0
  65. data/vendor/json-1.1.7/ext/json/ext/generator/extconf.rb +11 -0
  66. data/vendor/json-1.1.7/ext/json/ext/generator/generator.c +919 -0
  67. data/vendor/json-1.1.7/ext/json/ext/generator/unicode.c +182 -0
  68. data/vendor/json-1.1.7/ext/json/ext/generator/unicode.h +53 -0
  69. data/vendor/json-1.1.7/ext/json/ext/parser/extconf.rb +11 -0
  70. data/vendor/json-1.1.7/ext/json/ext/parser/parser.c +1829 -0
  71. data/vendor/json-1.1.7/ext/json/ext/parser/parser.rl +686 -0
  72. data/vendor/json-1.1.7/ext/json/ext/parser/unicode.c +154 -0
  73. data/vendor/json-1.1.7/ext/json/ext/parser/unicode.h +58 -0
  74. data/vendor/json-1.1.7/install.rb +26 -0
  75. data/vendor/json-1.1.7/lib/json.rb +10 -0
  76. data/vendor/json-1.1.7/lib/json/Array.xpm +21 -0
  77. data/vendor/json-1.1.7/lib/json/FalseClass.xpm +21 -0
  78. data/vendor/json-1.1.7/lib/json/Hash.xpm +21 -0
  79. data/vendor/json-1.1.7/lib/json/Key.xpm +73 -0
  80. data/vendor/json-1.1.7/lib/json/NilClass.xpm +21 -0
  81. data/vendor/json-1.1.7/lib/json/Numeric.xpm +28 -0
  82. data/vendor/json-1.1.7/lib/json/String.xpm +96 -0
  83. data/vendor/json-1.1.7/lib/json/TrueClass.xpm +21 -0
  84. data/vendor/json-1.1.7/lib/json/add/core.rb +135 -0
  85. data/vendor/json-1.1.7/lib/json/add/rails.rb +58 -0
  86. data/vendor/json-1.1.7/lib/json/common.rb +354 -0
  87. data/vendor/json-1.1.7/lib/json/editor.rb +1371 -0
  88. data/vendor/json-1.1.7/lib/json/ext.rb +15 -0
  89. data/vendor/json-1.1.7/lib/json/json.xpm +1499 -0
  90. data/vendor/json-1.1.7/lib/json/pure.rb +77 -0
  91. data/vendor/json-1.1.7/lib/json/pure/generator.rb +430 -0
  92. data/vendor/json-1.1.7/lib/json/pure/parser.rb +269 -0
  93. data/vendor/json-1.1.7/lib/json/version.rb +8 -0
  94. data/vendor/json-1.1.7/tests/fixtures/fail1.json +1 -0
  95. data/vendor/json-1.1.7/tests/fixtures/fail10.json +1 -0
  96. data/vendor/json-1.1.7/tests/fixtures/fail11.json +1 -0
  97. data/vendor/json-1.1.7/tests/fixtures/fail12.json +1 -0
  98. data/vendor/json-1.1.7/tests/fixtures/fail13.json +1 -0
  99. data/vendor/json-1.1.7/tests/fixtures/fail14.json +1 -0
  100. data/vendor/json-1.1.7/tests/fixtures/fail18.json +1 -0
  101. data/vendor/json-1.1.7/tests/fixtures/fail19.json +1 -0
  102. data/vendor/json-1.1.7/tests/fixtures/fail2.json +1 -0
  103. data/vendor/json-1.1.7/tests/fixtures/fail20.json +1 -0
  104. data/vendor/json-1.1.7/tests/fixtures/fail21.json +1 -0
  105. data/vendor/json-1.1.7/tests/fixtures/fail22.json +1 -0
  106. data/vendor/json-1.1.7/tests/fixtures/fail23.json +1 -0
  107. data/vendor/json-1.1.7/tests/fixtures/fail24.json +1 -0
  108. data/vendor/json-1.1.7/tests/fixtures/fail25.json +1 -0
  109. data/vendor/json-1.1.7/tests/fixtures/fail27.json +2 -0
  110. data/vendor/json-1.1.7/tests/fixtures/fail28.json +2 -0
  111. data/vendor/json-1.1.7/tests/fixtures/fail3.json +1 -0
  112. data/vendor/json-1.1.7/tests/fixtures/fail4.json +1 -0
  113. data/vendor/json-1.1.7/tests/fixtures/fail5.json +1 -0
  114. data/vendor/json-1.1.7/tests/fixtures/fail6.json +1 -0
  115. data/vendor/json-1.1.7/tests/fixtures/fail7.json +1 -0
  116. data/vendor/json-1.1.7/tests/fixtures/fail8.json +1 -0
  117. data/vendor/json-1.1.7/tests/fixtures/fail9.json +1 -0
  118. data/vendor/json-1.1.7/tests/fixtures/pass1.json +56 -0
  119. data/vendor/json-1.1.7/tests/fixtures/pass15.json +1 -0
  120. data/vendor/json-1.1.7/tests/fixtures/pass16.json +1 -0
  121. data/vendor/json-1.1.7/tests/fixtures/pass17.json +1 -0
  122. data/vendor/json-1.1.7/tests/fixtures/pass2.json +1 -0
  123. data/vendor/json-1.1.7/tests/fixtures/pass26.json +1 -0
  124. data/vendor/json-1.1.7/tests/fixtures/pass3.json +6 -0
  125. data/vendor/json-1.1.7/tests/test_json.rb +312 -0
  126. data/vendor/json-1.1.7/tests/test_json_addition.rb +164 -0
  127. data/vendor/json-1.1.7/tests/test_json_fixtures.rb +34 -0
  128. data/vendor/json-1.1.7/tests/test_json_generate.rb +106 -0
  129. data/vendor/json-1.1.7/tests/test_json_rails.rb +146 -0
  130. data/vendor/json-1.1.7/tests/test_json_unicode.rb +62 -0
  131. data/vendor/json-1.1.7/tools/fuzz.rb +139 -0
  132. data/vendor/json-1.1.7/tools/server.rb +61 -0
  133. metadata +196 -0
@@ -0,0 +1,269 @@
1
+ require 'strscan'
2
+
3
+ module JSON
4
+ module Pure
5
+ # This class implements the JSON parser that is used to parse a JSON string
6
+ # into a Ruby data structure.
7
+ class Parser < StringScanner
8
+ STRING = /" ((?:[^\x0-\x1f"\\] |
9
+ # escaped special characters:
10
+ \\["\\\/bfnrt] |
11
+ \\u[0-9a-fA-F]{4} |
12
+ # match all but escaped special characters:
13
+ \\[\x20-\x21\x23-\x2e\x30-\x5b\x5d-\x61\x63-\x65\x67-\x6d\x6f-\x71\x73\x75-\xff])*)
14
+ "/nx
15
+ INTEGER = /(-?0|-?[1-9]\d*)/
16
+ FLOAT = /(-?
17
+ (?:0|[1-9]\d*)
18
+ (?:
19
+ \.\d+(?i:e[+-]?\d+) |
20
+ \.\d+ |
21
+ (?i:e[+-]?\d+)
22
+ )
23
+ )/x
24
+ NAN = /NaN/
25
+ INFINITY = /Infinity/
26
+ MINUS_INFINITY = /-Infinity/
27
+ OBJECT_OPEN = /\{/
28
+ OBJECT_CLOSE = /\}/
29
+ ARRAY_OPEN = /\[/
30
+ ARRAY_CLOSE = /\]/
31
+ PAIR_DELIMITER = /:/
32
+ COLLECTION_DELIMITER = /,/
33
+ TRUE = /true/
34
+ FALSE = /false/
35
+ NULL = /null/
36
+ IGNORE = %r(
37
+ (?:
38
+ //[^\n\r]*[\n\r]| # line comments
39
+ /\* # c-style comments
40
+ (?:
41
+ [^*/]| # normal chars
42
+ /[^*]| # slashes that do not start a nested comment
43
+ \*[^/]| # asterisks that do not end this comment
44
+ /(?=\*/) # single slash before this comment's end
45
+ )*
46
+ \*/ # the End of this comment
47
+ |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
48
+ )+
49
+ )mx
50
+
51
+ UNPARSED = Object.new
52
+
53
+ # Creates a new JSON::Pure::Parser instance for the string _source_.
54
+ #
55
+ # It will be configured by the _opts_ hash. _opts_ can have the following
56
+ # keys:
57
+ # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
58
+ # structures. Disable depth checking with :max_nesting => false|nil|0,
59
+ # it defaults to 19.
60
+ # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
61
+ # defiance of RFC 4627 to be parsed by the Parser. This option defaults
62
+ # to false.
63
+ # * *create_additions*: If set to false, the Parser doesn't create
64
+ # additions even if a matchin class and create_id was found. This option
65
+ # defaults to true.
66
+ # * *object_class*: Defaults to Hash
67
+ # * *array_class*: Defaults to Array
68
+ def initialize(source, opts = {})
69
+ super
70
+ if !opts.key?(:max_nesting) # defaults to 19
71
+ @max_nesting = 19
72
+ elsif opts[:max_nesting]
73
+ @max_nesting = opts[:max_nesting]
74
+ else
75
+ @max_nesting = 0
76
+ end
77
+ @allow_nan = !!opts[:allow_nan]
78
+ ca = true
79
+ ca = opts[:create_additions] if opts.key?(:create_additions)
80
+ @create_id = ca ? JSON.create_id : nil
81
+ @object_class = opts[:object_class] || Hash
82
+ @array_class = opts[:array_class] || Array
83
+ end
84
+
85
+ alias source string
86
+
87
+ # Parses the current JSON string _source_ and returns the complete data
88
+ # structure as a result.
89
+ def parse
90
+ reset
91
+ obj = nil
92
+ until eos?
93
+ case
94
+ when scan(OBJECT_OPEN)
95
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
96
+ @current_nesting = 1
97
+ obj = parse_object
98
+ when scan(ARRAY_OPEN)
99
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
100
+ @current_nesting = 1
101
+ obj = parse_array
102
+ when skip(IGNORE)
103
+ ;
104
+ else
105
+ raise ParserError, "source '#{peek(20)}' not in JSON!"
106
+ end
107
+ end
108
+ obj or raise ParserError, "source did not contain any JSON!"
109
+ obj
110
+ end
111
+
112
+ private
113
+
114
+ # Unescape characters in strings.
115
+ UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
116
+ UNESCAPE_MAP.update({
117
+ ?" => '"',
118
+ ?\\ => '\\',
119
+ ?/ => '/',
120
+ ?b => "\b",
121
+ ?f => "\f",
122
+ ?n => "\n",
123
+ ?r => "\r",
124
+ ?t => "\t",
125
+ ?u => nil,
126
+ })
127
+
128
+ def parse_string
129
+ if scan(STRING)
130
+ return '' if self[1].empty?
131
+ string = self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
132
+ if u = UNESCAPE_MAP[$&[1]]
133
+ u
134
+ else # \uXXXX
135
+ bytes = ''
136
+ i = 0
137
+ while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
138
+ bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
139
+ i += 1
140
+ end
141
+ JSON::UTF16toUTF8.iconv(bytes)
142
+ end
143
+ end
144
+ if string.respond_to?(:force_encoding)
145
+ string.force_encoding(Encoding::UTF_8)
146
+ end
147
+ string
148
+ else
149
+ UNPARSED
150
+ end
151
+ rescue Iconv::Failure => e
152
+ raise GeneratorError, "Caught #{e.class}: #{e}"
153
+ end
154
+
155
+ def parse_value
156
+ case
157
+ when scan(FLOAT)
158
+ Float(self[1])
159
+ when scan(INTEGER)
160
+ Integer(self[1])
161
+ when scan(TRUE)
162
+ true
163
+ when scan(FALSE)
164
+ false
165
+ when scan(NULL)
166
+ nil
167
+ when (string = parse_string) != UNPARSED
168
+ string
169
+ when scan(ARRAY_OPEN)
170
+ @current_nesting += 1
171
+ ary = parse_array
172
+ @current_nesting -= 1
173
+ ary
174
+ when scan(OBJECT_OPEN)
175
+ @current_nesting += 1
176
+ obj = parse_object
177
+ @current_nesting -= 1
178
+ obj
179
+ when @allow_nan && scan(NAN)
180
+ NaN
181
+ when @allow_nan && scan(INFINITY)
182
+ Infinity
183
+ when @allow_nan && scan(MINUS_INFINITY)
184
+ MinusInfinity
185
+ else
186
+ UNPARSED
187
+ end
188
+ end
189
+
190
+ def parse_array
191
+ raise NestingError, "nesting of #@current_nesting is to deep" if
192
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
193
+ result = @array_class.new
194
+ delim = false
195
+ until eos?
196
+ case
197
+ when (value = parse_value) != UNPARSED
198
+ delim = false
199
+ result << value
200
+ skip(IGNORE)
201
+ if scan(COLLECTION_DELIMITER)
202
+ delim = true
203
+ elsif match?(ARRAY_CLOSE)
204
+ ;
205
+ else
206
+ raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
207
+ end
208
+ when scan(ARRAY_CLOSE)
209
+ if delim
210
+ raise ParserError, "expected next element in array at '#{peek(20)}'!"
211
+ end
212
+ break
213
+ when skip(IGNORE)
214
+ ;
215
+ else
216
+ raise ParserError, "unexpected token in array at '#{peek(20)}'!"
217
+ end
218
+ end
219
+ result
220
+ end
221
+
222
+ def parse_object
223
+ raise NestingError, "nesting of #@current_nesting is to deep" if
224
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
225
+ result = @object_class.new
226
+ delim = false
227
+ until eos?
228
+ case
229
+ when (string = parse_string) != UNPARSED
230
+ skip(IGNORE)
231
+ unless scan(PAIR_DELIMITER)
232
+ raise ParserError, "expected ':' in object at '#{peek(20)}'!"
233
+ end
234
+ skip(IGNORE)
235
+ unless (value = parse_value).equal? UNPARSED
236
+ result[string] = value
237
+ delim = false
238
+ skip(IGNORE)
239
+ if scan(COLLECTION_DELIMITER)
240
+ delim = true
241
+ elsif match?(OBJECT_CLOSE)
242
+ ;
243
+ else
244
+ raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
245
+ end
246
+ else
247
+ raise ParserError, "expected value in object at '#{peek(20)}'!"
248
+ end
249
+ when scan(OBJECT_CLOSE)
250
+ if delim
251
+ raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
252
+ end
253
+ if @create_id and klassname = result[@create_id]
254
+ klass = JSON.deep_const_get klassname
255
+ break unless klass and klass.json_creatable?
256
+ result = klass.json_create(result)
257
+ end
258
+ break
259
+ when skip(IGNORE)
260
+ ;
261
+ else
262
+ raise ParserError, "unexpected token in object at '#{peek(20)}'!"
263
+ end
264
+ end
265
+ result
266
+ end
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,8 @@
1
+ module JSON
2
+ # JSON version
3
+ VERSION = '1.1.7'
4
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
5
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
7
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
8
+ end
@@ -0,0 +1 @@
1
+ "A JSON payload should be an object or array, not a string."
@@ -0,0 +1 @@
1
+ {"Extra value after close": true} "misplaced quoted value"
@@ -0,0 +1 @@
1
+ {"Illegal expression": 1 + 2}
@@ -0,0 +1 @@
1
+ {"Illegal invocation": alert()}
@@ -0,0 +1 @@
1
+ {"Numbers cannot have leading zeroes": 013}
@@ -0,0 +1 @@
1
+ {"Numbers cannot be hex": 0x14}
@@ -0,0 +1 @@
1
+ [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
@@ -0,0 +1 @@
1
+ {"Missing colon" null}
@@ -0,0 +1 @@
1
+ ["Unclosed array"
@@ -0,0 +1 @@
1
+ {"Double colon":: null}
@@ -0,0 +1 @@
1
+ {"Comma instead of colon", null}
@@ -0,0 +1 @@
1
+ ["Colon instead of comma": false]
@@ -0,0 +1 @@
1
+ ["Bad value", truth]
@@ -0,0 +1 @@
1
+ ['single quote']
@@ -0,0 +1 @@
1
+ ["tab character in string "]
@@ -0,0 +1,2 @@
1
+ ["line
2
+ break"]
@@ -0,0 +1,2 @@
1
+ ["line\
2
+ break"]
@@ -0,0 +1 @@
1
+ {unquoted_key: "keys must be quoted"}
@@ -0,0 +1 @@
1
+ ["extra comma",]
@@ -0,0 +1 @@
1
+ ["double extra comma",,]
@@ -0,0 +1 @@
1
+ [ , "<-- missing value"]
@@ -0,0 +1 @@
1
+ ["Comma after the close"],
@@ -0,0 +1 @@
1
+ ["Extra close"]]
@@ -0,0 +1 @@
1
+ {"Extra comma": true,}
@@ -0,0 +1,56 @@
1
+ [
2
+ "JSON Test Pattern pass1",
3
+ {"object with 1 member":["array with 1 element"]},
4
+ {},
5
+ [],
6
+ -42,
7
+ true,
8
+ false,
9
+ null,
10
+ {
11
+ "integer": 1234567890,
12
+ "real": -9876.543210,
13
+ "e": 0.123456789e-12,
14
+ "E": 1.234567890E+34,
15
+ "": 23456789012E666,
16
+ "zero": 0,
17
+ "one": 1,
18
+ "space": " ",
19
+ "quote": "\"",
20
+ "backslash": "\\",
21
+ "controls": "\b\f\n\r\t",
22
+ "slash": "/ & \/",
23
+ "alpha": "abcdefghijklmnopqrstuvwyz",
24
+ "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
25
+ "digit": "0123456789",
26
+ "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
27
+ "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
28
+ "true": true,
29
+ "false": false,
30
+ "null": null,
31
+ "array":[ ],
32
+ "object":{ },
33
+ "address": "50 St. James Street",
34
+ "url": "http://www.JSON.org/",
35
+ "comment": "// /* <!-- --",
36
+ "# -- --> */": " ",
37
+ " s p a c e d " :[1,2 , 3
38
+
39
+ ,
40
+
41
+ 4 , 5 , 6 ,7 ],
42
+ "compact": [1,2,3,4,5,6,7],
43
+ "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
44
+ "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
45
+ "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
46
+ : "A key can be any string"
47
+ },
48
+ 0.5 ,98.6
49
+ ,
50
+ 99.44
51
+ ,
52
+
53
+ 1066
54
+
55
+
56
+ ,"rosebud"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \x15"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \'"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \017"]
@@ -0,0 +1 @@
1
+ [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
@@ -0,0 +1 @@
1
+ ["tab\ character\ in\ string\ "]
@@ -0,0 +1,6 @@
1
+ {
2
+ "JSON Test Pattern pass3": {
3
+ "The outermost value": "must be an object or array.",
4
+ "In this test": "It is an object."
5
+ }
6
+ }
@@ -0,0 +1,312 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'test/unit'
5
+ case ENV['JSON']
6
+ when 'pure' then require 'json/pure'
7
+ when 'ext' then require 'json/ext'
8
+ else require 'json'
9
+ end
10
+ require 'stringio'
11
+
12
+ class TC_JSON < Test::Unit::TestCase
13
+ include JSON
14
+
15
+ def setup
16
+ @ary = [1, "foo", 3.14, 4711.0, 2.718, nil, [1,-2,3], false, true].map do
17
+ |x| [x]
18
+ end
19
+ @ary_to_parse = ["1", '"foo"', "3.14", "4711.0", "2.718", "null",
20
+ "[1,-2,3]", "false", "true"].map do
21
+ |x| "[#{x}]"
22
+ end
23
+ @hash = {
24
+ 'a' => 2,
25
+ 'b' => 3.141,
26
+ 'c' => 'c',
27
+ 'd' => [ 1, "b", 3.14 ],
28
+ 'e' => { 'foo' => 'bar' },
29
+ 'g' => "\"\0\037",
30
+ 'h' => 1000.0,
31
+ 'i' => 0.001
32
+ }
33
+ @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
34
+ '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}'
35
+ end
36
+
37
+ def test_construction
38
+ parser = JSON::Parser.new('test')
39
+ assert_equal 'test', parser.source
40
+ end
41
+
42
+ def assert_equal_float(expected, is)
43
+ assert_in_delta(expected.first, is.first, 1e-2)
44
+ end
45
+
46
+ def test_parse_simple_arrays
47
+ assert_equal([], parse('[]'))
48
+ assert_equal([], parse(' [ ] '))
49
+ assert_equal([nil], parse('[null]'))
50
+ assert_equal([false], parse('[false]'))
51
+ assert_equal([true], parse('[true]'))
52
+ assert_equal([-23], parse('[-23]'))
53
+ assert_equal([23], parse('[23]'))
54
+ assert_equal([0.23], parse('[0.23]'))
55
+ assert_equal([0.0], parse('[0e0]'))
56
+ assert_raises(JSON::ParserError) { parse('[+23.2]') }
57
+ assert_raises(JSON::ParserError) { parse('[+23]') }
58
+ assert_raises(JSON::ParserError) { parse('[.23]') }
59
+ assert_raises(JSON::ParserError) { parse('[023]') }
60
+ assert_equal_float [3.141], parse('[3.141]')
61
+ assert_equal_float [-3.141], parse('[-3.141]')
62
+ assert_equal_float [3.141], parse('[3141e-3]')
63
+ assert_equal_float [3.141], parse('[3141.1e-3]')
64
+ assert_equal_float [3.141], parse('[3141E-3]')
65
+ assert_equal_float [3.141], parse('[3141.0E-3]')
66
+ assert_equal_float [-3.141], parse('[-3141.0e-3]')
67
+ assert_equal_float [-3.141], parse('[-3141e-3]')
68
+ assert_raises(ParserError) { parse('[NaN]') }
69
+ assert parse('[NaN]', :allow_nan => true).first.nan?
70
+ assert_raises(ParserError) { parse('[Infinity]') }
71
+ assert_equal [1.0/0], parse('[Infinity]', :allow_nan => true)
72
+ assert_raises(ParserError) { parse('[-Infinity]') }
73
+ assert_equal [-1.0/0], parse('[-Infinity]', :allow_nan => true)
74
+ assert_equal([""], parse('[""]'))
75
+ assert_equal(["foobar"], parse('["foobar"]'))
76
+ assert_equal([{}], parse('[{}]'))
77
+ end
78
+
79
+ def test_parse_simple_objects
80
+ assert_equal({}, parse('{}'))
81
+ assert_equal({}, parse(' { } '))
82
+ assert_equal({ "a" => nil }, parse('{ "a" : null}'))
83
+ assert_equal({ "a" => nil }, parse('{"a":null}'))
84
+ assert_equal({ "a" => false }, parse('{ "a" : false } '))
85
+ assert_equal({ "a" => false }, parse('{"a":false}'))
86
+ assert_raises(JSON::ParserError) { parse('{false}') }
87
+ assert_equal({ "a" => true }, parse('{"a":true}'))
88
+ assert_equal({ "a" => true }, parse(' { "a" : true } '))
89
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
90
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
91
+ assert_equal({ "a" => 23 }, parse('{"a":23 } '))
92
+ assert_equal({ "a" => 23 }, parse(' { "a" : 23 } '))
93
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
94
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
95
+ end
96
+
97
+ begin
98
+ require 'permutation'
99
+ def test_parse_more_complex_arrays
100
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
101
+ perms = Permutation.for a
102
+ perms.each do |perm|
103
+ orig_ary = perm.project
104
+ json = pretty_generate(orig_ary)
105
+ assert_equal orig_ary, parse(json)
106
+ end
107
+ end
108
+
109
+ def test_parse_complex_objects
110
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
111
+ perms = Permutation.for a
112
+ perms.each do |perm|
113
+ s = "a"
114
+ orig_obj = perm.project.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
115
+ json = pretty_generate(orig_obj)
116
+ assert_equal orig_obj, parse(json)
117
+ end
118
+ end
119
+ rescue LoadError
120
+ warn "Skipping permutation tests."
121
+ end
122
+
123
+ def test_parse_arrays
124
+ assert_equal([1,2,3], parse('[1,2,3]'))
125
+ assert_equal([1.2,2,3], parse('[1.2,2,3]'))
126
+ assert_equal([[],[[],[]]], parse('[[],[[],[]]]'))
127
+ end
128
+
129
+ def test_parse_values
130
+ assert_equal([""], parse('[""]'))
131
+ assert_equal(["\\"], parse('["\\\\"]'))
132
+ assert_equal(['"'], parse('["\""]'))
133
+ assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]'))
134
+ assert_equal(["\"\b\n\r\t\0\037"],
135
+ parse('["\"\b\n\r\t\u0000\u001f"]'))
136
+ for i in 0 ... @ary.size
137
+ assert_equal(@ary[i], parse(@ary_to_parse[i]))
138
+ end
139
+ end
140
+
141
+ def test_parse_array
142
+ assert_equal([], parse('[]'))
143
+ assert_equal([], parse(' [ ] '))
144
+ assert_equal([1], parse('[1]'))
145
+ assert_equal([1], parse(' [ 1 ] '))
146
+ assert_equal(@ary,
147
+ parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]]'\
148
+ ',[false],[true]]'))
149
+ assert_equal(@ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]
150
+ , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
151
+ end
152
+
153
+ class SubArray < Array; end
154
+
155
+ def test_parse_array_custom_class
156
+ res = parse('[]', :array_class => SubArray)
157
+ assert_equal([], res)
158
+ assert_equal(SubArray, res.class)
159
+ end
160
+
161
+ def test_parse_object
162
+ assert_equal({}, parse('{}'))
163
+ assert_equal({}, parse(' { } '))
164
+ assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}'))
165
+ assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } '))
166
+ end
167
+
168
+ class SubHash < Hash; end
169
+
170
+ def test_parse_object_custom_class
171
+ res = parse('{}', :object_class => SubHash)
172
+ assert_equal({}, res)
173
+ assert_equal(SubHash, res.class)
174
+ end
175
+
176
+ def test_parser_reset
177
+ parser = Parser.new(@json)
178
+ assert_equal(@hash, parser.parse)
179
+ assert_equal(@hash, parser.parse)
180
+ end
181
+
182
+ def test_comments
183
+ json = <<EOT
184
+ {
185
+ "key1":"value1", // eol comment
186
+ "key2":"value2" /* multi line
187
+ * comment */,
188
+ "key3":"value3" /* multi line
189
+ // nested eol comment
190
+ * comment */
191
+ }
192
+ EOT
193
+ assert_equal(
194
+ { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
195
+ parse(json))
196
+ json = <<EOT
197
+ {
198
+ "key1":"value1" /* multi line
199
+ // nested eol comment
200
+ /* illegal nested multi line comment */
201
+ * comment */
202
+ }
203
+ EOT
204
+ assert_raises(ParserError) { parse(json) }
205
+ json = <<EOT
206
+ {
207
+ "key1":"value1" /* multi line
208
+ // nested eol comment
209
+ closed multi comment */
210
+ and again, throw an Error */
211
+ }
212
+ EOT
213
+ assert_raises(ParserError) { parse(json) }
214
+ json = <<EOT
215
+ {
216
+ "key1":"value1" /*/*/
217
+ }
218
+ EOT
219
+ assert_equal({ "key1" => "value1" }, parse(json))
220
+ end
221
+
222
+ def test_backslash
223
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
224
+ json = '["\\\\.(?i:gif|jpe?g|png)$"]'
225
+ assert_equal json, JSON.unparse(data)
226
+ assert_equal data, JSON.parse(json)
227
+ #
228
+ data = [ '\\"' ]
229
+ json = '["\\\\\""]'
230
+ assert_equal json, JSON.unparse(data)
231
+ assert_equal data, JSON.parse(json)
232
+ #
233
+ json = '["\/"]'
234
+ data = JSON.parse(json)
235
+ assert_equal ['/'], data
236
+ assert_equal json, JSON.unparse(data)
237
+ #
238
+ json = '["\""]'
239
+ data = JSON.parse(json)
240
+ assert_equal ['"'], data
241
+ assert_equal json, JSON.unparse(data)
242
+ json = '["\\\'"]'
243
+ data = JSON.parse(json)
244
+ assert_equal ["'"], data
245
+ assert_equal '["\'"]', JSON.unparse(data)
246
+ end
247
+
248
+ def test_wrong_inputs
249
+ assert_raises(ParserError) { JSON.parse('"foo"') }
250
+ assert_raises(ParserError) { JSON.parse('123') }
251
+ assert_raises(ParserError) { JSON.parse('[] bla') }
252
+ assert_raises(ParserError) { JSON.parse('[] 1') }
253
+ assert_raises(ParserError) { JSON.parse('[] []') }
254
+ assert_raises(ParserError) { JSON.parse('[] {}') }
255
+ assert_raises(ParserError) { JSON.parse('{} []') }
256
+ assert_raises(ParserError) { JSON.parse('{} {}') }
257
+ assert_raises(ParserError) { JSON.parse('[NULL]') }
258
+ assert_raises(ParserError) { JSON.parse('[FALSE]') }
259
+ assert_raises(ParserError) { JSON.parse('[TRUE]') }
260
+ assert_raises(ParserError) { JSON.parse('[07] ') }
261
+ assert_raises(ParserError) { JSON.parse('[0a]') }
262
+ assert_raises(ParserError) { JSON.parse('[1.]') }
263
+ assert_raises(ParserError) { JSON.parse(' ') }
264
+ end
265
+
266
+ def test_nesting
267
+ assert_raises(JSON::NestingError) { JSON.parse '[[]]', :max_nesting => 1 }
268
+ assert_raises(JSON::NestingError) { JSON.parser.new('[[]]', :max_nesting => 1).parse }
269
+ assert_equal [[]], JSON.parse('[[]]', :max_nesting => 2)
270
+ too_deep = '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]'
271
+ too_deep_ary = eval too_deep
272
+ assert_raises(JSON::NestingError) { JSON.parse too_deep }
273
+ assert_raises(JSON::NestingError) { JSON.parser.new(too_deep).parse }
274
+ assert_raises(JSON::NestingError) { JSON.parse too_deep, :max_nesting => 19 }
275
+ ok = JSON.parse too_deep, :max_nesting => 20
276
+ assert_equal too_deep_ary, ok
277
+ ok = JSON.parse too_deep, :max_nesting => nil
278
+ assert_equal too_deep_ary, ok
279
+ ok = JSON.parse too_deep, :max_nesting => false
280
+ assert_equal too_deep_ary, ok
281
+ ok = JSON.parse too_deep, :max_nesting => 0
282
+ assert_equal too_deep_ary, ok
283
+ assert_raises(JSON::NestingError) { JSON.generate [[]], :max_nesting => 1 }
284
+ assert_equal '[[]]', JSON.generate([[]], :max_nesting => 2)
285
+ assert_raises(JSON::NestingError) { JSON.generate too_deep_ary }
286
+ assert_raises(JSON::NestingError) { JSON.generate too_deep_ary, :max_nesting => 19 }
287
+ ok = JSON.generate too_deep_ary, :max_nesting => 20
288
+ assert_equal too_deep, ok
289
+ ok = JSON.generate too_deep_ary, :max_nesting => nil
290
+ assert_equal too_deep, ok
291
+ ok = JSON.generate too_deep_ary, :max_nesting => false
292
+ assert_equal too_deep, ok
293
+ ok = JSON.generate too_deep_ary, :max_nesting => 0
294
+ assert_equal too_deep, ok
295
+ end
296
+
297
+ def test_load_dump
298
+ too_deep = '[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]'
299
+ assert_equal too_deep, JSON.dump(eval(too_deep))
300
+ assert_kind_of String, Marshal.dump(eval(too_deep))
301
+ assert_raises(ArgumentError) { JSON.dump(eval(too_deep), 19) }
302
+ assert_raises(ArgumentError) { Marshal.dump(eval(too_deep), 19) }
303
+ assert_equal too_deep, JSON.dump(eval(too_deep), 20)
304
+ assert_kind_of String, Marshal.dump(eval(too_deep), 20)
305
+ output = StringIO.new
306
+ JSON.dump(eval(too_deep), output)
307
+ assert_equal too_deep, output.string
308
+ output = StringIO.new
309
+ JSON.dump(eval(too_deep), output, 20)
310
+ assert_equal too_deep, output.string
311
+ end
312
+ end