oj 3.12.0 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ $: << File.dirname(__FILE__)
5
+
6
+ require 'helper'
7
+
8
+ class UsualTest < Minitest::Test
9
+
10
+ def test_nil
11
+ p = Oj::Parser.new(:usual)
12
+ doc = p.parse('nil')
13
+ assert_nil(doc)
14
+ end
15
+
16
+ def test_primitive
17
+ p = Oj::Parser.new(:usual)
18
+ [
19
+ ['true', true],
20
+ ['false', false],
21
+ ['123', 123],
22
+ ['1.25', 1.25],
23
+ ['"abc"', 'abc'],
24
+ ].each { |x|
25
+ doc = p.parse(x[0])
26
+ assert_equal(x[1], doc)
27
+ }
28
+ end
29
+
30
+ def test_big
31
+ p = Oj::Parser.new(:usual)
32
+ doc = p.parse('12345678901234567890123456789')
33
+ assert_equal(BigDecimal, doc.class)
34
+ doc = p.parse('1234567890.1234567890123456789')
35
+ assert_equal(BigDecimal, doc.class)
36
+ end
37
+
38
+ def test_array
39
+ p = Oj::Parser.new(:usual)
40
+ [
41
+ ['[]', []],
42
+ ['[false]', [false]],
43
+ ['[true,false]', [true,false]],
44
+ ['[[]]', [[]]],
45
+ ['[true,[],false]', [true,[],false]],
46
+ ['[true,[true],false]', [true,[true],false]],
47
+ ].each { |x|
48
+ doc = p.parse(x[0])
49
+ assert_equal(x[1], doc)
50
+ }
51
+ end
52
+
53
+ def test_hash
54
+ p = Oj::Parser.new(:usual)
55
+ [
56
+ ['{}', {}],
57
+ ['{"a": null}', {'a' => nil}],
58
+ ['{"t": true, "f": false, "s": "abc"}', {'t' => true, 'f' => false, 's' => 'abc'}],
59
+ ['{"a": {}}', {'a' => {}}],
60
+ ['{"a": {"b": 2}}', {'a' => {'b' => 2}}],
61
+ ['{"a": [true]}', {'a' => [true]}],
62
+ ].each { |x|
63
+ doc = p.parse(x[0])
64
+ assert_equal(x[1], doc)
65
+ }
66
+ end
67
+
68
+ def test_symbol_keys
69
+ p = Oj::Parser.new(:usual)
70
+ assert_equal(false, p.symbol_keys)
71
+ p.symbol_keys = true
72
+ doc = p.parse('{"a": true, "b": false}')
73
+ assert_equal({a: true, b: false}, doc)
74
+ end
75
+
76
+ def test_capacity
77
+ p = Oj::Parser.new(:usual)
78
+ p.capacity = 1000
79
+ assert_equal(4096, p.capacity)
80
+ p.capacity = 5000
81
+ assert_equal(5000, p.capacity)
82
+ end
83
+
84
+ def test_decimal
85
+ p = Oj::Parser.new(:usual)
86
+ assert_equal(:auto, p.decimal)
87
+ doc = p.parse('1.234567890123456789')
88
+ assert_equal(BigDecimal, doc.class)
89
+ assert_equal('0.1234567890123456789e1', doc.to_s)
90
+ doc = p.parse('1.25')
91
+ assert_equal(Float, doc.class)
92
+
93
+ p.decimal = :float
94
+ assert_equal(:float, p.decimal)
95
+ doc = p.parse('1.234567890123456789')
96
+ assert_equal(Float, doc.class)
97
+
98
+ p.decimal = :bigdecimal
99
+ assert_equal(:bigdecimal, p.decimal)
100
+ doc = p.parse('1.234567890123456789')
101
+ assert_equal(BigDecimal, doc.class)
102
+ doc = p.parse('1.25')
103
+ assert_equal(BigDecimal, doc.class)
104
+ assert_equal('0.125e1', doc.to_s)
105
+
106
+ p.decimal = :ruby
107
+ assert_equal(:ruby, p.decimal)
108
+ doc = p.parse('1.234567890123456789')
109
+ assert_equal(Float, doc.class)
110
+ end
111
+
112
+ def test_omit_null
113
+ p = Oj::Parser.new(:usual)
114
+ p.omit_null = true
115
+ doc = p.parse('{"a":true,"b":null}')
116
+ assert_equal({'a'=>true}, doc)
117
+
118
+ p.omit_null = false
119
+ doc = p.parse('{"a":true,"b":null}')
120
+ assert_equal({'a'=>true, 'b'=>nil}, doc)
121
+ end
122
+
123
+ class MyArray < Array
124
+ end
125
+
126
+ def test_array_class
127
+ p = Oj::Parser.new(:usual)
128
+ p.array_class = MyArray
129
+ assert_equal(MyArray, p.array_class)
130
+ doc = p.parse('[true]')
131
+ assert_equal(MyArray, doc.class)
132
+ end
133
+
134
+ class MyHash < Hash
135
+ end
136
+
137
+ def test_hash_class
138
+ p = Oj::Parser.new(:usual)
139
+ p.hash_class = MyHash
140
+ assert_equal(MyHash, p.hash_class)
141
+ doc = p.parse('{"a":true}')
142
+ assert_equal(MyHash, doc.class)
143
+ end
144
+
145
+ class MyClass
146
+ attr_accessor :a
147
+ attr_accessor :b
148
+
149
+ def to_s
150
+ "#{self.class}{a: #{@a} b: #{b}}"
151
+ end
152
+ end
153
+
154
+ class MyClass2 < MyClass
155
+ def self.json_create(arg)
156
+ obj = new
157
+ obj.a = arg['a']
158
+ obj.b = arg['b']
159
+ obj
160
+ end
161
+ end
162
+
163
+ def test_create_id
164
+ p = Oj::Parser.new(:usual)
165
+ p.create_id = '^'
166
+ doc = p.parse('{"a":true}')
167
+ assert_equal(Hash, doc.class)
168
+ doc = p.parse('{"a":true,"^":"UsualTest::MyClass","b":false}')
169
+ assert_equal('UsualTest::MyClass{a: true b: false}', doc.to_s)
170
+
171
+ doc = p.parse('{"a":true,"^":"UsualTest::MyClass2","b":false}')
172
+ assert_equal('UsualTest::MyClass2{a: true b: false}', doc.to_s)
173
+
174
+ p.hash_class = MyHash
175
+ assert_equal(MyHash, p.hash_class)
176
+ doc = p.parse('{"a":true}')
177
+ assert_equal(MyHash, doc.class)
178
+
179
+ doc = p.parse('{"a":true,"^":"UsualTest::MyClass","b":false}')
180
+ assert_equal('UsualTest::MyClass{a: true b: false}', doc.to_s)
181
+ end
182
+
183
+ def test_missing_class
184
+ p = Oj::Parser.new(:usual)
185
+ p.create_id = '^'
186
+ json = '{"a":true,"^":"Auto","b":false}'
187
+ doc = p.parse(json)
188
+ assert_equal(Hash, doc.class)
189
+
190
+ p.missing_class = :auto
191
+ doc = p.parse(json)
192
+ # Auto should be defined after parsing
193
+ assert_equal(Auto, doc.class)
194
+ end
195
+
196
+ def test_class_cache
197
+ p = Oj::Parser.new(:usual)
198
+ p.create_id = '^'
199
+ p.class_cache = true
200
+ p.missing_class = :auto
201
+ json = '{"a":true,"^":"Auto2","b":false}'
202
+ doc = p.parse(json)
203
+ assert_equal(Auto2, doc.class)
204
+
205
+ doc = p.parse(json)
206
+ assert_equal(Auto2, doc.class)
207
+ end
208
+
209
+ def test_default_parser
210
+ doc = Oj::Parser.usual.parse('{"a":true,"b":null}')
211
+ assert_equal({'a'=>true, 'b'=>nil}, doc)
212
+ end
213
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.12.0
4
+ version: 3.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-05 00:00:00.000000000 Z
11
+ date: 2021-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -86,6 +86,7 @@ extra_rdoc_files:
86
86
  - pages/JsonGem.md
