yajl-ruby 1.3.1 → 1.4.2

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.

Potentially problematic release.


This version of yajl-ruby might be problematic. Click here for more details.

@@ -0,0 +1,498 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+
3
+ require 'stringio'
4
+ require 'json'
5
+
6
+ describe "projection" do
7
+ it "should work" do
8
+ stream = StringIO.new('{"name": "keith", "age": 27}')
9
+ projector = Yajl::Projector.new(stream)
10
+ projection = projector.project({"name" => nil})
11
+ expect(projection['name']).to eql("keith")
12
+ end
13
+
14
+ it "should filter" do
15
+ stream = StringIO.new('{"name": "keith", "age": 27}')
16
+ projector = Yajl::Projector.new(stream)
17
+ projection = projector.project({"name" => nil})
18
+ expect(projection['age']).to eql(nil)
19
+ end
20
+
21
+ it "should raise an exception and not leak memory" do
22
+ stream = StringIO.new('foo')
23
+ projector = Yajl::Projector.new(stream)
24
+ expect {
25
+ projector.project({"name" => nil})
26
+ }.to raise_error(Yajl::ParseError)
27
+ end
28
+
29
+ it "should raise an exception and not segv" do
30
+ stream = StringIO.new('[,,,,]')
31
+ projector = Yajl::Projector.new(stream)
32
+ expect {
33
+ projector.project({"name" => nil})
34
+ }.to raise_error(Yajl::ParseError)
35
+ end
36
+
37
+ it "should raise an exception and not segv on colons" do
38
+ stream = StringIO.new('[::::]')
39
+ projector = Yajl::Projector.new(stream)
40
+ expect {
41
+ projector.project({"name" => nil})
42
+ }.to raise_error(Yajl::ParseError)
43
+ end
44
+
45
+ it "should behave the same way as the regular parser on bad tokens like comma" do
46
+ bad_json = '{"name": "keith", "age":, 27}'
47
+ stream = StringIO.new(bad_json)
48
+ projector = Yajl::Projector.new(stream)
49
+ expect {
50
+ projector.project({"name" => nil})
51
+ }.to raise_error(capture_exception_for(bad_json).class)
52
+ end
53
+
54
+ it "should behave the same way as the regular parser on bad tokens like colon" do
55
+ bad_json = '{"name": "keith", "age":: 27}'
56
+ stream = StringIO.new(bad_json)
57
+ projector = Yajl::Projector.new(stream)
58
+ expect {
59
+ projector.project({"name" => nil})
60
+ }.to raise_error(capture_exception_for(bad_json).class)
61
+ end
62
+
63
+ it "should behave the same way as the regular parser on not enough json" do
64
+ bad_json = '{"name": "keith", "age":'
65
+ stream = StringIO.new(bad_json)
66
+ projector = Yajl::Projector.new(stream)
67
+ expect {
68
+ projector.project({"name" => nil})
69
+ }.to raise_error(capture_exception_for(bad_json).class)
70
+ end
71
+
72
+ def capture_exception_for(bad_json)
73
+ Yajl::Parser.new.parse(bad_json)
74
+ rescue Exception => e
75
+ e
76
+ end
77
+
78
+ def project(schema, over: "", json: nil, stream: nil)
79
+ if stream.nil?
80
+ if json.nil?
81
+ json = over.to_json
82
+ end
83
+
84
+ stream = StringIO.new(json)
85
+ end
86
+
87
+ Yajl::Projector.new(stream).project(schema)
88
+ end
89
+
90
+ it "filters arrays" do
91
+ json = {
92
+ "users" => [
93
+ {
94
+ "name" => "keith",
95
+ "company" => "internet plumbing inc",
96
+ "department" => "janitorial",
97
+ },
98
+ {
99
+ "name" => "justin",
100
+ "company" => "big blue",
101
+ "department" => "programming?",
102
+ },
103
+ {
104
+ "name" => "alan",
105
+ "company" => "different colour of blue",
106
+ "department" => "drop bear containment",
107
+ }
108
+ ]
109
+ }.to_json
110
+
111
+ puts json
112
+
113
+ schema = {
114
+ # /users is an array of objects, each having many keys we only want name
115
+ "users" => {
116
+ "name" => nil,
117
+ }
118
+ }
119
+
120
+ expect(project(schema, json: json)).to eql({
121
+ "users" => [
122
+ { "name" => "keith" },
123
+ { "name" => "justin" },
124
+ { "name" => "alan" }
125
+ ]
126
+ })
127
+ end
128
+
129
+ it "filters top level arrays" do
130
+ json = [
131
+ {
132
+ "name" => "keith",
133
+ "personal detail" => "thing",
134
+ },
135
+ {
136
+ "name" => "cory",
137
+ "phone number" => "unknown",
138
+ }
139
+ ]
140
+
141
+ schema = {
142
+ "name" => nil,
143
+ }
144
+
145
+ expect(project(schema, over: json)).to eql([
146
+ { "name" => "keith" },
147
+ { "name" => "cory" },
148
+ ])
149
+ end
150
+
151
+ it "filters nested schemas" do
152
+ json = {
153
+ "foo" => 42,
154
+
155
+ "bar" => {
156
+ "name" => "keith",
157
+ "occupation" => "professional computering",
158
+ "age" => 26,
159
+ "hobbies" => [
160
+ "not computering",
161
+ ]
162
+ },
163
+
164
+ "qux" => {
165
+ "quux" => [
166
+ {
167
+ "name" => "Reactive X",
168
+ "members" => "many",
169
+ },
170
+ {
171
+ "name" => "lstoll",
172
+ "members" => "such",
173
+ },
174
+ {
175
+ "name" => "github",
176
+ "members" => "very",
177
+ },
178
+ {
179
+ "name" => "theleague",
180
+ "members" => "numerous",
181
+ }
182
+ ],
183
+
184
+ "corge" => {
185
+ "name" => "Brighton",
186
+ "address" =>"Buckingham Road",
187
+ },
188
+ },
189
+
190
+ "grault" => nil,
191
+
192
+ "waldo" => true,
193
+ }
194
+
195
+ schema = {
196
+ # include the /foo subtree (is a single number)
197
+ "foo" => nil,
198
+
199
+ # ignore the bar subtree (is an object)
200
+ # "bar" => ???
201
+
202
+ # include some of the /qux subtree (is an object)
203
+ "qux" => {
204
+ # include the whole /qux/quux subtree (is an array of objects)
205
+ "quux" => nil,
206
+
207
+ # include some of the /qux/corge subtree (is another object)
208
+ "corge" => {
209
+ # include name (is a string)
210
+ "name" => nil,
211
+ # include age (is missing from source doc)
212
+ "age" => nil,
213
+ # ignore address
214
+ # "address" => ???
215
+ },
216
+ },
217
+
218
+ # include the /grault subtree (is a null literal)
219
+ "grault" => nil,
220
+
221
+ # include the /waldo subtree (is a boolean literal)
222
+ "waldo" => nil,
223
+ }
224
+
225
+ expect(project(schema, over: json)).to eql({
226
+ "foo" => 42,
227
+
228
+ "qux" => {
229
+ "quux" => [
230
+ {
231
+ "name" => "Reactive X",
232
+ "members" => "many",
233
+ },
234
+ {
235
+ "name" => "lstoll",
236
+ "members" => "such",
237
+ },
238
+ {
239
+ "name" => "github",
240
+ "members" => "very",
241
+ },
242
+ {
243
+ "name" => "theleague",
244
+ "members" => "numerous",
245
+ }
246
+ ],
247
+
248
+ "corge" => {
249
+ "name" => "Brighton",
250
+ },
251
+ },
252
+
253
+ "grault" => nil,
254
+
255
+ "waldo" => true,
256
+ })
257
+ end
258
+
259
+ it "supports incompatible schemas" do
260
+ json = {
261
+ # surprise! the json doesn't include an object under the foo key
262
+ "foo" => 42,
263
+ }
264
+
265
+ schema = {
266
+ # include some of the /foo subtree
267
+ "foo" => {
268
+ # include the whole /foo/baz subtree
269
+ "baz" => nil,
270
+ }
271
+ }
272
+
273
+ # expect the 42 to be pulled out
274
+ expect(project(schema, over: json)).to eql({
275
+ "foo" => 42
276
+ })
277
+ end
278
+
279
+ it "supports nil schema" do
280
+ json = {
281
+ "foo" => "bar",
282
+ }
283
+
284
+ expect(project(nil, over: json)).to eql({
285
+ "foo" => "bar"
286
+ })
287
+ end
288
+
289
+ it "supports empty schema" do
290
+ json = {
291
+ "foo" => "bar",
292
+ }
293
+ expect(project({}, over: json)).to eql({})
294
+ end
295
+
296
+ it "supports object projection" do
297
+ json = {
298
+ "foo" => "bar",
299
+ "qux" => "quux",
300
+ }
301
+
302
+ schema = {
303
+ "foo" => nil,
304
+ }
305
+
306
+ expect(project(schema, over: json)).to eql({
307
+ "foo" => "bar"
308
+ })
309
+ end
310
+
311
+ it "projects the readme example" do
312
+ json = <<-EOJ
313
+ [
314
+ {
315
+ "user": {
316
+ "name": "keith",
317
+ "age": 26,
318
+ "jobs": [
319
+ {
320
+ "title": "director of overworking",
321
+ "company": "south coast software",
322
+ "department": "most"
323
+ },
324
+ {
325
+ "title": "some kind of computering",
326
+ "company": "github the website dot com",
327
+ "department": true
328
+ }
329
+ ]
330
+ },
331
+ "another key": {
332
+
333
+ },
334
+ "woah this document is huge": {
335
+
336
+ },
337
+ "many megabytes": {
338
+
339
+ },
340
+ "etc": {
341
+
342
+ }
343
+ }
344
+ ]
345
+ EOJ
346
+
347
+ schema = {
348
+ "user" => {
349
+ "name" => nil,
350
+ "jobs" => {
351
+ "title" => nil,
352
+ },
353
+ },
354
+ }
355
+
356
+ expect(project(schema, json: json)).to eql([{
357
+ "user" => {
358
+ "name" => "keith",
359
+ "jobs" => [
360
+ { "title" => "director of overworking" },
361
+ { "title" => "some kind of computering" },
362
+ ]
363
+ }
364
+ }])
365
+ end
366
+
367
+ it "errors with invalid json" do
368
+ expect {
369
+ project({"b" => nil}, json: '{"a":, "b": 2}')
370
+ }.to raise_error(StandardError)
371
+ end
372
+
373
+ it "errors with ignored unbalanced object syntax" do
374
+ expect {
375
+ project({"b" => nil}, json: '{"a": {{, "b": 2}')
376
+ }.to raise_error(StandardError)
377
+ end
378
+
379
+ it "errors with accepted unbalanced object tokens" do
380
+ expect {
381
+ project({"a" => nil}, json: '{"a": {"b": 2}')
382
+ }.to raise_error(Yajl::ParseError)
383
+ end
384
+
385
+ it "errors when projecting if an object comma is missing" do
386
+ expect {
387
+ project({"a" => nil}, json: '{"a": 1 "b": 2}')
388
+ }.to raise_error(Yajl::ParseError)
389
+ end
390
+
391
+ it "errors when building if an object comma is missing" do
392
+ expect {
393
+ project(nil, json: '{"a": {"b": 2 "c": 3}}')
394
+ }.to raise_error(Yajl::ParseError)
395
+ end
396
+
397
+ it "errors when eof instead of simple value" do
398
+ expect {
399
+ project(nil, json: '[')
400
+ }.to raise_error(Yajl::ParseError)
401
+ end
402
+
403
+ it "errors when arrays don't have a comma between elements" do
404
+ expect {
405
+ project(nil, json: '[1 2]')
406
+ }.to raise_error(Yajl::ParseError)
407
+ end
408
+
409
+ it "supports parsing empty array" do
410
+ expect(project(nil, json: '[]')).to eql([])
411
+ end
412
+
413
+ it "supports parsing empty object" do
414
+ expect(project(nil, json: '{}')).to eql({})
415
+ end
416
+
417
+ it "reads a full buffer" do
418
+ json = "[" + "1,"*2046 + "1 ]"
419
+ expect(json.size).to eql(4096)
420
+ expect(project(nil, json: json)).to eql(Array.new(2047, 1))
421
+ end
422
+
423
+ it "reads into a second buffer" do
424
+ json = "[" + "1,"*2047 + "1 ]"
425
+ expect(json.size).to eql(4098)
426
+ expect(JSON.parse(json)).to eql(Array.new(2048, 1))
427
+ expect(project(nil, json: json)).to eql(Array.new(2048, 1))
428
+ end
429
+
430
+ it "supports parsing big strings" do
431
+ json = [
432
+ "a",
433
+ "b"*10_000,
434
+ "c",
435
+ ]
436
+ expect(project(nil, over: json)).to eql(json)
437
+ end
438
+
439
+ it "supports bigger read buffers" do
440
+ json = {
441
+ "a"*10_000 => "b"*10_000
442
+ }.to_json
443
+ stream = StringIO.new(json)
444
+ expect(Yajl::Projector.new(stream, 8192).project(nil)).to have_key("a"*10_000)
445
+ end
446
+
447
+ it "errors if starting with closing object" do
448
+ expect {
449
+ project(nil, json: '}')
450
+ }.to raise_error(Yajl::ParseError)
451
+ end
452
+
453
+ it "handles objects with utf16 escape sequences as keys" do
454
+ projection = project(nil, json: '{"\ud83d\ude00": "grinning face"}')
455
+ literal = {"😀" => "grinning face"}
456
+ expect(projection).to eql(literal)
457
+ end
458
+
459
+ it "handles objects with non-ascii utf8 bytes as keys" do
460
+ expect(project(nil, json: '{"😀": "grinning face"}')).to eql({"😀" => "grinning face"})
461
+ end
462
+
463
+ it "handles strings with utf16 escape sequences as object values" do
464
+ expect(project(nil, json: '{"grinning face": "\ud83d\ude00"}')).to eql({"grinning face" => "😀"})
465
+ end
466
+
467
+ it "handles strings with utf16 escape sequences as array values" do
468
+ projection = project(nil, json: '["\ud83d\ude00"]')
469
+ puts projection.first.inspect
470
+ puts projection.first.bytes
471
+
472
+ literal = ["😀"]
473
+ puts literal.first.inspect
474
+ puts literal.first.bytes
475
+
476
+ expect(projection).to eql(literal)
477
+ end
478
+
479
+ it "handles strings with non-ascii utf8 bytes as array values" do
480
+ projection = project(nil, json: '["😀"]')
481
+ puts projection.first.inspect
482
+ puts projection.first.bytes
483
+
484
+ literal = ["😀"]
485
+ puts literal.first.inspect
486
+ puts literal.first.bytes
487
+
488
+ expect(projection).to eql(literal)
489
+ end
490
+
491
+ it "ignores strings with utf16 escape sequences" do
492
+ expect(project({"grinning face with open mouth" => nil}, json: '{"grinning face": "\ud83d\ude00", "grinning face with open mouth": "\ud83d\ude03"}')).to eql({"grinning face with open mouth" => "😃"})
493
+ end
494
+
495
+ it "handles objects whose second key has escape sequences" do
496
+ expect(project(nil, json: '{"foo": "bar", "\ud83d\ude00": "grinning face"}')).to eql({"foo" => "bar", "😀" => "grinning face"})
497
+ end
498
+ end
data/yajl-ruby.gemspec CHANGED
@@ -14,13 +14,13 @@ Gem::Specification.new do |s|
14
14
  s.rubygems_version = %q{1.4.2}
