oj 2.1.3 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of oj might be problematic. Click here for more details.

Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -4
  3. data/ext/oj/compat.c +3 -4
  4. data/ext/oj/encode.h +51 -0
  5. data/ext/oj/fast.c +4 -9
  6. data/ext/oj/object.c +7 -19
  7. data/ext/oj/oj.c +32 -12
  8. data/ext/oj/oj.h +3 -0
  9. data/ext/oj/parse.c +2 -3
  10. data/ext/oj/saj.c +4 -9
  11. data/ext/oj/scp.c +5 -12
  12. data/ext/oj/strict.c +5 -12
  13. data/lib/oj/version.rb +1 -1
  14. data/test/a.rb +38 -0
  15. data/test/bug.rb +15 -0
  16. data/test/e.rb +12 -0
  17. data/test/files.rb +29 -0
  18. data/test/foo.rb +24 -0
  19. data/test/mj.rb +48 -0
  20. data/test/perf.rb +107 -0
  21. data/test/perf_compat.rb +128 -0
  22. data/test/perf_fast.rb +164 -0
  23. data/test/perf_object.rb +136 -0
  24. data/test/perf_saj.rb +109 -0
  25. data/test/perf_scp.rb +151 -0
  26. data/test/perf_simple.rb +287 -0
  27. data/test/perf_strict.rb +127 -0
  28. data/test/sample.rb +55 -0
  29. data/test/sample/change.rb +14 -0
  30. data/test/sample/dir.rb +19 -0
  31. data/test/sample/doc.rb +36 -0
  32. data/test/sample/file.rb +48 -0
  33. data/test/sample/group.rb +16 -0
  34. data/test/sample/hasprops.rb +16 -0
  35. data/test/sample/layer.rb +12 -0
  36. data/test/sample/line.rb +20 -0
  37. data/test/sample/oval.rb +10 -0
  38. data/test/sample/rect.rb +10 -0
  39. data/test/sample/shape.rb +35 -0
  40. data/test/sample/text.rb +20 -0
  41. data/test/sample_json.rb +37 -0
  42. data/test/test_compat.rb +342 -0
  43. data/test/test_fast.rb +416 -0
  44. data/test/test_mimic.rb +208 -0
  45. data/test/test_mimic_after.rb +35 -0
  46. data/test/test_object.rb +390 -0
  47. data/test/test_saj.rb +184 -0
  48. data/test/test_scp.rb +224 -0
  49. data/test/test_strict.rb +259 -0
  50. data/test/tests.rb +1017 -0
  51. data/test/x.rb +59 -0
  52. metadata +41 -2