87
87
  - pages/Modes.md
88
88
  - pages/Options.md
89
+ - pages/Parser.md
89
90
  - pages/Rails.md
90
91
  - pages/Security.md
91
92
  - pages/WAB.md
@@ -93,6 +94,8 @@ files:
93
94
  - LICENSE
94
95
  - README.md
95
96
  - ext/oj/buf.h
97
+ - ext/oj/cache.c
98
+ - ext/oj/cache.h
96
99
  - ext/oj/cache8.c
97
100
  - ext/oj/cache8.h
98
101
  - ext/oj/circarray.c
@@ -101,6 +104,7 @@ files:
101
104
  - ext/oj/code.h
102
105
  - ext/oj/compat.c
103
106
  - ext/oj/custom.c
107
+ - ext/oj/debug.c
104
108
  - ext/oj/dump.c
105
109
  - ext/oj/dump.h
106
110
  - ext/oj/dump_compat.c
@@ -112,9 +116,9 @@ files:
112
116
  - ext/oj/err.h
113
117
  - ext/oj/extconf.rb
114
118
  - ext/oj/fast.c
115
- - ext/oj/hash.c
116
- - ext/oj/hash.h
117
119
  - ext/oj/hash_test.c
120
+ - ext/oj/intern.c
121
+ - ext/oj/intern.h
118
122
  - ext/oj/mimic_json.c
