ffi-yajl 2.2.3-universal-java → 2.4.0-universal-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,221 +0,0 @@
1
- # encoding: UTF-8
2
- # Copyright (c) 2015 Lamont Granquist
3
- # Copyright (c) 2015 Chef Software, Inc.
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining
6
- # a copy of this software and associated documentation files (the
7
- # "Software"), to deal in the Software without restriction, including
8
- # without limitation the rights to use, copy, modify, merge, publish,
9
- # distribute, sublicense, and/or sell copies of the Software, and to
10
- # permit persons to whom the Software is furnished to do so, subject to
11
- # the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be
14
- # included in all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- require 'spec_helper'
25
- require 'date'
26
-
27
- describe "FFI_Yajl::Encoder" do
28
- let(:options) { {} }
29
-
30
- let(:encoder) { FFI_Yajl::Encoder.new(options) }
31
-
32
- it "encodes hashes in keys as strings", ruby_gte_193: true do
33
- ruby = { { 'a' => 'b' } => 2 }
34
- expect(encoder.encode(ruby)).to eq('{"{\"a\"=>\"b\"}":2}')
35
- end
36
-
37
- it "encodes arrays in keys as strings", ruby_gte_193: true do
38
- ruby = { [0, 1] => 2 }
39
- expect(encoder.encode(ruby)).to eq('{"[0, 1]":2}')
40
- end
41
-
42
- it "encodes nil in keys as strings" do
43
- ruby = { nil => 2 }
44
- expect(encoder.encode(ruby)).to eq('{"":2}')
45
- end
46
-
47
- it "encodes true in keys as strings" do
48
- ruby = { true => 2 }
49
- expect(encoder.encode(ruby)).to eq('{"true":2}')
50
- end
51
-
52
- it "encodes false in keys as strings" do
53
- ruby = { false => 2 }
54
- expect(encoder.encode(ruby)).to eq('{"false":2}')
55
- end
56
-
57
- it "encodes fixnums in keys as strings" do
58
- ruby = { 1 => 2 }
59
- expect(encoder.encode(ruby)).to eq('{"1":2}')
60
- end
61
-
62
- it "encodes floats in keys as strings" do
63
- ruby = { 1.1 => 2 }
64
- expect(encoder.encode(ruby)).to eq('{"1.1":2}')
65
- end
66
-
67
- it "encodes bignums in keys as strings" do
68
- ruby = { 12_345_678_901_234_567_890 => 2 }
69
- expect(encoder.encode(ruby)).to eq('{"12345678901234567890":2}')
70
- end
71
-
72
- it "encodes objects in keys as strings" do
73
- o = Object.new
74
- ruby = { o => 2 }
75
- expect(encoder.encode(ruby)).to eq(%{{"#{o}":2}})
76
- end
77
-
78
- it "encodes an object in a key which has a #to_json method as strings" do
79
- class Thing
80
- def to_json(*a)
81
- "{}"
82
- end
83
- end
84
- o = Thing.new
85
- ruby = { o => 2 }
86
- expect(encoder.encode(ruby)).to eq(%{{"#{o}":2}})
87
- end
88
-
89
- # XXX: 127 == YAJL_MAX_DEPTH hardcodedness, zero control for us, it isn't even a twiddleable #define
90
- it "raises an exception for deeply nested arrays" do
91
- root = []
92
- a = root
93
- 127.times { |_| a << []; a = a[0] }
94
- expect { encoder.encode(root) }.to raise_error(FFI_Yajl::EncodeError)
95
- end
96
-
97
- it "raises an exception for deeply nested hashes" do
98
- root = {}
99
- a = root
100
- 127.times { |_| a["a"] = {}; a = a["a"] }
101
- expect { encoder.encode(root) }.to raise_error(FFI_Yajl::EncodeError)
102
- end
103
-
104
- it "encodes symbols in keys as strings" do
105
- ruby = { thing: 1 }
106
- expect(encoder.encode(ruby)).to eq('{"thing":1}')
107
- end
108
-
109
- it "encodes symbols in values as strings" do
110
- ruby = { "thing" => :one }
111
- expect(encoder.encode(ruby)).to eq('{"thing":"one"}')
112
- end
113
-
114
- it "can encode 32-bit unsigned ints" do
115
- ruby = { "gid" => 4_294_967_294 }
116
- expect(encoder.encode(ruby)).to eq('{"gid":4294967294}')
117
- end
118
-
119
- context "when the encoder has nil passed in for options" do
120
- let(:encoder) { FFI_Yajl::Encoder.new(nil) }
121
-
122
- it "does not throw an exception" do
123
- ruby = { "foo" => "bar" }
124
- expect(encoder.encode(ruby)).to eq("{\"foo\":\"bar\"}")
125
- end
126
- end
127
-
128
- it "can encode Date objects" do
129
- ruby = Date.parse('2001-02-03')
130
- expect(encoder.encode(ruby)).to eq( '"2001-02-03"' )
131
- end
132
-
133
- it "can encode StringIOs" do
134
- ruby = { "foo" => StringIO.new('THING') }
135
- expect(encoder.encode(ruby)).to eq("{\"foo\":\"THING\"}")
136
- end
137
-
138
- context "when encoding Time objects in UTC timezone" do
139
- before do
140
- @saved_tz = ENV['TZ']
141
- ENV['TZ'] = 'UTC'
142
- end
143
-
144
- after do
145
- ENV['TZ'] = @saved_tz
146
- end
147
-
148
- it "encodes them correctly" do
149
- ruby = Time.local(2001, 02, 02, 21, 05, 06)
150
- expect(encoder.encode(ruby)).to eq( '"2001-02-02 21:05:06 +0000"' )
151
- end
152
- end
153
-
154
- it "can encode DateTime objects" do
155
- ruby = DateTime.parse('2001-02-03T04:05:06.1+07:00')
156
- expect(encoder.encode(ruby)).to eq( '"2001-02-03T04:05:06+07:00"' )
157
- end
158
-
159
- describe "testing .to_json for Objects" do
160
- class NoToJson; end
161
- class HasToJson
162
- def to_json(*args)
163
- "{}"
164
- end
165
- end
166
-
167
- it "calls .to_s for objects without .to_json" do
168
- expect(encoder.encode(NoToJson.new)).to match(/^"#<NoToJson:\w+>"$/)
169
- end
170
-
171
- it "calls .to_json for objects wit .to_json" do
172
- expect(encoder.encode(HasToJson.new)).to eq("{}")
173
- end
174
- end
175
-
176
- context "when encoding invalid utf-8" do
177
- ruby = {
178
- "automatic" => {
179
- "etc" => {
180
- "passwd" => {
181
- "root" => { "dir" => "/root", "gid" => 0, "uid" => 0, "shell" => "/bin/sh", "gecos" => "Elan Ruusam\xc3\xa4e" },
182
- "glen" => { "dir" => "/home/glen", "gid" => 500, "uid" => 500, "shell" => "/bin/bash", "gecos" => "Elan Ruusam\xE4e" },
183
- "helmüt" => { "dir" => "/home/helmüt", "gid" => 500, "uid" => 500, "shell" => "/bin/bash", "gecos" => "Hañs Helmüt" },
184
- },
185
- },
186
- },
187
- }
188
-
189
- it "raises an error on invalid json" do
190
- expect { encoder.encode(ruby) }.to raise_error(FFI_Yajl::EncodeError, /Invalid UTF-8 string 'Elan Ruusam.*': cannot encode to UTF-8/)
191
- end
192
-
193
- context "when validate_utf8 is off" do
194
- let(:options) { { validate_utf8: false } }
195
-
196
- it "does not raise an error" do
197
- expect { encoder.encode(ruby) }.not_to raise_error
198
- end
199
-
200
- it "returns utf8" do
201
- expect( encoder.encode(ruby).encoding ).to eq(Encoding::UTF_8)
202
- end
203
-
204
- it "returns valid utf8" do
205
- expect( encoder.encode(ruby).valid_encoding? ).to be true
206
- end
207
-
208
- it "does not mangle valid utf8" do
209
- json = encoder.encode(ruby)
210
- expect(json).to match(/Hañs Helmüt/)
211
- end
212
-
213
- it "does not grow after a round trip" do
214
- json = encoder.encode(ruby)
215
- ruby2 = FFI_Yajl::Parser.parse(json)
216
- json2 = encoder.encode(ruby2)
217
- expect(json).to eql(json2)
218
- end
219
- end
220
- end
221
- end
@@ -1,115 +0,0 @@
1
- # Copyright (c) 2015 Lamont Granquist
2
- # Copyright (c) 2015 Chef Software, Inc.
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
-
23
- require 'spec_helper'
24
-
25
- class Test
26
- extend FFI_Yajl::MapLibraryName
27
- end
28
-
29
- host_os_library_name_mapping = {
30
- "mingw" => [ "libyajl.so", "yajl.dll" ],
31
- "mswin" => [ "libyajl.so", "yajl.dll" ],
32
- "cygwin" => [ "libyajl.so", "cygyajl.dll" ],
33
- "darwin" => [ "libyajl.bundle", "libyajl.dylib" ],
34
- "solaris2" => [ "libyajl.so" ],
35
- "linux" => [ "libyajl.so" ],
36
- "aix" => [ "libyajl.so" ],
37
- "hpux" => [ "libyajl.so" ],
38
- "netbsd" => [ "libyajl.so" ],
39
- "openbsd" => [ "libyajl.so" ],
40
- "freebsd" => [ "libyajl.so" ],
41
- }
42
-
43
- describe "FFI_Yajl::MapLibraryName" do
44
- let(:libyajl2_opt_path) { "/libyajl2/lib" }
45
- before do
46
- allow(Libyajl2).to receive(:opt_path).and_return(libyajl2_opt_path)
47
- end
48
-
49
- host_os_library_name_mapping.each do |host_os, library_names|
50
- context "#library_names" do
51
- it "maps #{host_os} correctly" do
52
- allow(Test).to receive(:host_os).and_return(host_os)
53
- expect(Test.send(:library_names)).to eq(library_names)
54
- end
55
- end
56
-
57
- context "#expanded_library_names" do
58
- it "maps #{host_os} correctly" do
59
- allow(Test).to receive(:host_os).and_return(host_os)
60
- expanded_library_names = []
61
- library_names.each do |library_name|
62
- path = File.expand_path(File.join(libyajl2_opt_path, library_name))
63
- expanded_library_names.push(path)
64
- expect(File).to receive(:file?).with(path).and_return(true)
65
- end
66
- expect(Test.send(:expanded_library_names)).to eq(expanded_library_names)
67
- end
68
- end
69
-
70
- context "#dlopen_yajl_library" do
71
- it "should call dlopen against an expanded library name if it finds it on #{host_os}" do
72
- allow(Test).to receive(:host_os).and_return(host_os)
73
- library_names.each do |library_name|
74
- path = File.expand_path(File.join(libyajl2_opt_path, library_name))
75
- allow(File).to receive(:file?).with(path).and_return(true)
76
- allow(Test).to receive(:dlopen).with(path).and_return(nil)
77
- end
78
- Test.send(:dlopen_yajl_library)
79
- end
80
- it "if dlopen calls all raise it should still use the short names on #{host_os}" do
81
- allow(Test).to receive(:host_os).and_return(host_os)
82
- library_names.each do |library_name|
83
- path = File.expand_path(File.join(libyajl2_opt_path, library_name))
84
- allow(File).to receive(:file?).with(path).and_return(true)
85
- allow(Test).to receive(:dlopen).with(path).and_raise(ArgumentError)
86
- end
87
- allow(Test).to receive(:dlopen).with(library_names.first).and_return(nil)
88
- Test.send(:dlopen_yajl_library)
89
- end
90
- end
91
-
92
- context "ffi_open_yajl_library" do
93
- it "should call ffi_lib against an expanded library name if it finds it on #{host_os}" do
94
- allow(Test).to receive(:host_os).and_return(host_os)
95
- library_names.each do |library_name|
96
- path = File.expand_path(File.join(libyajl2_opt_path, library_name))
97
- allow(File).to receive(:file?).with(path).and_return(true)
98
- allow(Test).to receive(:ffi_lib).with(path).and_return(nil)
99
- end
100
- Test.send(:ffi_open_yajl_library)
101
- end
102
-
103
- it "if dlopen calls all raise it should still use 'yajl' on #{host_os}" do
104
- allow(Test).to receive(:host_os).and_return(host_os)
105
- library_names.each do |library_name|
106
- path = File.expand_path(File.join(libyajl2_opt_path, library_name))
107
- allow(File).to receive(:file?).with(path).and_return(true)
108
- allow(Test).to receive(:ffi_lib).with(path).and_raise(LoadError)
109
- end
110
- allow(Test).to receive(:ffi_lib).with('yajl').and_return(nil)
111
- Test.send(:ffi_open_yajl_library)
112
- end
113
- end
114
- end
115
- end
@@ -1,569 +0,0 @@
1
- # encoding: UTF-8
2
- # Copyright (c) 2015 Lamont Granquist
3
- # Copyright (c) 2015 Chef Software, Inc.
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining
6
- # a copy of this software and associated documentation files (the
7
- # "Software"), to deal in the Software without restriction, including
8
- # without limitation the rights to use, copy, modify, merge, publish,
9
- # distribute, sublicense, and/or sell copies of the Software, and to
10
- # permit persons to whom the Software is furnished to do so, subject to
11
- # the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be
14
- # included in all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- require 'spec_helper'
25
-
26
- describe "FFI_Yajl::Parser" do
27
- shared_examples_for "correct json parsing" do
28
- context "when json has 23456789012E666" do
29
- let(:json) { '{"key": 23456789012E666}' }
30
-
31
- it "should return infinity" do
32
- infinity = (1.0 / 0)
33
- expect(parser).to eq("key" => infinity)
34
- end
35
- end
36
-
37
- context "when parsing nil" do
38
- let(:json) { nil }
39
- it "should not coredump ruby" do
40
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
41
- end
42
- end
43
-
44
- context "when parsing bare int" do
45
- let(:json) { "1" }
46
- it "should parse to the int value" do
47
- expect( parser ).to eq(1)
48
- end
49
- end
50
-
51
- context "when parsing bare string" do
52
- let(:json) { '"a"' }
53
- it "should parse to the string value" do
54
- expect( parser ).to eq("a")
55
- end
56
- end
57
-
58
- context "when parsing bare true" do
59
- let(:json) { "true" }
60
- it "should parse to the true value" do
61
- expect( parser ).to eq(true)
62
- end
63
- end
64
-
65
- context "when parsing bare false" do
66
- let(:json) { "false" }
67
- it "should parse to the false value" do
68
- expect( parser ).to eq(false)
69
- end
70
- end
71
-
72
- context "when parsing bare null" do
73
- let(:json) { "null" }
74
- it "should parse to the nil value" do
75
- expect( parser ).to eq(nil)
76
- end
77
- end
78
-
79
- context "when parsing bare float" do
80
- let(:json) { "1.1" }
81
- it "should parse to the a float" do
82
- expect( parser ).to eq(1.1)
83
- end
84
- end
85
-
86
- context "when json has comments" do
87
- let(:json) { '{"key": /* this is a comment */ "value"}' }
88
-
89
- context "when allow_comments is false" do
90
- let(:options) { { allow_comments: false } }
91
-
92
- it "should not parse" do
93
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
94
- end
95
- end
96
-
97
- context "when allow_comments is true" do
98
- let(:options) { { allow_comments: true } }
99
-
100
- it "should parse" do
101
- expect(parser).to eq("key" => "value")
102
- end
103
- end
104
-
105
- context "by default" do
106
- let(:options) {}
107
-
108
- it "should parse" do
109
- expect(parser).to eq("key" => "value")
110
- end
111
- end
112
- end
113
-
114
- context "when json has multiline comments" do
115
- let(:json) { %{{"key": \n/*\n this is a multiline comment \n*/\n "value"}} }
116
-
117
- context "when allow_comments is false" do
118
- let(:options) { { allow_comments: false } }
119
-
120
- it "should not parse" do
121
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
122
- end
123
- end
124
-
125
- context "when allow_comments is true" do
126
- let(:options) { { allow_comments: true } }
127
-
128
- it "should parse" do
129
- expect(parser).to eq("key" => "value")
130
- end
131
- end
132
- end
133
-
134
- context "when json has inline comments" do
135
- let(:json) { %{{"key": \n// this is an inline comment\n "value"}} }
136
-
137
- context "when allow_comments is false" do
138
- let(:options) { { allow_comments: false } }
139
-
140
- it "should not parse" do
141
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
142
- end
143
- end
144
-
145
- context "when allow_comments is true" do
146
- let(:options) { { allow_comments: true } }
147
-
148
- it "should parse" do
149
- expect(parser).to eq("key" => "value")
150
- end
151
- end
152
- end
153
-
154
- context "when json is invalid UTF8" do
155
- let(:json) { "[\"\201\203\"]" }
156
-
157
- it "should not parse by default" do
158
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
159
- end
160
-
161
- context "when :dont_validate_strings is set to true" do
162
- let(:options) { { dont_validate_strings: true } }
163
-
164
- it "should parse" do
165
- expect(parser).to eq(["\x81\x83"])
166
- end
167
- end
168
-
169
- context "when :dont_validate_strings is set to false" do
170
- let(:options) { { dont_validate_strings: false } }
171
-
172
- it "should not parse" do
173
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
174
- end
175
- end
176
-
177
- context "when :check_utf8 is set to true" do
178
- let(:options) { { check_utf8: true } }
179
-
180
- it "should not parse" do
181
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
182
- end
183
-
184
- context "when :dont_validate_strings is set to true" do
185
- let(:options) { { check_utf8: true, dont_validate_strings: true } }
186
-
187
- it "should raise an ArgumentError" do
188
- expect { parser }.to raise_error(ArgumentError)
189
- end
190
- end
191
-
192
- context "when :dont_validate_strings is set to false" do
193
- let(:options) { { check_utf8: true, dont_validate_strings: false } }
194
-
195
- it "should not parse" do
196
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
197
- end
198
- end
199
- end
200
-
201
- context "when :check_utf8 is set to false" do
202
- let(:options) { { check_utf8: false } }
203
-
204
- it "should parse" do
205
- expect(parser).to eq(["\x81\x83"])
206
- end
207
-
208
- context "when :dont_validate_strings is set to true" do
209
- let(:options) { { check_utf8: false, dont_validate_strings: true } }
210
-
211
- it "should parse" do
212
- expect(parser).to eq(["\x81\x83"])
213
- end
214
- end
215
-
216
- context "when :dont_validate_strings is set to false" do
217
- let(:options) { { check_utf8: false, dont_validate_strings: false } }
218
-
219
- it "should raise an ArgumentError" do
220
- expect { parser }.to raise_error(ArgumentError)
221
- end
222
- end
223
- end
224
- end
225
-
226
- context "when JSON is a StringIO" do
227
- let(:json) { StringIO.new('{"key": 1234}') }
228
-
229
- it "should parse" do
230
- expect(parser).to eq("key" => 1234)
231
- end
232
- end
233
-
234
- context "when parsing a JSON string" do
235
- let(:json) { '{"key": 1234}' }
236
-
237
- it "should parse correctly" do
238
- expect(parser).to eq("key" => 1234)
239
- end
240
-
241
- context "when symbolize_keys is true" do
242
- let(:options) { { symbolize_keys: true } }
243
-
244
- it "should symbolize keys correctly" do
245
- expect(parser).to eq(key: 1234)
246
- end
247
- end
248
-
249
- context "when passing a block" do
250
- it "should parse correctly" do
251
- skip "handle blocks"
252
- output = nil
253
- parser do |obj|
254
- output = obj
255
- end
256
- expect(output).to eq("key" => 1234)
257
- end
258
- end
259
- end
260
-
261
- context "when parsing a JSON hash with only strings" do
262
- let(:json) { '{"key": "value"}' }
263
-
264
- if RUBY_VERSION.to_f >= 1.9
265
- context "when Encoding.default_internal is nil" do
266
- before do
267
- @saved_encoding = Encoding.default_internal
268
- Encoding.default_internal = nil
269
- end
270
- after do
271
- Encoding.default_internal = @saved_encoding
272
- end
273
- it "encodes keys to UTF-8" do
274
- expect(parser.keys.first.encoding).to eql(Encoding.find('utf-8'))
275
- end
276
- it "encodes values to UTF-8" do
277
- expect(parser.values.first.encoding).to eql(Encoding.find('utf-8'))
278
- end
279
- end
280
-
281
- %w{utf-8 us-ascii}.each do |encoding|
282
- context "when Encoding.default_internal is #{encoding}" do
283
- before do
284
- @saved_encoding = Encoding.default_internal
285
- Encoding.default_internal = nil
286
- end
287
- after do
288
- Encoding.default_internal = @saved_encoding
289
- end
290
- it "encodes keys to #{encoding}" do
291
- skip "fix us-ascii" if encoding == "us-ascii"
292
- expect(parser.keys.first.encoding).to eql(Encoding.find(encoding))
293
- end
294
- it "encodes values to #{encoding}" do
295
- skip "fix us-ascii" if encoding == "us-ascii"
296
- expect(parser.values.first.encoding).to eql(Encoding.find(encoding))
297
- end
298
- end
299
- end
300
- end
301
- end
302
-
303
- context "when a parsed key has utf-8 multibyte characters" do
304
- let(:json) { '{"日本語": 1234}' }
305
-
306
- it "should parse correctly" do
307
- expect(parser).to eq("日本語" => 1234)
308
- end
309
-
310
- context "when symbolize_keys is true" do
311
- let(:options) { { symbolize_keys: true } }
312
-
313
- it "should symbolize keys correctly" do
314
- expect(parser).to eq(:"日本語" => 1234) # rubocop:disable Style/HashSyntax
315
- end
316
-
317
- if RUBY_VERSION.to_f >= 1.9
318
- it "should parse non-ascii symbols in UTF-8" do
319
- expect(parser.keys.fetch(0).encoding).to eq(Encoding::UTF_8)
320
- end
321
- end
322
- end
323
- end
324
-
325
- context "when parsing 2147483649" do
326
- let(:json) { "{\"id\": 2147483649}" }
327
-
328
- it "should parse corectly" do
329
- expect(parser).to eql("id" => 2_147_483_649)
330
- end
331
- end
332
-
333
- context "when parsing 5687389800" do
334
- let(:json) { "{\"id\": 5687389800}" }
335
-
336
- it "should parse corectly" do
337
- expect(parser).to eql("id" => 5_687_389_800)
338
- end
339
- end
340
-
341
- context "when parsing 1046289770033519442869495707521600000000" do
342
- let(:json) { "{\"id\": 1046289770033519442869495707521600000000}" }
343
-
344
- it "should parse corectly" do
345
- expect(parser).to eql("id" => 1_046_289_770_033_519_442_869_495_707_521_600_000_000)
346
- end
347
- end
348
-
349
- # NOTE: we are choosing to be compatible with yajl-ruby here vs. JSON
350
- # gem and libyajl C behavior (which is to throw an exception in this case)
351
- context "when the JSON is empty string" do
352
- let(:json) { '' }
353
-
354
- it "returns nil" do
355
- expect(parser).to be_nil
356
- end
357
- end
358
-
359
- # NOTE: this fixes yajl-ruby being too permissive
360
- context "when dealing with too much or too little input" do
361
- context "when trailing braces are missing" do
362
- let(:json) { '{"foo":{"foo": 1234}' }
363
-
364
- it "raises an exception" do
365
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
366
- end
367
- end
368
-
369
- context "when trailing brackets are missing" do
370
- let(:json) { '[["foo", "bar"]' }
371
-
372
- it "raises an exception" do
373
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
374
- end
375
- end
376
-
377
- context "when an extra brace is present" do
378
- let(:json) { '{"foo":{"foo": 1234}}}' }
379
-
380
- it "raises an exception" do
381
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
382
- end
383
-
384
- context "with allow_trailing_garbage" do
385
- let(:options) { { allow_trailing_garbage: true } }
386
- it "parses" do
387
- expect(parser).to eq("foo" => { "foo" => 1234 })
388
- end
389
- end
390
- end
391
-
392
- context "when an extra bracket is present" do
393
- let(:json) { '[["foo", "bar"]]]' }
394
-
395
- it "raises an exception" do
396
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
397
- end
398
- end
399
- end
400
-
401
- context "when parsing heavy metal umlauts in keys" do
402
- let(:json) { '{"München": "Bayern"}' }
403
-
404
- it "correctly parses" do
405
- expect(parser).to eql( "München" => "Bayern" )
406
- end
407
- end
408
-
409
- context "when parsing floats" do
410
- context "parses simple floating point values" do
411
- let(:json) { '{"foo": 3.14159265358979}' }
412
-
413
- it "correctly parses" do
414
- expect(parser).to eql( "foo" => 3.14159265358979 )
415
- end
416
- end
417
-
418
- context "parses simple negative floating point values" do
419
- let(:json) { '{"foo":-2.00231930436153}' }
420
-
421
- it "correctly parses" do
422
- expect(parser).to eql( "foo" => -2.00231930436153 )
423
- end
424
- end
425
-
426
- context "parses floats with negative exponents and a large E" do
427
- let(:json) { '{"foo": 1.602176565E-19}' }
428
-
429
- it "correctly parses" do
430
- expect(parser).to eql( "foo" => 1.602176565e-19 )
431
- end
432
- end
433
-
434
- context "parses floats with negative exponents and a small e" do
435
- let(:json) { '{"foo": 6.6260689633e-34 }' }
436
-
437
- it "correctly parses" do
438
- expect(parser).to eql( "foo" => 6.6260689633e-34 )
439
- end
440
- end
441
-
442
- context "parses floats with positive exponents and a large E" do
443
- let(:json) { '{"foo": 6.0221413E+23}' }
444
-
445
- it "correctly parses" do
446
- expect(parser).to eql( "foo" => 6.0221413e+23 )
447
- end
448
- end
449
-
450
- context "parses floats with positive exponents and a small e" do
451
- let(:json) { '{"foo": 8.9875517873681764e+9 }' }
452
-
453
- it "correctly parses" do
454
- expect(parser).to eql( "foo" => 8.9875517873681764e+9 )
455
- end
456
- end
457
-
458
- context "parses floats with an exponent without a sign and a large E" do
459
- let(:json) { '{"foo": 2.99792458E8 }' }
460
-
461
- it "correctly parses" do
462
- expect(parser).to eql( "foo" => 2.99792458e+8 )
463
- end
464
- end
465
-
466
- context "parses floats with an exponent without a sign and a small e" do
467
- let(:json) { '{"foo": 1.0973731568539e7 }' }
468
-
469
- it "correctly parses" do
470
- expect(parser).to eql( "foo" => 1.0973731568539e+7 )
471
- end
472
- end
473
- end
474
-
475
- # NOTE: parsing floats with 8 million digits on windows has some kind of huge
476
- # perf issues likely in ruby and/or the underlying windows libs
477
- context "when parsing big floats", ruby_gte_193: true, unix_only: true do
478
- let(:json) { '[0.' + '1' * 2**23 + ']' }
479
-
480
- it "parses" do
481
- expect { parser }.not_to raise_error
482
- end
483
- end
484
-
485
- context "when parsing long hash keys with symbolize_keys option", ruby_gte_193: true do
486
- let(:json) { '{"' + 'a' * 2**23 + '": 0}' }
487
- let(:options) { { symbolize_keys: true } }
488
-
489
- it "parses" do
490
- expect { parser }.not_to raise_error
491
- end
492
- end
493
-
494
- context "should ignore repeated keys by default" do
495
- let(:json) { '{"foo":"bar","foo":"baz"}' }
496
- it "should replace the first hash key with the second" do
497
- expect(parser).to eql( "foo" => "baz" )
498
- end
499
- end
500
-
501
- context "should raise an exception for repeated keys" do
502
- let(:json) { '{"foo":"bar","foo":"baz"}' }
503
- let(:options) { { unique_key_checking: true } }
504
- it "should raise" do
505
- expect { parser }.to raise_error(FFI_Yajl::ParseError)
506
- end
507
- end
508
- end
509
-
510
- context "when options are set to empty hash" do
511
- let(:options) { {} }
512
-
513
- context "when using a parsing object" do
514
- let(:parser) { FFI_Yajl::Parser.new(options).parse(json) }
515
-
516
- it_behaves_like "correct json parsing"
517
- end
518
-
519
- context "when using the class method" do
520
- let(:parser) { FFI_Yajl::Parser.parse(json, options) }
521
-
522
- it_behaves_like "correct json parsing"
523
- end
524
- end
525
-
526
- context "when options are set to nil" do
527
- let(:options) { nil }
528
-
529
- context "when using a parsing object" do
530
- let(:parser) { FFI_Yajl::Parser.new(options).parse(json) }
531
-
532
- it_behaves_like "correct json parsing"
533
- end
534
-
535
- context "when using the class method" do
536
- let(:parser) { FFI_Yajl::Parser.parse(json, options) }
537
-
538
- it_behaves_like "correct json parsing"
539
- end
540
- end
541
-
542
- context "when options default to nothing" do
543
- let(:options) { nil }
544
-
545
- context "when using a parsing object" do
546
- let(:parser) do
547
- if options.nil?
548
- FFI_Yajl::Parser.new.parse(json)
549
- else
550
- FFI_Yajl::Parser.new(options).parse(json)
551
- end
552
- end
553
-
554
- it_behaves_like "correct json parsing"
555
- end
556
-
557
- context "when using the class method" do
558
- let(:parser) do
559
- if options.nil?
560
- FFI_Yajl::Parser.parse(json)
561
- else
562
- FFI_Yajl::Parser.parse(json, options)
563
- end
564
- end
565
-
566
- it_behaves_like "correct json parsing"
567
- end
568
- end
569
- end