oj 3.8.0 → 3.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/oj/custom.c +61 -36
- data/ext/oj/dump.c +9 -12
- data/ext/oj/dump_compat.c +6 -9
- data/ext/oj/dump_object.c +14 -9
- data/ext/oj/extconf.rb +1 -0
- data/ext/oj/mimic_json.c +4 -2
- data/ext/oj/object.c +8 -5
- data/ext/oj/oj.c +47 -30
- data/ext/oj/oj.h +6 -4
- data/ext/oj/parse.c +15 -2
- data/ext/oj/parse.h +1 -0
- data/ext/oj/rails.c +9 -2
- data/ext/oj/resolve.c +3 -3
- data/ext/oj/sparse.c +4 -0
- data/ext/oj/util.c +5 -5
- data/ext/oj/val_stack.c +9 -9
- data/ext/oj/val_stack.h +9 -9
- data/lib/oj/json.rb +1 -1
- data/lib/oj/version.rb +1 -1
- data/pages/Options.md +4 -0
- data/pages/Rails.md +21 -21
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/bar.rb +8 -11
- data/test/baz.rb +16 -0
- data/test/test_compat.rb +0 -7
- data/test/test_custom.rb +6 -2
- data/test/test_integer_range.rb +1 -2
- data/test/test_object.rb +4 -3
- data/test/test_strict.rb +24 -1
- data/test/test_various.rb +41 -62
- metadata +20 -2
data/ext/oj/oj.h
CHANGED
@@ -21,7 +21,7 @@ extern "C" {
|
|
21
21
|
#include <stdint.h>
|
22
22
|
#include <stdbool.h>
|
23
23
|
|
24
|
-
#
|
24
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
25
25
|
#include <pthread.h>
|
26
26
|
#endif
|
27
27
|
#include "cache8.h"
|
@@ -149,8 +149,10 @@ typedef struct _options {
|
|
149
149
|
char allow_nan; // YEsyNo for parsing only
|
150
150
|
char trace; // YesNo
|
151
151
|
char safe; // YesNo
|
152
|
-
|
153
|
-
|
152
|
+
char sec_prec_set; // boolean (0 or 1)
|
153
|
+
char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
|
154
|
+
int64_t int_range_min; // dump numbers below as string
|
155
|
+
int64_t int_range_max; // dump numbers above as string
|
154
156
|
const char *create_id; // 0 or string
|
155
157
|
size_t create_id_len; // length of create_id
|
156
158
|
int sec_prec; // second precision when dumping time
|
@@ -370,7 +372,7 @@ extern bool oj_use_hash_alt;
|
|
370
372
|
extern bool oj_use_array_alt;
|
371
373
|
extern bool string_writer_optimized;
|
372
374
|
|
373
|
-
#
|
375
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
374
376
|
extern pthread_mutex_t oj_cache_mutex;
|
375
377
|
#else
|
376
378
|
extern VALUE oj_cache_mutex;
|
data/ext/oj/parse.c
CHANGED
@@ -400,6 +400,10 @@ read_num(ParseInfo pi) {
|
|
400
400
|
pi->cur++;
|
401
401
|
ni.neg = 1;
|
402
402
|
} else if ('+' == *pi->cur) {
|
403
|
+
if (StrictMode == pi->options.mode) {
|
404
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
405
|
+
return;
|
406
|
+
}
|
403
407
|
pi->cur++;
|
404
408
|
}
|
405
409
|
if ('I' == *pi->cur) {
|
@@ -446,8 +450,13 @@ read_num(ParseInfo pi) {
|
|
446
450
|
if ('.' == *pi->cur) {
|
447
451
|
pi->cur++;
|
448
452
|
// A trailing . is not a valid decimal but if encountered allow it
|
449
|
-
// except when mimicing the JSON gem.
|
450
|
-
if (CompatMode == pi->options.mode) {
|
453
|
+
// except when mimicing the JSON gem or in strict mode.
|
454
|
+
if (StrictMode == pi->options.mode || CompatMode == pi->options.mode) {
|
455
|
+
int pos = (int)(pi->cur - ni.str);
|
456
|
+
if (1 == pos || (2 == pos && ni.neg)) {
|
457
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number");
|
458
|
+
return;
|
459
|
+
}
|
451
460
|
if (*pi->cur < '0' || '9' < *pi->cur) {
|
452
461
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number");
|
453
462
|
return;
|
@@ -1049,6 +1058,10 @@ CLEANUP:
|
|
1049
1058
|
msg = rb_str_append(msg, oj_encode(rb_str_new2(pi->json)));
|
1050
1059
|
}
|
1051
1060
|
args[0] = msg;
|
1061
|
+
if (pi->err.clas == oj_parse_error_class) {
|
1062
|
+
// The error was an Oj::ParseError so change to a JSON::ParserError.
|
1063
|
+
pi->err.clas = oj_json_parser_error_class;
|
1064
|
+
}
|
1052
1065
|
rb_exc_raise(rb_class_new_instance(1, args, pi->err.clas));
|
1053
1066
|
} else {
|
1054
1067
|
oj_err_raise(&pi->err);
|
data/ext/oj/parse.h
CHANGED
@@ -80,6 +80,7 @@ extern VALUE oj_num_as_value(NumInfo ni);
|
|
80
80
|
extern void oj_set_strict_callbacks(ParseInfo pi);
|
81
81
|
extern void oj_set_object_callbacks(ParseInfo pi);
|
82
82
|
extern void oj_set_compat_callbacks(ParseInfo pi);
|
83
|
+
extern void oj_set_custom_callbacks(ParseInfo pi);
|
83
84
|
extern void oj_set_wab_callbacks(ParseInfo pi);
|
84
85
|
|
85
86
|
extern void oj_sparse2(ParseInfo pi);
|
data/ext/oj/rails.c
CHANGED
@@ -214,6 +214,8 @@ dump_bigdecimal(VALUE obj, int depth, Out out, bool as_ok) {
|
|
214
214
|
|
215
215
|
if ('I' == *str || 'N' == *str || ('-' == *str && 'I' == str[1])) {
|
216
216
|
oj_dump_nil(Qnil, depth, out, false);
|
217
|
+
} else if (out->opts->int_range_max != 0 || out->opts->int_range_min != 0) {
|
218
|
+
oj_dump_cstr(str, (int)RSTRING_LEN(rstr), 0, 0, out);
|
217
219
|
} else if (Yes == out->opts->bigdec_as_num) {
|
218
220
|
oj_dump_raw(str, (int)RSTRING_LEN(rstr), out);
|
219
221
|
} else {
|
@@ -1035,6 +1037,7 @@ static VALUE
|
|
1035
1037
|
rails_time_precision(VALUE self, VALUE prec) {
|
1036
1038
|
rb_iv_set(self, "@time_precision", prec);
|
1037
1039
|
oj_default_options.sec_prec = NUM2INT(prec);
|
1040
|
+
oj_default_options.sec_prec_set = true;
|
1038
1041
|
|
1039
1042
|
return prec;
|
1040
1043
|
}
|
@@ -1071,11 +1074,14 @@ rails_set_encoder(VALUE self) {
|
|
1071
1074
|
rb_undef_method(encoding, "use_standard_json_time_format=");
|
1072
1075
|
rb_define_module_function(encoding, "use_standard_json_time_format=", rails_use_standard_json_time_format, 1);
|
1073
1076
|
|
1077
|
+
pv = rb_iv_get(encoding, "@escape_html_entities_in_json");
|
1078
|
+
escape_html = Qtrue == pv;
|
1074
1079
|
rb_undef_method(encoding, "escape_html_entities_in_json=");
|
1075
1080
|
rb_define_module_function(encoding, "escape_html_entities_in_json=", rails_escape_html_entities_in_json, 1);
|
1076
1081
|
|
1077
1082
|
pv = rb_iv_get(encoding, "@time_precision");
|
1078
1083
|
oj_default_options.sec_prec = NUM2INT(pv);
|
1084
|
+
oj_default_options.sec_prec_set = true;
|
1079
1085
|
rb_undef_method(encoding, "time_precision=");
|
1080
1086
|
rb_define_module_function(encoding, "time_precision=", rails_time_precision, 1);
|
1081
1087
|
rb_gv_set("$VERBOSE", verbose);
|
@@ -1436,8 +1442,9 @@ static DumpFunc rails_funcs[] = {
|
|
1436
1442
|
dump_array, // RUBY_T_ARRAY = 0x07,
|
1437
1443
|
dump_hash, // RUBY_T_HASH = 0x08,
|
1438
1444
|
dump_obj, // RUBY_T_STRUCT = 0x09,
|
1439
|
-
|
1440
|
-
|
1445
|
+
dump_bigdecimal, // RUBY_T_BIGNUM = 0x0a,
|
1446
|
+
//oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
1447
|
+
dump_as_string, // RUBY_T_FILE = 0x0b,
|
1441
1448
|
dump_obj, // RUBY_T_DATA = 0x0c,
|
1442
1449
|
NULL, // RUBY_T_MATCH = 0x0d,
|
1443
1450
|
// Rails raises a stack error on Complex and Rational. It also corrupts
|
data/ext/oj/resolve.c
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
#include <stdlib.h>
|
7
7
|
#include <stdio.h>
|
8
8
|
#include <string.h>
|
9
|
-
#
|
9
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
10
10
|
#include <pthread.h>
|
11
11
|
#endif
|
12
12
|
|
@@ -75,7 +75,7 @@ oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE
|
|
75
75
|
if (No == pi->options.class_cache) {
|
76
76
|
return resolve_classpath(pi, name, len, auto_define, error_class);
|
77
77
|
}
|
78
|
-
#
|
78
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
79
79
|
pthread_mutex_lock(&oj_cache_mutex);
|
80
80
|
#else
|
81
81
|
rb_mutex_lock(oj_cache_mutex);
|
@@ -85,7 +85,7 @@ oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE
|
|
85
85
|
*slot = clas;
|
86
86
|
}
|
87
87
|
}
|
88
|
-
#
|
88
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
89
89
|
pthread_mutex_unlock(&oj_cache_mutex);
|
90
90
|
#else
|
91
91
|
rb_mutex_unlock(oj_cache_mutex);
|
data/ext/oj/sparse.c
CHANGED
@@ -898,6 +898,10 @@ CLEANUP:
|
|
898
898
|
// idea.
|
899
899
|
VALUE args[] = { oj_encode(rb_str_new2(pi->err.msg)) };
|
900
900
|
|
901
|
+
if (pi->err.clas == oj_parse_error_class) {
|
902
|
+
// The error was an Oj::ParseError so change to a JSON::ParserError.
|
903
|
+
pi->err.clas = oj_json_parser_error_class;
|
904
|
+
}
|
901
905
|
rb_exc_raise(rb_class_new_instance(1, args, pi->err.clas));
|
902
906
|
} else {
|
903
907
|
oj_err_raise(&pi->err);
|
data/ext/oj/util.c
CHANGED
@@ -110,7 +110,7 @@ sec_as_time(int64_t secs, TimeInfo ti) {
|
|
110
110
|
}
|
111
111
|
}
|
112
112
|
}
|
113
|
-
ti->year = (qc - shift) * 400 + c * 100 + qy * 4 + y;
|
113
|
+
ti->year = (int)((qc - (int64_t)shift) * 400 + c * 100 + qy * 4 + y);
|
114
114
|
if (leap) {
|
115
115
|
ms = eom_leap_secs;
|
116
116
|
} else {
|
@@ -125,12 +125,12 @@ sec_as_time(int64_t secs, TimeInfo ti) {
|
|
125
125
|
break;
|
126
126
|
}
|
127
127
|
}
|
128
|
-
ti->day = secs / 86400LL;
|
128
|
+
ti->day = (int)(secs / 86400LL);
|
129
129
|
secs = secs - (int64_t)ti->day * 86400LL;
|
130
130
|
ti->day++;
|
131
|
-
ti->hour = secs / 3600LL;
|
131
|
+
ti->hour = (int)(secs / 3600LL);
|
132
132
|
secs = secs - (int64_t)ti->hour * 3600LL;
|
133
|
-
ti->min = secs / 60LL;
|
133
|
+
ti->min = (int)(secs / 60LL);
|
134
134
|
secs = secs - (int64_t)ti->min * 60LL;
|
135
|
-
ti->sec = secs;
|
135
|
+
ti->sec = (int)secs;
|
136
136
|
}
|
data/ext/oj/val_stack.c
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
/* val_stack.c
|
2
2
|
* Copyright (c) 2011, Peter Ohler
|
3
3
|
* All rights reserved.
|
4
|
-
*
|
4
|
+
*
|
5
5
|
* Redistribution and use in source and binary forms, with or without
|
6
6
|
* modification, are permitted provided that the following conditions are met:
|
7
|
-
*
|
7
|
+
*
|
8
8
|
* - Redistributions of source code must retain the above copyright notice, this
|
9
9
|
* list of conditions and the following disclaimer.
|
10
|
-
*
|
10
|
+
*
|
11
11
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
12
|
* this list of conditions and the following disclaimer in the documentation
|
13
13
|
* and/or other materials provided with the distribution.
|
14
|
-
*
|
14
|
+
*
|
15
15
|
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
16
|
* used to endorse or promote products derived from this software without
|
17
17
|
* specific prior written permission.
|
18
|
-
*
|
18
|
+
*
|
19
19
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
20
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
21
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
@@ -42,7 +42,7 @@ mark(void *ptr) {
|
|
42
42
|
if (0 == ptr) {
|
43
43
|
return;
|
44
44
|
}
|
45
|
-
#
|
45
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
46
46
|
pthread_mutex_lock(&stack->mutex);
|
47
47
|
#else
|
48
48
|
rb_mutex_lock(stack->mutex);
|
@@ -66,7 +66,7 @@ mark(void *ptr) {
|
|
66
66
|
}
|
67
67
|
}
|
68
68
|
}
|
69
|
-
#
|
69
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
70
70
|
pthread_mutex_unlock(&stack->mutex);
|
71
71
|
#else
|
72
72
|
rb_mutex_unlock(stack->mutex);
|
@@ -75,9 +75,9 @@ mark(void *ptr) {
|
|
75
75
|
|
76
76
|
VALUE
|
77
77
|
oj_stack_init(ValStack stack) {
|
78
|
-
#
|
78
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
79
79
|
int err;
|
80
|
-
|
80
|
+
|
81
81
|
if (0 != (err = pthread_mutex_init(&stack->mutex, 0))) {
|
82
82
|
rb_raise(rb_eException, "failed to initialize a mutex. %s", strerror(err));
|
83
83
|
}
|
data/ext/oj/val_stack.h
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
/* val_stack.h
|
2
2
|
* Copyright (c) 2011, Peter Ohler
|
3
3
|
* All rights reserved.
|
4
|
-
*
|
4
|
+
*
|
5
5
|
* Redistribution and use in source and binary forms, with or without
|
6
6
|
* modification, are permitted provided that the following conditions are met:
|
7
|
-
*
|
7
|
+
*
|
8
8
|
* - Redistributions of source code must retain the above copyright notice, this
|
9
9
|
* list of conditions and the following disclaimer.
|
10
|
-
*
|
10
|
+
*
|
11
11
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
12
|
* this list of conditions and the following disclaimer in the documentation
|
13
13
|
* and/or other materials provided with the distribution.
|
14
|
-
*
|
14
|
+
*
|
15
15
|
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
16
|
* used to endorse or promote products derived from this software without
|
17
17
|
* specific prior written permission.
|
18
|
-
*
|
18
|
+
*
|
19
19
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
20
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
21
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
@@ -34,7 +34,7 @@
|
|
34
34
|
#include "ruby.h"
|
35
35
|
#include "odd.h"
|
36
36
|
#include <stdint.h>
|
37
|
-
#
|
37
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
38
38
|
#include <pthread.h>
|
39
39
|
#endif
|
40
40
|
|
@@ -72,7 +72,7 @@ typedef struct _valStack {
|
|
72
72
|
Val head; // current stack
|
73
73
|
Val end; // stack end
|
74
74
|
Val tail; // pointer to one past last element name on stack
|
75
|
-
#
|
75
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
76
76
|
pthread_mutex_t mutex;
|
77
77
|
#else
|
78
78
|
VALUE mutex;
|
@@ -110,7 +110,7 @@ stack_push(ValStack stack, VALUE val, ValNext next) {
|
|
110
110
|
} else {
|
111
111
|
REALLOC_N(head, struct _val, len + STACK_INC);
|
112
112
|
}
|
113
|
-
#
|
113
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
114
114
|
pthread_mutex_lock(&stack->mutex);
|
115
115
|
#else
|
116
116
|
rb_mutex_lock(stack->mutex);
|
@@ -118,7 +118,7 @@ stack_push(ValStack stack, VALUE val, ValNext next) {
|
|
118
118
|
stack->head = head;
|
119
119
|
stack->tail = stack->head + toff;
|
120
120
|
stack->end = stack->head + len + STACK_INC;
|
121
|
-
#
|
121
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
122
122
|
pthread_mutex_unlock(&stack->mutex);
|
123
123
|
#else
|
124
124
|
rb_mutex_unlock(stack->mutex);
|
data/lib/oj/json.rb
CHANGED
data/lib/oj/version.rb
CHANGED
data/pages/Options.md
CHANGED
@@ -89,6 +89,10 @@ with the key.
|
|
89
89
|
The :create_id option specifies that key is used for dumping and loading when
|
90
90
|
specifying the class for an encoded object. The default is `json_create`.
|
91
91
|
|
92
|
+
In the `:custom` mode setting the `:create_id` to nil will cause Complex,
|
93
|
+
Rational, Range, and Regexp to be output as strings instead of as JSON
|
94
|
+
objects.
|
95
|
+
|
92
96
|
### :empty_string [Boolean]
|
93
97
|
|
94
98
|
If true an empty or all whitespace input will not raise an Exception. The
|
data/pages/Rails.md
CHANGED
@@ -26,44 +26,44 @@ directly. If Rails mode is also desired then use the `Oj.default_options` to
|
|
26
26
|
change the default mode.
|
27
27
|
|
28
28
|
Some of the Oj options are supported as arguments to the encoder if called
|
29
|
-
from Oj::Rails.encode() but when using the Oj::Rails::Encoder class the
|
30
|
-
encode() method does not support optional arguments as required by the
|
29
|
+
from `Oj::Rails.encode()` but when using the `Oj::Rails::Encoder` class the
|
30
|
+
`encode()` method does not support optional arguments as required by the
|
31
31
|
ActiveSupport compliance guidelines. The general approach Rails takes for
|
32
32
|
configuring encoding options is to either set global values or to create a new
|
33
33
|
instance of the Encoder class and provide options in the initializer.
|
34
34
|
|
35
35
|
The globals that ActiveSupport uses for encoding are:
|
36
36
|
|
37
|
-
* ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
38
|
-
* ActiveSupport::JSON::Encoding.escape_html_entities_in_json
|
39
|
-
* ActiveSupport::JSON::Encoding.time_precision
|
40
|
-
* ActiveSupport::JSON::Encoding.json_encoder
|
37
|
+
* `ActiveSupport::JSON::Encoding.use_standard_json_time_format`
|
38
|
+
* `ActiveSupport::JSON::Encoding.escape_html_entities_in_json`
|
39
|
+
* `ActiveSupport::JSON::Encoding.time_precision`
|
40
|
+
* `ActiveSupport::JSON::Encoding.json_encoder`
|
41
41
|
|
42
42
|
Those globals are aliased to also be accessed from the ActiveSupport module
|
43
|
-
directly so ActiveSupport::JSON::Encoding.time_precision can also be accessed
|
44
|
-
from ActiveSupport.time_precision
|
45
|
-
Rails after the Oj::Rails.set_encode() method is called. That also sets the
|
46
|
-
ActiveSupport.json_encoder to the Oj::Rails::Encoder class.
|
43
|
+
directly so `ActiveSupport::JSON::Encoding.time_precision` can also be accessed
|
44
|
+
from `ActiveSupport.time_precision`. Oj makes use of these globals in mimicing
|
45
|
+
Rails after the `Oj::Rails.set_encode()` method is called. That also sets the
|
46
|
+
`ActiveSupport.json_encoder` to the `Oj::Rails::Encoder` class.
|
47
47
|
|
48
|
-
Options passed into a call to to_json() are passed to the as_json()
|
48
|
+
Options passed into a call to `to_json()` are passed to the `as_json()`
|
49
49
|
methods. These are mostly ignored by Oj and simply passed on without
|
50
50
|
modifications as per the guidelines. The exception to this are the options
|
51
|
-
specific to Oj such as the
|
51
|
+
specific to Oj such as the `:circular` option which it used to detect circular
|
52
52
|
references while encoding.
|
53
53
|
|
54
54
|
By default Oj acts like the ActiveSupport encoder and honors any changes in
|
55
|
-
the as_json() methods. There are some optimized Oj encoders for some
|
56
|
-
classes. When the optimized encoder it toggled the as_json() methods will not
|
55
|
+
the `as_json()` methods. There are some optimized Oj encoders for some
|
56
|
+
classes. When the optimized encoder it toggled the `as_json()` methods will not
|
57
57
|
be called for that class but instead the optimized version will be called. The
|
58
58
|
optimized version is the same as the ActiveSupport default encoding for a
|
59
|
-
given class. The optimized versions are toggled with the optimize() and
|
60
|
-
deoptimize() methods. There is a default optimized version for every class
|
59
|
+
given class. The optimized versions are toggled with the `optimize()` and
|
60
|
+
`deoptimize()` methods. There is a default optimized version for every class
|
61
61
|
that takes the visible attributes and encodes them but that may not be the
|
62
62
|
same as what Rails uses. Trial and error is the best approach for classes not
|
63
63
|
listed here.
|
64
64
|
|
65
65
|
The classes that can be put in optimized mode and are optimized when
|
66
|
-
Oj::Rails.optimize is called with no arguments are:
|
66
|
+
`Oj::Rails.optimize` is called with no arguments are:
|
67
67
|
|
68
68
|
* Array
|
69
69
|
* BigDecimal
|
@@ -77,8 +77,8 @@ Oj::Rails.optimize is called with no arguments are:
|
|
77
77
|
* any class inheriting from ActiveRecord::Base
|
78
78
|
* any other class where all attributes should be dumped
|
79
79
|
|
80
|
-
The ActiveSupport decoder is the JSON.parse() method. Calling the
|
81
|
-
Oj::Rails.set_decoder() method replaces that method with the Oj equivalent.
|
80
|
+
The ActiveSupport decoder is the `JSON.parse()` method. Calling the
|
81
|
+
`Oj::Rails.set_decoder()` method replaces that method with the Oj equivalent.
|
82
82
|
|
83
83
|
### Notes:
|
84
84
|
|
@@ -87,8 +87,8 @@ Oj::Rails.set_decoder() method replaces that method with the Oj equivalent.
|
|
87
87
|
significant digits which can be either 16 or 17 depending on the value.
|
88
88
|
|
89
89
|
2. Optimized Hashs do not collapse keys that become the same in the output. As
|
90
|
-
an example, a non-String object that has a to_s() method will become the
|
91
|
-
return value of the to_s() method in the output without checking to see if
|
90
|
+
an example, a non-String object that has a `to_s()` method will become the
|
91
|
+
return value of the `to_s()` method in the output without checking to see if
|
92
92
|
that has already been used. This could occur is a mix of String and Symbols
|
93
93
|
are used as keys or if a other non-String objects such as Numerics are mixed
|
94
94
|
with numbers as Strings.
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ORIG_ARGV = ARGV.dup
|
4
|
+
|
5
|
+
require "active_support/core_ext/kernel/reporting"
|
6
|
+
|
7
|
+
silence_warnings do
|
8
|
+
Encoding.default_internal = Encoding::UTF_8
|
9
|
+
Encoding.default_external = Encoding::UTF_8
|
10
|
+
end
|
11
|
+
|
12
|
+
require "active_support/testing/autorun"
|
13
|
+
require "active_support/testing/method_call_assertions"
|
14
|
+
|
15
|
+
ENV["NO_RELOAD"] = "1"
|
16
|
+
require "active_support"
|
17
|
+
|
18
|
+
Thread.abort_on_exception = true
|
19
|
+
|
20
|
+
# Show backtraces for deprecated behavior for quicker cleanup.
|
21
|
+
ActiveSupport::Deprecation.debug = true
|
22
|
+
|
23
|
+
# Default to old to_time behavior but allow running tests with new behavior
|
24
|
+
ActiveSupport.to_time_preserves_timezone = ENV["PRESERVE_TIMEZONES"] == "1"
|
25
|
+
|
26
|
+
# Disable available locale checks to avoid warnings running the test suite.
|
27
|
+
I18n.enforce_available_locales = false
|
28
|
+
|
29
|
+
class ActiveSupport::TestCase
|
30
|
+
include ActiveSupport::Testing::MethodCallAssertions
|
31
|
+
|
32
|
+
# Skips the current run on Rubinius using Minitest::Assertions#skip
|
33
|
+
private def rubinius_skip(message = "")
|
34
|
+
skip message if RUBY_ENGINE == "rbx"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Skips the current run on JRuby using Minitest::Assertions#skip
|
38
|
+
private def jruby_skip(message = "")
|
39
|
+
skip message if defined?(JRUBY_VERSION)
|
40
|
+
end
|
41
|
+
|
42
|
+
def frozen_error_class
|
43
|
+
Object.const_defined?(:FrozenError) ? FrozenError : RuntimeError
|
44
|
+
end
|
45
|
+
end
|