15
15
  s.summary = %q{Ruby C bindings to the excellent Yajl JSON stream-based parser library.}
16
16
  s.test_files = `git ls-files spec examples`.split("\n")
17
- s.required_ruby_version = ">= 1.8.6"
17
+ s.required_ruby_version = ">= 2.6.0"
18
18
 
19
19
  # tests
20
- s.add_development_dependency 'rake-compiler', '>= 0.7.5'
21
- s.add_development_dependency 'rspec', '~> 3.0'
20
+ s.add_development_dependency 'rake-compiler'
21
+ s.add_development_dependency 'rspec'
22
22
  # benchmarks
23
- s.add_development_dependency 'activesupport', '~> 3.1.2'
23
+ s.add_development_dependency 'activesupport'
24
24
  s.add_development_dependency 'json'
25
+ s.add_development_dependency "benchmark-memory"
25
26
  end
26
-
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yajl-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Lopez
8
8
  - Lloyd Hilaiel
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-11-07 00:00:00.000000000 Z
12
+ date: 2022-04-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
@@ -17,42 +17,42 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: 0.7.5
20
+ version: '0'
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: 0.7.5
27
+ version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rspec
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: '3.0'
34
+ version: '0'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: '3.0'
41
+ version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: activesupport
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - "~>"
46
+ - - ">="
47
47
  - !ruby/object:Gem::Version