119
123
  - ext/oj/object.c
120
124
  - ext/oj/odd.c
@@ -123,6 +127,8 @@ files:
123
127
  - ext/oj/oj.h
124
128
  - ext/oj/parse.c
125
129
  - ext/oj/parse.h
130
+ - ext/oj/parser.c
131
+ - ext/oj/parser.h
126
132
  - ext/oj/rails.c
127
133
  - ext/oj/rails.h
128
134
  - ext/oj/reader.c
@@ -132,6 +138,7 @@ files:
132
138
  - ext/oj/rxclass.c
133
139
  - ext/oj/rxclass.h
134
140
  - ext/oj/saj.c
141
+ - ext/oj/saj2.c
135
142
  - ext/oj/scp.c
136
143
  - ext/oj/sparse.c
137
144
  - ext/oj/stream_writer.c
@@ -139,10 +146,12 @@ files:
139
146
  - ext/oj/string_writer.c
140
147
  - ext/oj/trace.c
141
148
  - ext/oj/trace.h
149
+ - ext/oj/usual.c
142
150
  - ext/oj/util.c
143
151
  - ext/oj/util.h
144
152
  - ext/oj/val_stack.c
145
153
  - ext/oj/val_stack.h
154
+ - ext/oj/validate.c
146
155
  - ext/oj/wab.c
147
156
  - lib/oj.rb
148
157
  - lib/oj/active_support_helper.rb
@@ -162,6 +171,7 @@ files:
162
171
  - pages/JsonGem.md
163
172
  - pages/Modes.md
164
173
  - pages/Options.md
174
+ - pages/Parser.md
165
175
  - pages/Rails.md
166
176
  - pages/Security.md
167
177
  - pages/WAB.md
@@ -214,6 +224,7 @@ files:
214
224
  - test/perf_fast.rb
215
225
  - test/perf_file.rb
216
226
  - test/perf_object.rb
227
+ - test/perf_parser.rb
217
228
  - test/perf_saj.rb
218
229
  - test/perf_scp.rb
219
230
  - test/perf_simple.rb
@@ -245,6 +256,9 @@ files:
245
256
  - test/test_integer_range.rb
246
257
  - test/test_null.rb
247
258
  - test/test_object.rb
259
+ - test/test_parser.rb
260
+ - test/test_parser_saj.rb
261
+ - test/test_parser_usual.rb
248
262
  - test/test_rails.rb
249
263
  - test/test_saj.rb
250
264
  - test/test_scp.rb
@@ -285,7 +299,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
285
299
  - !ruby/object:Gem::Version
286
300
  version: '0'
287
301
  requirements: []
288
- rubygems_version: 3.2.3
302
+ rubygems_version: 3.2.22
289
303
  signing_key:
290
304
  specification_version: 4
291
305
  summary: A fast JSON parser and serializer.
@@ -339,6 +353,7 @@ test_files:
339
353
  - test/perf_fast.rb
340
354
  - test/perf_file.rb
341
355
  - test/perf_object.rb
356
+ - test/perf_parser.rb
342
357
  - test/perf_saj.rb
343
358
  - test/perf_scp.rb
344
359
  - test/perf_simple.rb
@@ -370,6 +385,9 @@ test_files:
370
385
  - test/test_integer_range.rb
371
386
  - test/test_null.rb
372
387
  - test/test_object.rb
388
+ - test/test_parser.rb
389
+ - test/test_parser_saj.rb
390
+ - test/test_parser_usual.rb
373
391
  - test/test_rails.rb
374
392
  - test/test_saj.rb
375
393
  - test/test_scp.rb
