json 1.8.3 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +5 -5
  2. data/{CHANGES → CHANGES.md} +241 -90
  3. data/Gemfile +10 -6
  4. data/{COPYING-json-jruby → LICENSE} +5 -6
  5. data/{README.rdoc → README.md} +201 -134
  6. data/VERSION +1 -1
  7. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  8. data/ext/json/ext/generator/generator.c +264 -104
  9. data/ext/json/ext/generator/generator.h +12 -4
  10. data/ext/json/ext/parser/extconf.rb +28 -0
  11. data/ext/json/ext/parser/parser.c +425 -462
  12. data/ext/json/ext/parser/parser.h +5 -5
  13. data/ext/json/ext/parser/parser.rl +181 -181
  14. data/ext/json/extconf.rb +1 -1
  15. data/json.gemspec +0 -0
  16. data/lib/json.rb +550 -29
  17. data/lib/json/add/bigdecimal.rb +3 -2
  18. data/lib/json/add/complex.rb +4 -4
  19. data/lib/json/add/core.rb +1 -0
  20. data/lib/json/add/date.rb +1 -1
  21. data/lib/json/add/date_time.rb +1 -1
  22. data/lib/json/add/exception.rb +1 -1
  23. data/lib/json/add/ostruct.rb +3 -3
  24. data/lib/json/add/range.rb +1 -1
  25. data/lib/json/add/rational.rb +3 -3
  26. data/lib/json/add/regexp.rb +3 -3
  27. data/lib/json/add/set.rb +29 -0
  28. data/lib/json/add/struct.rb +1 -1
  29. data/lib/json/add/symbol.rb +1 -1
  30. data/lib/json/add/time.rb +1 -1
  31. data/lib/json/common.rb +381 -162
  32. data/lib/json/ext.rb +0 -6
  33. data/lib/json/generic_object.rb +5 -4
  34. data/lib/json/pure.rb +2 -8
  35. data/lib/json/pure/generator.rb +83 -126
  36. data/lib/json/pure/parser.rb +62 -84
  37. data/lib/json/version.rb +2 -1
  38. data/tests/fixtures/fail29.json +1 -0
  39. data/tests/fixtures/fail30.json +1 -0
  40. data/tests/fixtures/fail31.json +1 -0
  41. data/tests/fixtures/fail32.json +1 -0
  42. data/tests/fixtures/obsolete_fail1.json +1 -0
  43. data/tests/{test_json_addition.rb → json_addition_test.rb} +28 -25
  44. data/tests/json_common_interface_test.rb +169 -0
  45. data/tests/json_encoding_test.rb +107 -0
  46. data/tests/json_ext_parser_test.rb +15 -0
  47. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +13 -8
  48. data/tests/{test_json_generate.rb → json_generator_test.rb} +109 -47
  49. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  50. data/tests/json_parser_test.rb +497 -0
  51. data/tests/json_string_matching_test.rb +38 -0
  52. data/tests/lib/core_assertions.rb +763 -0
  53. data/tests/lib/envutil.rb +365 -0
  54. data/tests/lib/find_executable.rb +22 -0
  55. data/tests/lib/helper.rb +4 -0
  56. data/tests/ractor_test.rb +30 -0
  57. data/tests/test_helper.rb +17 -0
  58. metadata +48 -76
  59. data/.gitignore +0 -16
  60. data/.travis.yml +0 -26
  61. data/COPYING +0 -58
  62. data/GPL +0 -340
  63. data/README-json-jruby.markdown +0 -33
  64. data/Rakefile +0 -412
  65. data/TODO +0 -1
  66. data/data/example.json +0 -1
  67. data/data/index.html +0 -38
  68. data/data/prototype.js +0 -4184
  69. data/diagrams/.keep +0 -0
  70. data/install.rb +0 -23
  71. data/java/src/json/ext/ByteListTranscoder.java +0 -167
  72. data/java/src/json/ext/Generator.java +0 -444
  73. data/java/src/json/ext/GeneratorMethods.java +0 -232
  74. data/java/src/json/ext/GeneratorService.java +0 -43
  75. data/java/src/json/ext/GeneratorState.java +0 -543
  76. data/java/src/json/ext/OptionsReader.java +0 -114
  77. data/java/src/json/ext/Parser.java +0 -2645
  78. data/java/src/json/ext/Parser.rl +0 -969
  79. data/java/src/json/ext/ParserService.java +0 -35
  80. data/java/src/json/ext/RuntimeInfo.java +0 -121
  81. data/java/src/json/ext/StringDecoder.java +0 -167
  82. data/java/src/json/ext/StringEncoder.java +0 -106
  83. data/java/src/json/ext/Utils.java +0 -89
  84. data/json-java.gemspec +0 -23
  85. data/json_pure.gemspec +0 -40
  86. data/tests/fixtures/fail1.json +0 -1
  87. data/tests/setup_variant.rb +0 -11
  88. data/tests/test_json.rb +0 -553
  89. data/tests/test_json_encoding.rb +0 -65
  90. data/tests/test_json_string_matching.rb +0 -39
  91. data/tests/test_json_unicode.rb +0 -72
  92. data/tools/fuzz.rb +0 -139
  93. data/tools/server.rb +0 -62
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'test/unit'
5
- require File.join(File.dirname(__FILE__), 'setup_variant')
6
-
7
- class TestJSONEncoding < Test::Unit::TestCase
8
- include JSON
9
-
10
- def setup
11
- @utf_8 = '["© ≠ €!"]'
12
- @parsed = [ "© ≠ €!" ]
13
- @generated = '["\u00a9 \u2260 \u20ac!"]'
14
- if String.method_defined?(:encode)
15
- @utf_16_data = [@parsed.first.encode('utf-16be', 'utf-8')]
16
- @utf_8_ascii_8bit = @utf_8.dup.force_encoding(Encoding::ASCII_8BIT)
17
- @utf_16be = @utf_8.encode('utf-16be', 'utf-8')
18
- @utf_16be_ascii_8bit = @utf_16be.dup.force_encoding(Encoding::ASCII_8BIT)
19
- @utf_16le = @utf_8.encode('utf-16le', 'utf-8')
20
- @utf_16le_ascii_8bit = @utf_16le.dup.force_encoding(Encoding::ASCII_8BIT)
21
- @utf_32be = @utf_8.encode('utf-32be', 'utf-8')
22
- @utf_32be_ascii_8bit = @utf_32be.dup.force_encoding(Encoding::ASCII_8BIT)
23
- @utf_32le = @utf_8.encode('utf-32le', 'utf-8')
24
- @utf_32le_ascii_8bit = @utf_32le.dup.force_encoding(Encoding::ASCII_8BIT)
25
- else
26
- require 'iconv'
27
- @utf_16_data = Iconv.iconv('utf-16be', 'utf-8', @parsed.first)
28
- @utf_8_ascii_8bit = @utf_8.dup
29
- @utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8)
30
- @utf_16be_ascii_8bit = @utf_16be.dup
31
- @utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8)
32
- @utf_16le_ascii_8bit = @utf_16le.dup
33
- @utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8)
34
- @utf_32be_ascii_8bit = @utf_32be.dup
35
- @utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8)
36
- @utf_32le_ascii_8bit = @utf_32le.dup
37
- end
38
- end
39
-
40
- def test_parse
41
- assert_equal @parsed, JSON.parse(@utf_8)
42
- assert_equal @parsed, JSON.parse(@utf_16be)
43
- assert_equal @parsed, JSON.parse(@utf_16le)
44
- assert_equal @parsed, JSON.parse(@utf_32be)
45
- assert_equal @parsed, JSON.parse(@utf_32le)
46
- end
47
-
48
- def test_parse_ascii_8bit
49
- assert_equal @parsed, JSON.parse(@utf_8_ascii_8bit)
50
- assert_equal @parsed, JSON.parse(@utf_16be_ascii_8bit)
51
- assert_equal @parsed, JSON.parse(@utf_16le_ascii_8bit)
52
- assert_equal @parsed, JSON.parse(@utf_32be_ascii_8bit)
53
- assert_equal @parsed, JSON.parse(@utf_32le_ascii_8bit)
54
- end
55
-
56
- def test_generate
57
- assert_equal @generated, JSON.generate(@parsed, :ascii_only => true)
58
- if defined?(::Encoding)
59
- assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true)
60
- else
61
- # XXX checking of correct utf8 data is not as strict (yet?) without :ascii_only
62
- assert_raises(JSON::GeneratorError) { JSON.generate(@utf_16_data, :ascii_only => true) }
63
- end
64
- end
65
- end
@@ -1,39 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'test/unit'
5
- require File.join(File.dirname(__FILE__), 'setup_variant')
6
- require 'stringio'
7
- require 'time'
8
-
9
- class TestJSONStringMatching < Test::Unit::TestCase
10
- include JSON
11
-
12
- class TestTime < ::Time
13
- def self.json_create(string)
14
- Time.parse(string)
15
- end
16
-
17
- def to_json(*)
18
- %{"#{strftime('%FT%T%z')}"}
19
- end
20
-
21
- def ==(other)
22
- to_i == other.to_i
23
- end
24
- end
25
-
26
- def test_match_date
27
- t = TestTime.new
28
- t_json = [ t ].to_json
29
- assert_equal [ t ],
30
- JSON.parse(t_json, :create_additions => true,
31
- :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime })
32
- assert_equal [ t.strftime('%FT%T%z') ],
33
- JSON.parse(t_json, :create_additions => true,
34
- :match_string => { /\A\d{3}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime })
35
- assert_equal [ t.strftime('%FT%T%z') ],
36
- JSON.parse(t_json,
37
- :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime })
38
- end
39
- end
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'test/unit'
5
- require File.join(File.dirname(__FILE__), 'setup_variant')
6
-
7
- class TestJSONUnicode < Test::Unit::TestCase
8
- include JSON
9
-
10
- def test_unicode
11
- assert_equal '""', ''.to_json
12
- assert_equal '"\\b"', "\b".to_json
13
- assert_equal '"\u0001"', 0x1.chr.to_json
14
- assert_equal '"\u001f"', 0x1f.chr.to_json
15
- assert_equal '" "', ' '.to_json
16
- assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
17
- utf8 = [ "© ≠ €! \01" ]
18
- json = '["© ≠ €! \u0001"]'
19
- assert_equal json, utf8.to_json(:ascii_only => false)
20
- assert_equal utf8, parse(json)
21
- json = '["\u00a9 \u2260 \u20ac! \u0001"]'
22
- assert_equal json, utf8.to_json(:ascii_only => true)
23
- assert_equal utf8, parse(json)
24
- utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
25
- json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]"
26
- assert_equal utf8, parse(json)
27
- assert_equal json, utf8.to_json(:ascii_only => false)
28
- utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
29
- assert_equal utf8, parse(json)
30
- json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]"
31
- assert_equal json, utf8.to_json(:ascii_only => true)
32
- assert_equal utf8, parse(json)
33
- utf8 = ['საქართველო']
34
- json = '["საქართველო"]'
35
- assert_equal json, utf8.to_json(:ascii_only => false)
36
- json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]"
37
- assert_equal json, utf8.to_json(:ascii_only => true)
38
- assert_equal utf8, parse(json)
39
- assert_equal '["Ã"]', JSON.generate(["Ã"], :ascii_only => false)
40
- assert_equal '["\\u00c3"]', JSON.generate(["Ã"], :ascii_only => true)
41
- assert_equal ["€"], JSON.parse('["\u20ac"]')
42
- utf8 = ["\xf0\xa0\x80\x81"]
43
- json = "[\"\xf0\xa0\x80\x81\"]"
44
- assert_equal json, JSON.generate(utf8, :ascii_only => false)
45
- assert_equal utf8, JSON.parse(json)
46
- json = '["\ud840\udc01"]'
47
- assert_equal json, JSON.generate(utf8, :ascii_only => true)
48
- assert_equal utf8, JSON.parse(json)
49
- end
50
-
51
- def test_chars
52
- (0..0x7f).each do |i|
53
- json = '["\u%04x"]' % i
54
- if RUBY_VERSION >= "1.9."
55
- i = i.chr
56
- end
57
- assert_equal i, JSON.parse(json).first[0]
58
- if i == ?\b
59
- generated = JSON.generate(["" << i])
60
- assert '["\b"]' == generated || '["\10"]' == generated
61
- elsif [?\n, ?\r, ?\t, ?\f].include?(i)
62
- assert_equal '[' << ('' << i).dump << ']', JSON.generate(["" << i])
63
- elsif i.chr < 0x20.chr
64
- assert_equal json, JSON.generate(["" << i])
65
- end
66
- end
67
- assert_raise(JSON::GeneratorError) do
68
- JSON.generate(["\x80"], :ascii_only => true)
69
- end
70
- assert_equal "\302\200", JSON.parse('["\u0080"]').first
71
- end
72
- end
data/tools/fuzz.rb DELETED
@@ -1,139 +0,0 @@
1
- require 'json'
2
-
3
- require 'iconv'
4
- ISO_8859_1_TO_UTF8 = Iconv.new('utf-8', 'iso-8859-15')
5
- class ::String
6
- def to_utf8
7
- ISO_8859_1_TO_UTF8.iconv self
8
- end
9
- end
10
-
11
- class Fuzzer
12
- def initialize(n, freqs = {})
13
- sum = freqs.inject(0.0) { |s, x| s + x.last }
14
- freqs.each_key { |x| freqs[x] /= sum }
15
- s = 0.0
16
- freqs.each_key do |x|
17
- freqs[x] = s .. (s + t = freqs[x])
18
- s += t
19
- end
20
- @freqs = freqs
21
- @n = n
22
- @alpha = (0..0xff).to_a
23
- end
24
-
25
- def random_string
26
- s = ''
27
- 30.times { s << @alpha[rand(@alpha.size)] }
28
- s.to_utf8
29
- end
30
-
31
- def pick
32
- r = rand
33
- found = @freqs.find { |k, f| f.include? rand }
34
- found && found.first
35
- end
36
-
37
- def make_pick
38
- k = pick
39
- case
40
- when k == Hash, k == Array
41
- k.new
42
- when k == true, k == false, k == nil
43
- k
44
- when k == String
45
- random_string
46
- when k == Fixnum
47
- rand(2 ** 30) - 2 ** 29
48
- when k == Bignum
49
- rand(2 ** 70) - 2 ** 69
50
- end
51
- end
52
-
53
- def fuzz(current = nil)
54
- if @n > 0
55
- case current
56
- when nil
57
- @n -= 1
58
- current = fuzz [ Hash, Array ][rand(2)].new
59
- when Array
60
- while @n > 0
61
- @n -= 1
62
- current << case p = make_pick
63
- when Array, Hash
64
- fuzz(p)
65
- else
66
- p
67
- end
68
- end
69
- when Hash
70
- while @n > 0
71
- @n -= 1
72
- current[random_string] = case p = make_pick
73
- when Array, Hash
74
- fuzz(p)
75
- else
76
- p
77
- end
78
- end
79
- end
80
- end
81
- current
82
- end
83
- end
84
-
85
- class MyState < JSON.state
86
- WS = " \r\t\n"
87
-
88
- def initialize
89
- super(
90
- :indent => make_spaces,
91
- :space => make_spaces,
92
- :space_before => make_spaces,
93
- :object_nl => make_spaces,
94
- :array_nl => make_spaces,
95
- :max_nesting => false
96
- )
97
- end
98
-
99
- def make_spaces
100
- s = ''
101
- rand(1).times { s << WS[rand(WS.size)] }
102
- s
103
- end
104
- end
105
-
106
- n = (ARGV.shift || 500).to_i
107
- loop do
108
- fuzzer = Fuzzer.new(n,
109
- Hash => 25,
110
- Array => 25,
111
- String => 10,
112
- Fixnum => 10,
113
- Bignum => 10,
114
- nil => 5,
115
- true => 5,
116
- false => 5
117
- )
118
- o1 = fuzzer.fuzz
119
- json = JSON.generate o1, MyState.new
120
- if $DEBUG
121
- puts "-" * 80
122
- puts json, json.size
123
- else
124
- puts json.size
125
- end
126
- begin
127
- o2 = JSON.parse(json, :max_nesting => false)
128
- rescue JSON::ParserError => e
129
- puts "Caught #{e.class}: #{e.message}\n#{e.backtrace * "\n"}"
130
- puts "o1 = #{o1.inspect}", "json = #{json}", "json_str = #{json.inspect}"
131
- puts "locals = #{local_variables.inspect}"
132
- exit
133
- end
134
- if o1 != o2
135
- puts "mismatch", "o1 = #{o1.inspect}", "o2 = #{o2.inspect}",
136
- "json = #{json}", "json_str = #{json.inspect}"
137
- puts "locals = #{local_variables.inspect}"
138
- end
139
- end
data/tools/server.rb DELETED
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'webrick'
5
- include WEBrick
6
- $:.unshift 'ext'
7
- $:.unshift 'lib'
8
- require 'json'
9
-
10
- class JSONServlet < HTTPServlet::AbstractServlet
11
- @@count = 1
12
-
13
- def do_GET(req, res)
14
- obj = {
15
- "TIME" => Time.now.strftime("%FT%T"),
16
- "foo" => "Bär",
17
- "bar" => "© ≠ €!",
18
- 'a' => 2,
19
- 'b' => 3.141,
20
- 'COUNT' => @@count += 1,
21
- 'c' => 'c',
22
- 'd' => [ 1, "b", 3.14 ],
23
- 'e' => { 'foo' => 'bar' },
24
- 'g' => "松本行弘",
25
- 'h' => 1000.0,
26
- 'i' => 0.001,
27
- 'j' => "\xf0\xa0\x80\x81",
28
- }
29
- res.body = JSON.generate obj
30
- res['Content-Type'] = "application/json"
31
- end
32
- end
33
-
34
- def create_server(err, dir, port)
35
- dir = File.expand_path(dir)
36
- err.puts "Surf to:", "http://#{Socket.gethostname}:#{port}"
37
-
38
- s = HTTPServer.new(
39
- :Port => port,
40
- :DocumentRoot => dir,
41
- :Logger => WEBrick::Log.new(err),
42
- :AccessLog => [
43
- [ err, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
44
- [ err, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
45
- [ err, WEBrick::AccessLog::AGENT_LOG_FORMAT ]
46
- ]
47
- )
48
- s.mount("/json", JSONServlet)
49
- s
50
- end
51
-
52
- default_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'data'))
53
- dir = ARGV.shift || default_dir
54
- port = (ARGV.shift || 6666).to_i
55
- s = create_server(STDERR, dir, 6666)
56
- t = Thread.new { s.start }
57
- trap(:INT) do
58
- s.shutdown
59
- t.join
60
- exit
61
- end
62
- sleep