48
- version: 3.1.2
48
+ version: '0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - "~>"
53
+ - - ">="
54
54
  - !ruby/object:Gem::Version
55
- version: 3.1.2
55
+ version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: json
58
58
  requirement: !ruby/object:Gem::Requirement
@@ -67,7 +67,21 @@ dependencies:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
- description:
70
+ - !ruby/object:Gem::Dependency
71
+ name: benchmark-memory
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description:
71
85
  email: seniorlopez@gmail.com
72
86
  executables: []
73
87
  extensions:
@@ -75,9 +89,9 @@ extensions:
75
89
  extra_rdoc_files: []
76
90
  files:
77
91
  - ".codeclimate.yml"
92
+ - ".github/workflows/ci.yml"
78
93
  - ".gitignore"
79
94
  - ".rspec"
80
- - ".travis.yml"
81
95
  - CHANGELOG.md
82
96
  - Gemfile
83
97
  - LICENSE
@@ -221,6 +235,8 @@ files:
221
235
  - spec/parsing/fixtures_spec.rb
222
236
  - spec/parsing/large_number_spec.rb
223
237
  - spec/parsing/one_off_spec.rb
238
+ - spec/projection/project_file.rb
239
+ - spec/projection/projection.rb
224
240
  - spec/rcov.opts
