crazy_ivan 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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