@@ -0,0 +1,224 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is
5
+ # required. That can be set in the RUBYOPT environment variable.
6
+ # export RUBYOPT=-w
7
+
8
+ $VERBOSE = true
9
+
10
+ $: << File.join(File.dirname(__FILE__), "../lib")
11
+ $: << File.join(File.dirname(__FILE__), "../ext")
12
+
13
+ require 'test/unit'
14
+ require 'oj'
15
+ require 'pp'
16
+
17
+ $json = %{{
18
+ "array": [
19
+ {
20
+ "num" : 3,
21
+ "string": "message",
22
+ "hash" : {
23
+ "h2" : {
24
+ "a" : [ 1, 2, 3 ]
25
+ }
26
+ }
27
+ }
28
+ ],
29
+ "boolean" : true
30
+ }}
31
+
32
+ class NoHandler < Oj::ScHandler
33
+ def initialize()
34
+ end
35
+ end
36
+
37
+ class AllHandler < Oj::ScHandler
38
+ attr_accessor :calls
39
+
40
+ def initialize()
41
+ @calls = []
42
+ end
43
+
44
+ def hash_start()
45
+ @calls << [:hash_start]
46
+ {}
47
+ end
48
+
49
+ def hash_end()
50
+ @calls << [:hash_end]
51
+ end
52
+
53
+ def array_start()
54
+ @calls << [:array_start]
55
+ []
56
+ end
57
+
58
+ def array_end()
59
+ @calls << [:array_end]
60
+ end
61
+
62
+ def add_value(value)
63
+ @calls << [:add_value, value]
64
+ end
65
+
66
+ def hash_set(h, key, value)
67
+ @calls << [:hash_set, key, value]
68
+ end
69
+
70
+ def array_append(a, value)
71
+ @calls << [:array_append, value]
72
+ end
73
+
74
+ end # AllHandler
75
+
76
+ class ScpTest < ::Test::Unit::TestCase
77
+
78
+ def test_nil
79
+ handler = AllHandler.new()
80
+ json = %{null}
81
+ Oj.sc_parse(handler, json)
82
+ assert_equal([[:add_value, nil]], handler.calls)
83
+ end
84
+
85
+ def test_true
86
+ handler = AllHandler.new()
87
+ json = %{true}
88
+ Oj.sc_parse(handler, json)
89
+ assert_equal([[:add_value, true]], handler.calls)
90
+ end
91
+
92
+ def test_false
93
+ handler = AllHandler.new()
94
+ json = %{false}
95
+ Oj.sc_parse(handler, json)
96
+ assert_equal([[:add_value, false]], handler.calls)
97
+ end
98
+
99
+ def test_string
100
+ handler = AllHandler.new()
101
+ json = %{"a string"}
102
+ Oj.sc_parse(handler, json)
103
+ assert_equal([[:add_value, 'a string']], handler.calls)
104
+ end
105
+
106
+ def test_fixnum
107
+ handler = AllHandler.new()
108
+ json = %{12345}
109
+ Oj.sc_parse(handler, json)
110
+ assert_equal([[:add_value, 12345]], handler.calls)
111
+ end
112
+
113
+ def test_float
114
+ handler = AllHandler.new()
115
+ json = %{12345.6789}
116
+ Oj.sc_parse(handler, json)
117
+ assert_equal([[:add_value, 12345.6789]], handler.calls)
118
+ end
119
+
120
+ def test_float_exp
121
+ handler = AllHandler.new()
122
+ json = %{12345.6789e7}
123
+ Oj.sc_parse(handler, json)
124
+ assert_equal(1, handler.calls.size)
125
+ assert_equal(:add_value, handler.calls[0][0])
126
+ assert_equal((12345.6789e7 * 10000).to_i, (handler.calls[0][1] * 10000).to_i)
127
+ end
128
+
129
+ def test_array_empty
130
+ handler = AllHandler.new()
131
+ json = %{[]}
132
+ Oj.sc_parse(handler, json)
133
+ assert_equal([[:array_start],
134
+ [:array_end],
135
+ [:add_value, []]], handler.calls)
136
+ end
137
+
138
+ def test_array
139
+ handler = AllHandler.new()
140
+ json = %{[true,false]}
141
+ Oj.sc_parse(handler, json)
142
+ assert_equal([[:array_start],
143
+ [:array_append, true],
144
+ [:array_append, false],
145
+ [:array_end],
146
+ [:add_value, []]], handler.calls)
147
+ end
148
+
149
+ def test_hash_empty
150
+ handler = AllHandler.new()
151
+ json = %{{}}
152
+ Oj.sc_parse(handler, json)
153
+ assert_equal([[:hash_start],
154
+ [:hash_end],
155
+ [:add_value, {}]], handler.calls)
156
+ end
157
+
158
+ def test_hash
159
+ handler = AllHandler.new()
160
+ json = %{{"one":true,"two":false}}
161
+ Oj.sc_parse(handler, json)
162
+ assert_equal([[:hash_start],
163
+ [:hash_set, 'one', true],
164
+ [:hash_set, 'two', false],
165
+ [:hash_end],
166
+ [:add_value, {}]], handler.calls)
167
+ end
168
+
169
+ def test_hash_sym
170
+ handler = AllHandler.new()
171
+ json = %{{"one":true,"two":false}}
172
+ Oj.sc_parse(handler, json, :symbol_keys => true)
173
+ assert_equal([[:hash_start],
174
+ [:hash_set, :one, true],
175
+ [:hash_set, :two, false],
176
+ [:hash_end],
177
+ [:add_value, {}]], handler.calls)
178
+ end
179
+
180
+ def test_full
181
+ handler = AllHandler.new()
182
+ Oj.sc_parse(handler, $json)
183
+ assert_equal([[:hash_start],
184
+ [:array_start],
185
+ [:hash_start],
186
+ [:hash_set, "num", 3],
187
+ [:hash_set, "string", "message"],
188
+ [:hash_start],
189
+ [:hash_start],
190
+ [:array_start],
191
+ [:array_append, 1],
192
+ [:array_append, 2],
193
+ [:array_append, 3],
194
+ [:array_end],
195
+ [:hash_set, "a", []],
196
+ [:hash_end],
197
+ [:hash_set, "h2", {}],
198
+ [:hash_end],
199
+ [:hash_set, "hash", {}],
200
+ [:hash_end],
201
+ [:array_append, {}],
202
+ [:array_end],
203
+ [:hash_set, "array", []],
204
+ [:hash_set, "boolean", true],
205
+ [:hash_end],
206
+ [:add_value, {}]], handler.calls)
207
+ end
208
+
209
+ def test_none
210
+ handler = NoHandler.new()
211
+ Oj.sc_parse(handler, $json)
212
+ end
213
+
214
+ def test_fixnum_bad
215
+ handler = AllHandler.new()
216
+ json = %{12345xyz}
217
+ begin
218
+ Oj.sc_parse(handler, json)
219
+ rescue Exception => e
220
+ assert_equal("unexpected character at line 1, column 6 [parse.c:625]", e.message)
221
+ end
222
+ end
223
+
224
+ end
@@ -0,0 +1,259 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is
5
+ # required. That can be set in the RUBYOPT environment variable.
6
+ # export RUBYOPT=-w
7
+
8
+ $VERBOSE = true
9
+
10
+ $: << File.join(File.dirname(__FILE__), "../lib")
11
+ $: << File.join(File.dirname(__FILE__), "../ext")
12
+
13
+ require 'test/unit'
14
+ require 'stringio'
15
+ require 'date'
16
+ require 'bigdecimal'
17
+ require 'oj'
18
+
19
+ $ruby = RUBY_DESCRIPTION.split(' ')[0]
20
+ $ruby = 'ree' if 'ruby' == $ruby && RUBY_DESCRIPTION.include?('Ruby Enterprise Edition')
21
+
22
+ def hash_eql(h1, h2)
23
+ return false if h1.size != h2.size
24
+ h1.keys.each do |k|
25
+ return false unless h1[k] == h2[k]
26
+ end
27
+ true
28
+ end
29
+
30
+ class StrictJuice < ::Test::Unit::TestCase
31
+
32
+ def test_nil
33
+ dump_and_load(nil, false)
34
+ end
35
+
36
+ def test_true
37
+ dump_and_load(true, false)
38
+ end
39
+
40
+ def test_false
41
+ dump_and_load(false, false)
42
+ end
43
+
44
+ def test_fixnum
45
+ dump_and_load(0, false)
46
+ dump_and_load(12345, false)
47
+ dump_and_load(-54321, false)
48
+ dump_and_load(1, false)
49
+ end
50
+
51
+ def test_float
52
+ dump_and_load(0.0, false)
53
+ dump_and_load(12345.6789, false)
54
+ dump_and_load(70.35, false)
55
+ dump_and_load(-54321.012, false)
56
+ dump_and_load(2.48e16, false)
57
+ dump_and_load(2.48e100 * 1.0e10, false)
58
+ dump_and_load(-2.48e100 * 1.0e10, false)
59
+ end
60
+
61
+ def test_string
62
+ dump_and_load('', false)
63
+ dump_and_load('abc', false)
64
+ dump_and_load("abc\ndef", false)
65
+ dump_and_load("a\u0041", false)
66
+ end
67
+
68
+ def test_encode
69
+ opts = Oj.default_options
70
+ Oj.default_options = { :ascii_only => false }
71
+ unless 'jruby' == $ruby
72
+ dump_and_load("ぴーたー", false)
73
+ end
74
+ Oj.default_options = { :ascii_only => true }
75
+ json = Oj.dump("ぴーたー")
76
+ assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
77
+ unless 'jruby' == $ruby
78
+ dump_and_load("ぴーたー", false)
79
+ end
80
+ Oj.default_options = opts
81
+ end
82
+
83
+ def test_unicode
84
+ # hits the 3 normal ranges and one extended surrogate pair
85
+ json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e"}
86
+ obj = Oj.load(json)
87
+ json2 = Oj.dump(obj, :ascii_only => true)
88
+ assert_equal(json, json2)
89
+ end
90
+
91
+ def test_unicode_long
92
+ # tests buffer overflow
93
+ json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e #{'x' * 2000}"}
94
+ obj = Oj.load(json)
95
+ json2 = Oj.dump(obj, :ascii_only => true)
96
+ assert_equal(json, json2)
97
+ end
98
+
99
+ def test_array
100
+ dump_and_load([], false)
101
+ dump_and_load([true, false], false)
102
+ dump_and_load(['a', 1, nil], false)
103
+ dump_and_load([[nil]], false)
104
+ dump_and_load([[nil], 58], false)
105
+ end
106
+
107
+ def test_array_deep
108
+ dump_and_load([1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20]]]]]]]]]]]]]]]]]]]], false)
109
+ end
110
+
111
+ # Hash
112
+ def test_hash
113
+ dump_and_load({}, false)
114
+ dump_and_load({ 'true' => true, 'false' => false}, false)
115
+ dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
116
+ end
117
+
118
+ def test_hash_deep
119
+ dump_and_load({'1' => {
120
+ '2' => {
121
+ '3' => {
122
+ '4' => {
123
+ '5' => {
124
+ '6' => {
125
+ '7' => {
126
+ '8' => {
127
+ '9' => {
128
+ '10' => {
129
+ '11' => {
130
+ '12' => {
131
+ '13' => {
132
+ '14' => {
133
+ '15' => {
134
+ '16' => {
135
+ '17' => {
136
+ '18' => {
137
+ '19' => {
138
+ '20' => {}}}}}}}}}}}}}}}}}}}}}, false)
139
+ end
140
+
141
+ def test_hash_escaped_key
142
+ json = %{{"a\nb":true,"c\td":false}}
143
+ obj = Oj.strict_load(json)
144
+ assert_equal({"a\nb" => true, "c\td" => false}, obj)
145
+ end
146
+
147
+ def test_bignum_object
148
+ dump_and_load(7 ** 55, false)
149
+ end
150
+
151
+ # BigDecimal
152
+ def test_bigdecimal_strict
153
+ dump_and_load(BigDecimal.new('3.14159265358979323846'), false)
154
+ end
155
+
156
+ def test_bigdecimal_load
157
+ orig = BigDecimal.new('80.51')
158
+ json = Oj.dump(orig, :mode => :compat, :bigdecimal_as_decimal => true)
159
+ bg = Oj.load(json, :mode => :compat, :bigdecimal_load => true)
160
+ assert_equal(BigDecimal, bg.class)
161
+ assert_equal(orig, bg)
162
+ end
163
+
164
+ # Stream IO
165
+ def test_io_string
166
+ json = %{{
167
+ "x":true,
168
+ "y":58,
169
+ "z": [1,2,3]
170
+ }
171
+ }
172
+ input = StringIO.new(json)
173
+ obj = Oj.strict_load(input)
174
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
175
+ end
176
+
177
+ def test_io_file
178
+ filename = 'open_file_test.json'
179
+ File.open(filename, 'w') { |f| f.write(%{{
180
+ "x":true,
181
+ "y":58,
182
+ "z": [1,2,3]
183
+ }
184
+ }) }
185
+ f = File.new(filename)
186
+ obj = Oj.strict_load(f)
187
+ f.close()
188
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
189
+ end
190
+
191
+ # symbol_keys option
192
+ def test_symbol_keys
193
+ json = %{{
194
+ "x":true,
195
+ "y":58,
196
+ "z": [1,2,3]
197
+ }
198
+ }
199
+ obj = Oj.strict_load(json, :symbol_keys => true)
200
+ assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
201
+ end
202
+
203
+ def test_symbol_keys_safe
204
+ json = %{{
205
+ "x":true,
206
+ "y":58,
207
+ "z": [1,2,3]
208
+ }
209
+ }
210
+ obj = Oj.safe_load(json)
211
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
212
+ end
213
+
214
+ # comments
215
+ def test_comment_slash
216
+ json = %{{
217
+ "x":true,//three
218
+ "y":58,
219
+ "z": [1,2,
220
+ 3 // six
221
+ ]}
222
+ }
223
+ obj = Oj.strict_load(json)
224
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
225
+ end
226
+
227
+ def test_comment_c
228
+ json = %{{
229
+ "x"/*one*/:/*two*/true,
230
+ "y":58,
231
+ "z": [1,2,3]}
232
+ }
233
+ obj = Oj.strict_load(json)
234
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
235
+ end
236
+
237
+ def test_comment
238
+ json = %{{
239
+ "x"/*one*/:/*two*/true,//three
240
+ "y":58/*four*/,
241
+ "z": [1,2/*five*/,
242
+ 3 // six
243
+ ]
244
+ }
245
+ }
246
+ obj = Oj.strict_load(json)
247
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
248
+ end
249
+
250
+
251
+ def dump_and_load(obj, trace=false)
252
+ json = Oj.dump(obj, :indent => 2)
253
+ puts json if trace
254
+ loaded = Oj.strict_load(json);
255
+ assert_equal(obj, loaded)
256
+ loaded
257
+ end
258
+
259
+ end