data/ext/oj/hash.c DELETED
@@ -1,146 +0,0 @@
1
- // Copyright (c) 2011 Peter Ohler. All rights reserved.
2
- // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
-
4
- #include "hash.h"
5
-
6
- #include <stdint.h>
7
-
8
- #define HASH_MASK 0x000003FF
9
- #define HASH_SLOT_CNT 1024
10
-
11
- typedef struct _keyVal {
12
- struct _keyVal *next;
13
- const char * key;
14
- size_t len;
15
- VALUE val;
16
- } * KeyVal;
17
-
18
- struct _hash {
19
- struct _keyVal slots[HASH_SLOT_CNT];
20
- };
21
-
22
- struct _hash class_hash;
23
- struct _hash str_hash;
24
- struct _hash sym_hash;
25
- struct _hash intern_hash;
26
-
27
- // almost the Murmur hash algorithm
28
- #define M 0x5bd1e995
29
- #define C1 0xCC9E2D51
30
- #define C2 0x1B873593
31
- #define N 0xE6546B64
32
-
33
- static uint32_t hash_calc(const uint8_t *key, size_t len) {
34
- const uint8_t *end = key + len;
35
- const uint8_t *endless = key + (len / 4 * 4);
36
- uint32_t h = (uint32_t)len;
37
- uint32_t k;
38
-
39
- while (key < endless) {
40
- k = (uint32_t)*key++;
41
- k |= (uint32_t)*key++ << 8;
42
- k |= (uint32_t)*key++ << 16;
43
- k |= (uint32_t)*key++ << 24;
44
-
45
- k *= M;
46
- k ^= k >> 24;
47
- h *= M;
48
- h ^= k * M;
49
- }
50
- if (1 < end - key) {
51
- uint16_t k16 = (uint16_t)*key++;
52
-
53
- k16 |= (uint16_t)*key++ << 8;
54
- h ^= k16 << 8;
55
- }
56
- if (key < end) {
57
- h ^= *key;
58
- }
59
- h *= M;
60
- h ^= h >> 13;
61
- h *= M;
62
- h ^= h >> 15;
63
-
64
- return h;
65
- }
66
-
67
- void oj_hash_init() {
68
- memset(class_hash.slots, 0, sizeof(class_hash.slots));
69
- memset(str_hash.slots, 0, sizeof(str_hash.slots));
70
- memset(sym_hash.slots, 0, sizeof(sym_hash.slots));
71
- memset(intern_hash.slots, 0, sizeof(intern_hash.slots));
72
- }
73
-
74
- // if slotp is 0 then just lookup
75
- static VALUE hash_get(Hash hash, const char *key, size_t len, VALUE **slotp, VALUE def_value) {
76
- uint32_t h = hash_calc((const uint8_t *)key, len) & HASH_MASK;
77
- KeyVal bucket = hash->slots + h;
78
-
79
- if (0 != bucket->key) {
80
- KeyVal b;
81
-
82
- for (b = bucket; 0 != b; b = b->next) {
83
- if (len == b->len && 0 == strncmp(b->key, key, len)) {
84
- *slotp = &b->val;
85
- return b->val;
86
- }
87
- bucket = b;
88
- }
89
- }
90
- if (0 != slotp) {
91
- if (0 != bucket->key) {
92
- KeyVal b = ALLOC(struct _keyVal);
93
-
94
- b->next = 0;
95
- bucket->next = b;
96
- bucket = b;
97
- }
98
- bucket->key = oj_strndup(key, len);
99
- bucket->len = len;
100
- bucket->val = def_value;
101
- *slotp = &bucket->val;
102
- }
103
- return def_value;
104
- }
105
-
106
- void oj_hash_print() {
107
- int i;
108
- KeyVal b;
109
-
110
- for (i = 0; i < HASH_SLOT_CNT; i++) {
111
- printf("%4d:", i);
112
- for (b = class_hash.slots + i; 0 != b && 0 != b->key; b = b->next) {
113
- printf(" %s", b->key);
114
- }
115
- printf("\n");
116
- }
117
- }
118
-
119
- VALUE
120
- oj_class_hash_get(const char *key, size_t len, VALUE **slotp) {
121
- return hash_get(&class_hash, key, len, slotp, Qnil);
122
- }
123
-
124
- VALUE
125
- oj_str_hash_get(const char *key, size_t len, VALUE **slotp) {
126
- return hash_get(&str_hash, key, len, slotp, Qnil);
127
- }
128
-
129
- VALUE
130
- oj_sym_hash_get(const char *key, size_t len, VALUE **slotp) {
131
- return hash_get(&sym_hash, key, len, slotp, Qnil);
132
- }
133
-
134
- ID
135
- oj_attr_hash_get(const char *key, size_t len, ID **slotp) {
136
- return (ID)hash_get(&intern_hash, key, len, (VALUE **)slotp, 0);
137
- }
138
-
139
- char *oj_strndup(const char *s, size_t len) {
140
- char *d = ALLOC_N(char, len + 1);
141
-
142
- memcpy(d, s, len);
143
- d[len] = '\0';
144
-
145
- return d;
146
- }