225
241
  - spec/spec_helper.rb
226
242
  - tasks/compile.rake
@@ -230,7 +246,7 @@ homepage: http://github.com/brianmario/yajl-ruby
230
246
  licenses:
231
247
  - MIT
232
248
  metadata: {}
233
- post_install_message:
249
+ post_install_message:
234
250
  rdoc_options: []
235
251
  require_paths:
236
252
  - lib
@@ -238,16 +254,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
238
254
  requirements:
239
255
  - - ">="
240
256
  - !ruby/object:Gem::Version
241
- version: 1.8.6
257
+ version: 2.6.0
242
258
  required_rubygems_version: !ruby/object:Gem::Requirement
243
259
  requirements:
244
260
  - - ">="
245
261
  - !ruby/object:Gem::Version
246
262
  version: '0'
247
263
  requirements: []
248
- rubyforge_project:
249
- rubygems_version: 2.6.11
250
- signing_key:
264
+ rubygems_version: 3.3.3
265
+ signing_key:
251
266
  specification_version: 4
252
267
  summary: Ruby C bindings to the excellent Yajl JSON stream-based parser library.
253
268
  test_files:
@@ -337,5 +352,7 @@ test_files:
337
352
  - spec/parsing/fixtures_spec.rb
338
353
  - spec/parsing/large_number_spec.rb
339
354
  - spec/parsing/one_off_spec.rb
355
+ - spec/projection/project_file.rb
356
+ - spec/projection/projection.rb
340
357
  - spec/rcov.opts
341
358
  - spec/spec_helper.rb
data/.travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.0.0
4
- - 2.1
5
- - 2.2
6
- - 2.3
7
- - 2.4.1
8
- - ruby-head
9
- before_install: gem install bundler --no-document