oj 3.7.12

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.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +96 -0
  4. data/ext/oj/buf.h +103 -0
  5. data/ext/oj/cache8.c +107 -0
  6. data/ext/oj/cache8.h +48 -0
  7. data/ext/oj/circarray.c +68 -0
  8. data/ext/oj/circarray.h +23 -0
  9. data/ext/oj/code.c +235 -0
  10. data/ext/oj/code.h +42 -0
  11. data/ext/oj/compat.c +299 -0
  12. data/ext/oj/custom.c +1188 -0
  13. data/ext/oj/dump.c +1232 -0
  14. data/ext/oj/dump.h +94 -0
  15. data/ext/oj/dump_compat.c +973 -0
  16. data/ext/oj/dump_leaf.c +252 -0
  17. data/ext/oj/dump_object.c +837 -0
  18. data/ext/oj/dump_strict.c +433 -0
  19. data/ext/oj/encode.h +45 -0
  20. data/ext/oj/err.c +57 -0
  21. data/ext/oj/err.h +70 -0
  22. data/ext/oj/extconf.rb +47 -0
  23. data/ext/oj/fast.c +1771 -0
  24. data/ext/oj/hash.c +163 -0
  25. data/ext/oj/hash.h +46 -0
  26. data/ext/oj/hash_test.c +512 -0
  27. data/ext/oj/mimic_json.c +873 -0
  28. data/ext/oj/object.c +771 -0
  29. data/ext/oj/odd.c +231 -0
  30. data/ext/oj/odd.h +44 -0
  31. data/ext/oj/oj.c +1694 -0
  32. data/ext/oj/oj.h +381 -0
  33. data/ext/oj/parse.c +1085 -0
  34. data/ext/oj/parse.h +111 -0
  35. data/ext/oj/rails.c +1485 -0
  36. data/ext/oj/rails.h +21 -0
  37. data/ext/oj/reader.c +231 -0
  38. data/ext/oj/reader.h +151 -0
  39. data/ext/oj/resolve.c +102 -0
  40. data/ext/oj/resolve.h +14 -0
  41. data/ext/oj/rxclass.c +147 -0
  42. data/ext/oj/rxclass.h +27 -0
  43. data/ext/oj/saj.c +714 -0
  44. data/ext/oj/scp.c +224 -0
  45. data/ext/oj/sparse.c +910 -0
  46. data/ext/oj/stream_writer.c +363 -0
  47. data/ext/oj/strict.c +212 -0
  48. data/ext/oj/string_writer.c +512 -0
  49. data/ext/oj/trace.c +79 -0
  50. data/ext/oj/trace.h +28 -0
  51. data/ext/oj/util.c +136 -0
  52. data/ext/oj/util.h +19 -0
  53. data/ext/oj/val_stack.c +118 -0
  54. data/ext/oj/val_stack.h +185 -0
  55. data/ext/oj/wab.c +631 -0
  56. data/lib/oj.rb +21 -0
  57. data/lib/oj/active_support_helper.rb +41 -0
  58. data/lib/oj/bag.rb +88 -0
  59. data/lib/oj/easy_hash.rb +52 -0
  60. data/lib/oj/error.rb +22 -0
  61. data/lib/oj/json.rb +176 -0
  62. data/lib/oj/mimic.rb +267 -0
  63. data/lib/oj/saj.rb +66 -0
  64. data/lib/oj/schandler.rb +142 -0
  65. data/lib/oj/state.rb +131 -0
  66. data/lib/oj/version.rb +5 -0
  67. data/pages/Advanced.md +22 -0
  68. data/pages/Compatibility.md +25 -0
  69. data/pages/Custom.md +23 -0
  70. data/pages/Encoding.md +65 -0
  71. data/pages/JsonGem.md +79 -0
  72. data/pages/Modes.md +154 -0
  73. data/pages/Options.md +266 -0
  74. data/pages/Rails.md +116 -0
  75. data/pages/Security.md +20 -0
  76. data/pages/WAB.md +13 -0
  77. data/test/_test_active.rb +76 -0
  78. data/test/_test_active_mimic.rb +96 -0
  79. data/test/_test_mimic_rails.rb +126 -0
  80. data/test/activerecord/result_test.rb +27 -0
  81. data/test/activesupport4/decoding_test.rb +108 -0
  82. data/test/activesupport4/encoding_test.rb +531 -0
  83. data/test/activesupport4/test_helper.rb +41 -0
  84. data/test/activesupport5/decoding_test.rb +125 -0
  85. data/test/activesupport5/encoding_test.rb +485 -0
  86. data/test/activesupport5/encoding_test_cases.rb +90 -0
  87. data/test/activesupport5/test_helper.rb +50 -0
  88. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  89. data/test/big.rb +15 -0
  90. data/test/files.rb +29 -0
  91. data/test/foo.rb +33 -0
  92. data/test/helper.rb +26 -0
  93. data/test/isolated/shared.rb +308 -0
  94. data/test/isolated/test_mimic_after.rb +13 -0
  95. data/test/isolated/test_mimic_alone.rb +12 -0
  96. data/test/isolated/test_mimic_as_json.rb +45 -0
  97. data/test/isolated/test_mimic_before.rb +13 -0
  98. data/test/isolated/test_mimic_define.rb +28 -0
  99. data/test/isolated/test_mimic_rails_after.rb +22 -0
  100. data/test/isolated/test_mimic_rails_before.rb +21 -0
  101. data/test/isolated/test_mimic_redefine.rb +15 -0
  102. data/test/json_gem/json_addition_test.rb +216 -0
  103. data/test/json_gem/json_common_interface_test.rb +148 -0
  104. data/test/json_gem/json_encoding_test.rb +107 -0
  105. data/test/json_gem/json_ext_parser_test.rb +20 -0
  106. data/test/json_gem/json_fixtures_test.rb +35 -0
  107. data/test/json_gem/json_generator_test.rb +383 -0
  108. data/test/json_gem/json_generic_object_test.rb +90 -0
  109. data/test/json_gem/json_parser_test.rb +470 -0
  110. data/test/json_gem/json_string_matching_test.rb +42 -0
  111. data/test/json_gem/test_helper.rb +18 -0
  112. data/test/mem.rb +35 -0
  113. data/test/perf.rb +107 -0
  114. data/test/perf_compat.rb +130 -0
  115. data/test/perf_fast.rb +164 -0
  116. data/test/perf_file.rb +64 -0
  117. data/test/perf_object.rb +138 -0
  118. data/test/perf_saj.rb +109 -0
  119. data/test/perf_scp.rb +151 -0
  120. data/test/perf_simple.rb +287 -0
  121. data/test/perf_strict.rb +145 -0
  122. data/test/perf_wab.rb +131 -0
  123. data/test/sample.rb +54 -0
  124. data/test/sample/change.rb +14 -0
  125. data/test/sample/dir.rb +19 -0
  126. data/test/sample/doc.rb +36 -0
  127. data/test/sample/file.rb +48 -0
  128. data/test/sample/group.rb +16 -0
  129. data/test/sample/hasprops.rb +16 -0
  130. data/test/sample/layer.rb +12 -0
  131. data/test/sample/line.rb +20 -0
  132. data/test/sample/oval.rb +10 -0
  133. data/test/sample/rect.rb +10 -0
  134. data/test/sample/shape.rb +35 -0
  135. data/test/sample/text.rb +20 -0
  136. data/test/sample_json.rb +37 -0
  137. data/test/test_compat.rb +509 -0
  138. data/test/test_custom.rb +406 -0
  139. data/test/test_debian.rb +53 -0
  140. data/test/test_fast.rb +470 -0
  141. data/test/test_file.rb +239 -0
  142. data/test/test_gc.rb +49 -0
  143. data/test/test_hash.rb +29 -0
  144. data/test/test_integer_range.rb +73 -0
  145. data/test/test_null.rb +376 -0
  146. data/test/test_object.rb +1018 -0
  147. data/test/test_saj.rb +186 -0
  148. data/test/test_scp.rb +433 -0
  149. data/test/test_strict.rb +410 -0
  150. data/test/test_various.rb +739 -0
  151. data/test/test_wab.rb +307 -0
  152. data/test/test_writer.rb +380 -0
  153. data/test/tests.rb +24 -0
  154. data/test/tests_mimic.rb +14 -0
  155. data/test/tests_mimic_addition.rb +7 -0
  156. metadata +359 -0
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby -wW2
2
+
3
+ if $0 == __FILE__
4
+ $: << '.'
5
+ $: << '..'
6
+ $: << '../lib'
7
+ $: << '../ext'
8
+ end
9
+
10
+ require 'pp'
11
+ require 'sample/doc'
12
+
13
+ def sample_doc(size=3)
14
+ colors = [ :black, :gray, :white, :red, :blue, :yellow, :green, :purple, :orange ]
15
+
16
+ d = ::Sample::Doc.new('Sample')
17
+
18
+ # add some history
19
+ (0..size * 10).each do |i|
20
+ d.add_change("Changed at t+#{i}.")
21
+ end
22
+
23
+ # add some layers
24
+ (1..size).each do |i|
25
+ layer = ::Sample::Layer.new("Layer-#{i}")
26
+ (1..size).each do |j|
27
+ g = ::Sample::Group.new
28
+ (1..size).each do |k|
29
+ g2 = ::Sample::Group.new
30
+ r = ::Sample::Rect.new(j * 40 + 10.0, i * 10.0,
31
+ 10.123456 / k, 10.0 / k, colors[(i + j + k) % colors.size])
32
+ r.add_prop(:part_of, layer.name)
33
+ g2 << r
34
+ g2 << ::Sample::Text.new("#{k} in #{j}", r.left, r.top, r.width, r.height)
35
+ g << g2
36
+ end
37
+ g2 = ::Sample::Group.new
38
+ (1..size).each do |k|
39
+ o = ::Sample::Oval.new(j * 40 + 12.0, i * 10.0 + 2.0,
40
+ 6.0 / k, 6.0 / k, colors[(i + j + k) % colors.size])
41
+ o.add_prop(:inside, true)
42
+ g << o
43
+ end
44
+ g << g2
45
+ layer << g
46
+ end
47
+ d.layers[layer.name] = layer
48
+ end
49
+
50
+ # some properties
51
+ d.add_prop(:purpose, 'an example')
52
+
53
+ d
54
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module Sample
3
+ class Change
4
+ attr_accessor :time
5
+ attr_accessor :user
6
+ attr_accessor :comment
7
+
8
+ def initialize(comment=nil, time=nil, user=nil)
9
+ @user = user || ENV['USER']
10
+ @time = time || Time.now
11
+ @comment = comment
12
+ end
13
+ end # Change
14
+ end # Sample
@@ -0,0 +1,19 @@
1
+
2
+ require 'etc'
3
+
4
+ module Sample
5
+
6
+ class Dir < File
7
+ attr_accessor :files
8
+
9
+ def initialize(filename)
10
+ super
11
+ @files = []
12
+ end
13
+
14
+ def <<(f)
15
+ @files << f
16
+ end
17
+
18
+ end # Dir
19
+ end # Sample
@@ -0,0 +1,36 @@
1
+
2
+ require 'sample/hasprops'
3
+ require 'sample/group'
4
+ require 'sample/layer'
5
+ require 'sample/line'
6
+ require 'sample/shape'
7
+ require 'sample/oval'
8
+ require 'sample/rect'
9
+ require 'sample/text'
10
+ require 'sample/change'
11
+
12
+ module Sample
13
+ class Doc
14
+ include HasProps
15
+
16
+ attr_accessor :title
17
+ attr_accessor :create_time
18
+ attr_accessor :user
19
+ # Hash of layers in the document indexed by layer name.
20
+ attr_reader :layers
21
+ attr_reader :change_history
22
+
23
+ def initialize(title)
24
+ @title = title
25
+ @user = ENV['USER']
26
+ @create_time = Time.now
27
+ @layers = { }
28
+ @change_history = []
29
+ end
30
+
31
+ def add_change(comment, time=nil, user=nil)
32
+ @change_history << Change.new(comment, time, user)
33
+ end
34
+
35
+ end # Doc
36
+ end # Sample
@@ -0,0 +1,48 @@
1
+
2
+ require 'etc'
3
+
4
+ module Sample
5
+
6
+ class File
7
+ attr_accessor :name, :ctime, :mtime, :size, :owner, :group, :permissions
8
+
9
+ def initialize(filename)
10
+ @name = ::File.basename(filename)
11
+ stat = ::File.stat(filename)
12
+ @ctime = stat.ctime
13
+ @mtime = stat.mtime
14
+ @size = stat.size
15
+ @owner = Etc.getpwuid(stat.uid).name
16
+ @group = Etc.getgrgid(stat.gid).name
17
+ if false
18
+ @permissions = {
19
+ 'user' => {
20
+ 'read' => (0 != (stat.mode & 0x0100)),
21
+ 'write' => (0 != (stat.mode & 0x0080)),
22
+ 'execute' => (0 != (stat.mode & 0x0040))},
23
+ 'group' => {
24
+ 'read' => (0 != (stat.mode & 0x0020)),
25
+ 'write' => (0 != (stat.mode & 0x0010)),
26
+ 'execute' => (0 != (stat.mode & 0x0008))},
27
+ 'other' => {
28
+ 'read' => (0 != (stat.mode & 0x0004)),
29
+ 'write' => (0 != (stat.mode & 0x0002)),
30
+ 'execute' => (0 != (stat.mode & 0x0001))}
31
+ }
32
+ else
33
+ @permissions = {
34
+ 'user' => [(0 != (stat.mode & 0x0100)) ? 'r' : '-',
35
+ (0 != (stat.mode & 0x0080)) ? 'w' : '-',
36
+ (0 != (stat.mode & 0x0040)) ? 'x' : '-'].join(''),
37
+ 'group' => [(0 != (stat.mode & 0x0020)) ? 'r' : '-',
38
+ (0 != (stat.mode & 0x0010)) ? 'w' : '-',
39
+ (0 != (stat.mode & 0x0008)) ? 'x' : '-'].join(''),
40
+ 'other' => [(0 != (stat.mode & 0x0004)) ? 'r' : '-',
41
+ (0 != (stat.mode & 0x0002)) ? 'w' : '-',
42
+ (0 != (stat.mode & 0x0001)) ? 'x' : '-'].join('')
43
+ }
44
+ end
45
+ end
46
+
47
+ end # File
48
+ end # Sample
@@ -0,0 +1,16 @@
1
+
2
+ module Sample
3
+ class Group
4
+ attr_reader :members
5
+
6
+ def initialize()
7
+ @members = []
8
+ end
9
+
10
+ def <<(member)
11
+ @members << member
12
+ end
13
+
14
+ end # Group
15
+ end # Sample
16
+
@@ -0,0 +1,16 @@
1
+
2
+ module Sample
3
+ module HasProps
4
+
5
+ def add_prop(key, value)
6
+ @props = { } unless self.instance_variable_defined?(:@props)
7
+ @props[key] = value
8
+ end
9
+
10
+ def props
11
+ @props = { } unless self.instance_variable_defined?(:@props)
12
+ @props
13
+ end
14
+
15
+ end # HasProps
16
+ end # Sample
@@ -0,0 +1,12 @@
1
+
2
+ module Sample
3
+ class Layer < Group
4
+ attr_accessor :name
5
+
6
+ def initialize(name)
7
+ super()
8
+ @name = name
9
+ end
10
+
11
+ end # Layer
12
+ end # Sample
@@ -0,0 +1,20 @@
1
+ module Sample
2
+
3
+ class Line
4
+ include HasProps
5
+
6
+ attr_accessor :x, :y, :dx, :dy
7
+ attr_accessor :color
8
+ attr_accessor :thick
9
+
10
+ def initialize(x, y, dx, dy, thick, color)
11
+ @x = x
12
+ @y = y
13
+ @dx = dx
14
+ @dy = dy
15
+ @thick = thick
16
+ @color = color
17
+ end
18
+
19
+ end # Line
20
+ end # Sample
@@ -0,0 +1,10 @@
1
+ module Sample
2
+
3
+ class Oval < Shape
4
+
5
+ def initialize(left, top, wide, high, color=nil)
6
+ super
7
+ end
8
+
9
+ end # Oval
10
+ end # Sample
@@ -0,0 +1,10 @@
1
+
2
+ module Sample
3
+ class Rect < Shape
4
+
5
+ def initialize(left, top, wide, high, color=nil)
6
+ super
7
+ end
8
+
9
+ end # Rect
10
+ end # Sample
@@ -0,0 +1,35 @@
1
+
2
+ module Sample
3
+ class Shape
4
+ include HasProps
5
+
6
+ attr_accessor :bounds
7
+ attr_accessor :color
8
+ attr_accessor :border, :border_color
9
+
10
+ def initialize(left, top, wide, high, color=nil)
11
+ @bounds = [[left, top], [left + wide, top + high]]
12
+ @color = color
13
+ @border = 1
14
+ @border_color = :black
15
+ end
16
+
17
+ def left
18
+ @bounds[0][0]
19
+ end
20
+
21
+ def top
22
+ @bounds[0][1]
23
+ end
24
+
25
+ def width
26
+ @bounds[1][0] - @bounds[0][0]
27
+ end
28
+
29
+ def height
30
+ @bounds[1][1] - @bounds[0][1]
31
+ end
32
+
33
+ end # Shape
34
+ end # Sample
35
+
@@ -0,0 +1,20 @@
1
+
2
+ module Sample
3
+ class Text < Shape
4
+ attr_accessor :text
5
+ attr_accessor :font
6
+ attr_accessor :font_size
7
+ attr_accessor :just
8
+ attr_accessor :text_color
9
+
10
+ def initialize(text, left, top, wide, high, color=nil)
11
+ super(left, top, wide, high, color)
12
+ @text = text
13
+ @font = 'helvetica'
14
+ @font_size = 14
15
+ @just = 'left'
16
+ @text_color = 'black'
17
+ end
18
+
19
+ end # Text
20
+ end # Sample
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby -wW2
2
+
3
+ if $0 == __FILE__
4
+ $: << '.'
5
+ $: << '..'
6
+ $: << '../lib'
7
+ $: << '../ext'
8
+ end
9
+
10
+ require 'pp'
11
+ require 'oj'
12
+
13
+ def sample_json(size=3)
14
+ colors = [ :black, :gray, :white, :red, :blue, :yellow, :green, :purple, :orange ]
15
+ container = []
16
+ size.times do |i|
17
+ box = {
18
+ 'color' => colors[i % colors.size],
19
+ 'fragile' => (0 == (i % 2)),
20
+ 'width' => i,
21
+ 'height' => i,
22
+ 'depth' => i,
23
+ 'weight' => i * 1.3,
24
+ 'address' => {
25
+ 'street' => "#{i} Main Street",
26
+ 'city' => 'Sity',
27
+ 'state' => nil
28
+ }
29
+ }
30
+ container << box
31
+ end
32
+ container
33
+ end
34
+
35
+ if $0 == __FILE__
36
+ File.open('sample.json', "w") { |f| f.write(Oj.dump(sample_json(3), :indent => 2)) }
37
+ end
@@ -0,0 +1,509 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ $: << File.dirname(__FILE__)
5
+ $oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
6
+ %w(lib ext).each do |dir|
7
+ $: << File.join($oj_dir, dir)
8
+ end
9
+
10
+ require 'minitest'
11
+ require 'minitest/autorun'
12
+ require 'stringio'
13
+ require 'date'
14
+ require 'bigdecimal'
15
+ require 'oj'
16
+
17
+ class CompatJuice < Minitest::Test
18
+
19
+ class Jeez
20
+ attr_accessor :x, :y
21
+
22
+ def initialize(x, y)
23
+ @x = x
24
+ @y = y
25
+ end
26
+
27
+ def eql?(o)
28
+ self.class == o.class && @x == o.x && @y == o.y
29
+ end
30
+ alias == eql?
31
+
32
+ def to_json(*a)
33
+ %|{"json_class":"#{self.class.to_s}","x":#{@x},"y":#{@y}}|
34
+ end
35
+
36
+ def self.json_create(h)
37
+ self.new(h['x'], h['y'])
38
+ end
39
+ end # Jeez
40
+
41
+ class Argy
42
+ def initialize()
43
+ end
44
+
45
+ def to_json(*a)
46
+ %|{"args":"#{a}"}|
47
+ end
48
+ end # Argy
49
+
50
+ class Stringy
51
+ def initialize()
52
+ end
53
+
54
+ def to_s()
55
+ %|[1,2]|
56
+ end
57
+ end # Stringy
58
+
59
+ module One
60
+ module Two
61
+ module Three
62
+ class Deep
63
+
64
+ def initialize()
65
+ end
66
+
67
+ def eql?(o)
68
+ self.class == o.class
69
+ end
70
+ alias == eql?
71
+
72
+ def to_json(*a)
73
+ %|{"json_class":"#{self.class.name}"}|
74
+ end
75
+
76
+ def self.json_create(h)
77
+ self.new()
78
+ end
79
+ end # Deep
80
+ end # Three
81
+ end # Two
82
+ end # One
83
+
84
+ def setup
85
+ @default_options = Oj.default_options
86
+ # in compat mode other options other than the JSON gem globals and options
87
+ # are not used.
88
+ Oj.default_options = { :mode => :compat }
89
+ end
90
+
91
+ def teardown
92
+ Oj.default_options = @default_options
93
+ end
94
+
95
+ def test_nil
96
+ dump_and_load(nil, false)
97
+ end
98
+
99
+ def test_true
100
+ dump_and_load(true, false)
101
+ end
102
+
103
+ def test_false
104
+ dump_and_load(false, false)
105
+ end
106
+
107
+ def test_fixnum
108
+ dump_and_load(0, false)
109
+ dump_and_load(12345, false)
110
+ dump_and_load(-54321, false)
111
+ dump_and_load(1, false)
112
+ end
113
+
114
+ def test_float
115
+ dump_and_load(0.0, false)
116
+ dump_and_load(0.56, false)
117
+ dump_and_load(3.0, false)
118
+ dump_and_load(12345.6789, false)
119
+ dump_and_load(70.35, false)
120
+ dump_and_load(-54321.012, false)
121
+ dump_and_load(1.7775, false)
122
+ dump_and_load(2.5024, false)
123
+ dump_and_load(2.48e16, false)
124
+ dump_and_load(2.48e100 * 1.0e10, false)
125
+ dump_and_load(-2.48e100 * 1.0e10, false)
126
+ dump_and_load(1405460727.723866, false)
127
+ dump_and_load(0.5773, false)
128
+ dump_and_load(0.6768, false)
129
+ dump_and_load(0.685, false)
130
+ dump_and_load(0.7032, false)
131
+ dump_and_load(0.7051, false)
132
+ dump_and_load(0.8274, false)
133
+ dump_and_load(0.9149, false)
134
+ dump_and_load(64.4, false)
135
+ dump_and_load(71.6, false)
136
+ dump_and_load(73.4, false)
137
+ dump_and_load(80.6, false)
138
+ dump_and_load(-95.640172, false)
139
+ end
140
+
141
+ def test_string
142
+ dump_and_load('', false)
143
+ dump_and_load('abc', false)
144
+ dump_and_load("abc\ndef", false)
145
+ dump_and_load("a\u0041", false)
146
+ end
147
+
148
+ def test_encode
149
+ opts = Oj.default_options
150
+ Oj.default_options = { :ascii_only => false }
151
+ unless 'jruby' == $ruby
152
+ dump_and_load("ぴーたー", false)
153
+ end
154
+ Oj.default_options = { :ascii_only => true }
155
+ json = Oj.dump("ぴーたー")
156
+ assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
157
+ unless 'jruby' == $ruby
158
+ dump_and_load("ぴーたー", false)
159
+ end
160
+ Oj.default_options = opts
161
+ end
162
+
163
+ def test_unicode
164
+ # hits the 3 normal ranges and one extended surrogate pair
165
+ json = %{"\\u019f\\u05e9\\u3074\\ud834\\udd1e"}
166
+ obj = Oj.load(json)
167
+ json2 = Oj.dump(obj, :ascii_only => true)
168
+ assert_equal(json, json2)
169
+ end
170
+
171
+ def test_array
172
+ dump_and_load([], false)
173
+ dump_and_load([true, false], false)
174
+ dump_and_load(['a', 1, nil], false)
175
+ dump_and_load([[nil]], false)
176
+ dump_and_load([[nil], 58], false)
177
+ end
178
+
179
+ def test_array_deep
180
+ dump_and_load([1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20]]]]]]]]]]]]]]]]]]]], false)
181
+ end
182
+
183
+ def test_symbol
184
+ json = Oj.dump(:abc, :mode => :compat)
185
+ assert_equal('"abc"', json)
186
+ end
187
+
188
+ def test_time
189
+ t = Time.xmlschema("2012-01-05T23:58:07.123456000+09:00")
190
+ #t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
191
+ json = Oj.dump(t, :mode => :compat)
192
+ assert_equal(%{"2012-01-05 23:58:07 +0900"}, json)
193
+ end
194
+
195
+ def test_class
196
+ json = Oj.dump(CompatJuice, :mode => :compat)
197
+ assert_equal(%{"CompatJuice"}, json)
198
+ end
199
+
200
+ def test_module
201
+ json = Oj.dump(One::Two, :mode => :compat)
202
+ assert_equal(%{"CompatJuice::One::Two"}, json)
203
+ end
204
+
205
+ # Hash
206
+ def test_non_str_hash
207
+ json = Oj.dump({ 1 => true, 0 => false }, :mode => :compat)
208
+ h = Oj.load(json, :mode => :strict)
209
+ assert_equal({ "1" => true, "0" => false }, h)
210
+ end
211
+ def test_hash
212
+ dump_and_load({}, false)
213
+ dump_and_load({ 'true' => true, 'false' => false}, false)
214
+ dump_and_load({ 'true' => true, 'array' => [], 'hash' => { }}, false)
215
+ end
216
+
217
+ def test_hash_deep
218
+ dump_and_load({'1' => {
219
+ '2' => {
220
+ '3' => {
221
+ '4' => {
222
+ '5' => {
223
+ '6' => {
224
+ '7' => {
225
+ '8' => {
226
+ '9' => {
227
+ '10' => {
228
+ '11' => {
229
+ '12' => {
230
+ '13' => {
231
+ '14' => {
232
+ '15' => {
233
+ '16' => {
234
+ '17' => {
235
+ '18' => {
236
+ '19' => {
237
+ '20' => {}}}}}}}}}}}}}}}}}}}}}, false)
238
+ end
239
+
240
+ def test_hash_escaped_key
241
+ json = %{{"a\nb":true,"c\td":false}}
242
+ obj = Oj.compat_load(json)
243
+ assert_equal({"a\nb" => true, "c\td" => false}, obj)
244
+ end
245
+
246
+ def test_hash_escaping
247
+ json = Oj.to_json({'<>' => '<>'}, mode: :compat)
248
+ assert_equal(json, '{"<>":"<>"}')
249
+ end
250
+
251
+ def test_bignum_object
252
+ dump_and_load(7 ** 55, false)
253
+ end
254
+
255
+ def test_json_object
256
+ obj = Jeez.new(true, 58)
257
+ json = Oj.to_json(obj)
258
+ assert(%|{"json_class":"CompatJuice::Jeez","x":true,"y":58}| == json ||
259
+ %|{"json_class":"CompatJuice::Jeez","y":58,"x":true}| == json)
260
+ dump_to_json_and_load(obj, false)
261
+ end
262
+
263
+ def test_json_object_create_id
264
+ Oj.default_options = { :create_id => 'kson_class', :create_additions => true}
265
+ expected = Jeez.new(true, 58)
266
+ json = %{{"kson_class":"CompatJuice::Jeez","x":true,"y":58}}
267
+ obj = Oj.load(json)
268
+ assert_equal(expected, obj)
269
+ Oj.default_options = { :create_id => 'json_class' }
270
+ end
271
+
272
+ def test_bignum_compat
273
+ json = Oj.dump(7 ** 55, :mode => :compat)
274
+ b = Oj.load(json, :mode => :strict)
275
+ assert_equal(30226801971775055948247051683954096612865741943, b)
276
+ end
277
+
278
+ # BigDecimal
279
+ def test_bigdecimal
280
+ # BigDecimals are dumped as strings and can not be restored to the
281
+ # original value.
282
+ json = Oj.dump(BigDecimal('3.14159265358979323846'))
283
+ # 2.4.0 changes the exponent to lowercase
284
+ assert_equal('"0.314159265358979323846e1"', json.downcase)
285
+ end
286
+
287
+ def test_infinity
288
+ assert_raises(Oj::ParseError) { Oj.load('Infinity', :mode => :strict) }
289
+ x = Oj.load('Infinity', :mode => :compat)
290
+ assert_equal('Infinity', x.to_s)
291
+ end
292
+
293
+ # Time
294
+ def test_time
295
+ t = Time.new(2015, 1, 5, 21, 37, 7.123456, -8 * 3600)
296
+ expect = '"' + t.to_s + '"'
297
+ json = Oj.dump(t)
298
+ assert_equal(expect, json)
299
+ end
300
+
301
+ def test_date_compat
302
+ orig = Date.new(2012, 6, 19)
303
+ json = Oj.dump(orig, :mode => :compat)
304
+ x = Oj.load(json, :mode => :compat)
305
+ # Some Rubies implement Date as data and some as a real Object. Either are
306
+ # okay for the test.
307
+ if x.is_a?(String)
308
+ assert_equal(orig.to_s, x)
309
+ else # better be a Hash
310
+ assert_equal({"year" => orig.year, "month" => orig.month, "day" => orig.day, "start" => orig.start}, x)
311
+ end
312
+ end
313
+
314
+ def test_datetime_compat
315
+ orig = DateTime.new(2012, 6, 19, 20, 19, 27)
316
+ json = Oj.dump(orig, :mode => :compat)
317
+ x = Oj.load(json, :mode => :compat)
318
+ # Some Rubies implement Date as data and some as a real Object. Either are
319
+ # okay for the test.
320
+ assert_equal(orig.to_s, x)
321
+ end
322
+
323
+ # Stream IO
324
+ def test_io_string
325
+ json = %{{
326
+ "x":true,
327
+ "y":58,
328
+ "z": [1,2,3]
329
+ }
330
+ }
331
+ input = StringIO.new(json)
332
+ obj = Oj.compat_load(input)
333
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
334
+ end
335
+
336
+ def test_io_file
337
+ filename = File.join(File.dirname(__FILE__), 'open_file_test.json')
338
+ File.open(filename, 'w') { |f| f.write(%{{
339
+ "x":true,
340
+ "y":58,
341
+ "z": [1,2,3]
342
+ }
343
+ }) }
344
+ f = File.new(filename)
345
+ obj = Oj.compat_load(f)
346
+ f.close()
347
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
348
+ end
349
+
350
+ # symbol_keys option
351
+ def test_symbol_keys
352
+ json = %{{
353
+ "x":true,
354
+ "y":58,
355
+ "z": [1,2,3]
356
+ }
357
+ }
358
+ obj = Oj.compat_load(json, :symbol_keys => true)
359
+ assert_equal({ :x => true, :y => 58, :z => [1, 2, 3]}, obj)
360
+ end
361
+
362
+ # comments
363
+ def test_comment_slash
364
+ json = %{{
365
+ "x":true,//three
366
+ "y":58,
367
+ "z": [1,2,
368
+ 3 // six
369
+ ]}
370
+ }
371
+ obj = Oj.compat_load(json)
372
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
373
+ end
374
+
375
+ def test_comment_c
376
+ json = %{{
377
+ "x"/*one*/:/*two*/true,
378
+ "y":58,
379
+ "z": [1,2,3]}
380
+ }
381
+ obj = Oj.compat_load(json)
382
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
383
+ end
384
+
385
+ def test_comment
386
+ json = %{{
387
+ "x"/*one*/:/*two*/true,//three
388
+ "y":58/*four*/,
389
+ "z": [1,2/*five*/,
390
+ 3 // six
391
+ ]
392
+ }
393
+ }
394
+ obj = Oj.compat_load(json)
395
+ assert_equal({ 'x' => true, 'y' => 58, 'z' => [1, 2, 3]}, obj)
396
+ end
397
+
398
+ # If mimic_JSON has not been called then Oj.dump will call to_json on the
399
+ # top level object only.
400
+ def test_json_object_top
401
+ obj = Jeez.new(true, 58)
402
+ dump_to_json_and_load(obj, false)
403
+ end
404
+
405
+ # A child to_json should not be called.
406
+ def test_json_object_child
407
+ obj = { "child" => Jeez.new(true, 58) }
408
+ assert_equal('{"child":{"json_class":"CompatJuice::Jeez","x":true,"y":58}}', Oj.dump(obj))
409
+ end
410
+
411
+ def test_json_module_object
412
+ obj = One::Two::Three::Deep.new()
413
+ dump_to_json_and_load(obj, false)
414
+ end
415
+
416
+ def test_json_object_dump_create_id
417
+ expected = Jeez.new(true, 58)
418
+ json = Oj.to_json(expected)
419
+ obj = Oj.compat_load(json, :create_additions => true)
420
+ assert_equal(expected, obj)
421
+ end
422
+
423
+ def test_json_object_bad
424
+ json = %{{"json_class":"CompatJuice::Junk","x":true}}
425
+ begin
426
+ Oj.compat_load(json, :create_additions => true)
427
+ rescue Exception => e
428
+ assert_equal("ArgumentError", e.class().name)
429
+ return
430
+ end
431
+ assert(false, "*** expected an exception")
432
+ end
433
+
434
+ def test_json_object_create_cache
435
+ expected = Jeez.new(true, 58)
436
+ json = Oj.to_json(expected)
437
+ obj = Oj.compat_load(json, :class_cache => true, :create_additions => true)
438
+ assert_equal(expected, obj)
439
+ obj = Oj.compat_load(json, :class_cache => false, :create_additions => true)
440
+ assert_equal(expected, obj)
441
+ end
442
+
443
+ def test_json_object_create_id_other
444
+ expected = Jeez.new(true, 58)
445
+ json = Oj.to_json(expected)
446
+ json.gsub!('json_class', '_class_')
447
+ obj = Oj.compat_load(json, :create_id => "_class_", :create_additions => true)
448
+ assert_equal(expected, obj)
449
+ end
450
+
451
+ def test_json_object_create_deep
452
+ expected = One::Two::Three::Deep.new()
453
+ json = Oj.to_json(expected)
454
+ obj = Oj.compat_load(json, :create_additions => true)
455
+ assert_equal(expected, obj)
456
+ end
457
+
458
+ def test_range
459
+ json = Oj.dump(1..7)
460
+ assert_equal('"1..7"', json)
461
+ end
462
+
463
+ def test_arg_passing
464
+ json = Oj.to_json(Argy.new(), :max_nesting=> 40)
465
+ assert_equal(%|{"args":"[{:max_nesting=>40}]"}|, json)
466
+ end
467
+
468
+ def test_bad_unicode
469
+ assert_raises() { Oj.to_json("\xE4xy") }
470
+ end
471
+
472
+ def test_bad_unicode_e2
473
+ assert_raises() { Oj.to_json("L\xE2m ") }
474
+ end
475
+
476
+ def test_bad_unicode_start
477
+ assert_raises() { Oj.to_json("\x8abc") }
478
+ end
479
+
480
+ def test_parse_to_s
481
+ s = Stringy.new
482
+ assert_equal([1,2], Oj.load(s, :mode => :compat))
483
+ end
484
+
485
+ def dump_and_load(obj, trace=false)
486
+ json = Oj.dump(obj)
487
+ puts json if trace
488
+ loaded = Oj.compat_load(json, :create_additions => true);
489
+ if obj.nil?
490
+ assert_nil(loaded)
491
+ else
492
+ assert_equal(obj, loaded)
493
+ end
494
+ loaded
495
+ end
496
+
497
+ def dump_to_json_and_load(obj, trace=false)
498
+ json = Oj.to_json(obj, :indent => ' ')
499
+ puts json if trace
500
+ loaded = Oj.compat_load(json, :create_additions => true);
501
+ if obj.nil?
502
+ assert_nil(loaded)
503
+ else
504
+ assert_equal(obj, loaded)
505
+ end
506
+ loaded
507
+ end
508
+
509
+ end