oortle-yajl-ruby 0.5.8
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.
- data/.gitignore +6 -0
- data/CHANGELOG.md +177 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +270 -0
- data/Rakefile +35 -0
- data/VERSION.yml +4 -0
- data/benchmark/encode.rb +46 -0
- data/benchmark/encode_json_and_marshal.rb +35 -0
- data/benchmark/encode_json_and_yaml.rb +47 -0
- data/benchmark/http.rb +30 -0
- data/benchmark/parse.rb +49 -0
- data/benchmark/parse_json_and_marshal.rb +47 -0
- data/benchmark/parse_json_and_yaml.rb +56 -0
- data/benchmark/parse_stream.rb +48 -0
- data/benchmark/subjects/item.json +1 -0
- data/benchmark/subjects/ohai.json +1216 -0
- data/benchmark/subjects/ohai.marshal_dump +0 -0
- data/benchmark/subjects/ohai.yml +975 -0
- data/benchmark/subjects/twitter_search.json +1 -0
- data/benchmark/subjects/twitter_stream.json +430 -0
- data/benchmark/subjects/unicode.json +1 -0
- data/examples/http/twitter_search_api.rb +15 -0
- data/examples/http/twitter_stream_api.rb +27 -0
- data/examples/parsing/from_file.rb +14 -0
- data/examples/parsing/from_stdin.rb +9 -0
- data/examples/parsing/from_string.rb +15 -0
- data/ext/api/yajl_common.h +85 -0
- data/ext/api/yajl_gen.h +123 -0
- data/ext/api/yajl_parse.h +182 -0
- data/ext/extconf.rb +8 -0
- data/ext/yajl.c +157 -0
- data/ext/yajl_alloc.c +65 -0
- data/ext/yajl_alloc.h +50 -0
- data/ext/yajl_buf.c +119 -0
- data/ext/yajl_buf.h +73 -0
- data/ext/yajl_bytestack.h +85 -0
- data/ext/yajl_encode.c +179 -0
- data/ext/yajl_encode.h +44 -0
- data/ext/yajl_ext.c +774 -0
- data/ext/yajl_ext.h +74 -0
- data/ext/yajl_gen.c +290 -0
- data/ext/yajl_lex.c +744 -0
- data/ext/yajl_lex.h +135 -0
- data/ext/yajl_parser.c +447 -0
- data/ext/yajl_parser.h +79 -0
- data/lib/yajl.rb +80 -0
- data/lib/yajl/bzip2.rb +11 -0
- data/lib/yajl/bzip2/stream_reader.rb +29 -0
- data/lib/yajl/bzip2/stream_writer.rb +15 -0
- data/lib/yajl/deflate.rb +6 -0
- data/lib/yajl/deflate/stream_reader.rb +38 -0
- data/lib/yajl/deflate/stream_writer.rb +21 -0
- data/lib/yajl/gzip.rb +6 -0
- data/lib/yajl/gzip/stream_reader.rb +28 -0
- data/lib/yajl/gzip/stream_writer.rb +14 -0
- data/lib/yajl/http_stream.rb +150 -0
- data/lib/yajl/json_gem.rb +14 -0
- data/lib/yajl/json_gem/encoding.rb +40 -0
- data/lib/yajl/json_gem/parsing.rb +26 -0
- data/spec/encoding/encoding_spec.rb +186 -0
- data/spec/http/fixtures/http.bzip2.dump +0 -0
- data/spec/http/fixtures/http.deflate.dump +0 -0
- data/spec/http/fixtures/http.gzip.dump +0 -0
- data/spec/http/fixtures/http.raw.dump +1226 -0
- data/spec/http/http_spec.rb +158 -0
- data/spec/json_gem_compatibility/compatibility_spec.rb +178 -0
- data/spec/parsing/active_support_spec.rb +64 -0
- data/spec/parsing/chunked_spec.rb +98 -0
- data/spec/parsing/fixtures/fail.15.json +1 -0
- data/spec/parsing/fixtures/fail.16.json +1 -0
- data/spec/parsing/fixtures/fail.17.json +1 -0
- data/spec/parsing/fixtures/fail.26.json +1 -0
- data/spec/parsing/fixtures/fail11.json +1 -0
- data/spec/parsing/fixtures/fail12.json +1 -0
- data/spec/parsing/fixtures/fail13.json +1 -0
- data/spec/parsing/fixtures/fail14.json +1 -0
- data/spec/parsing/fixtures/fail19.json +1 -0
- data/spec/parsing/fixtures/fail20.json +1 -0
- data/spec/parsing/fixtures/fail21.json +1 -0
- data/spec/parsing/fixtures/fail22.json +1 -0
- data/spec/parsing/fixtures/fail23.json +1 -0
- data/spec/parsing/fixtures/fail24.json +1 -0
- data/spec/parsing/fixtures/fail25.json +1 -0
- data/spec/parsing/fixtures/fail27.json +2 -0
- data/spec/parsing/fixtures/fail28.json +2 -0
- data/spec/parsing/fixtures/fail3.json +1 -0
- data/spec/parsing/fixtures/fail4.json +1 -0
- data/spec/parsing/fixtures/fail5.json +1 -0
- data/spec/parsing/fixtures/fail6.json +1 -0
- data/spec/parsing/fixtures/fail9.json +1 -0
- data/spec/parsing/fixtures/pass.array.json +6 -0
- data/spec/parsing/fixtures/pass.codepoints_from_unicode_org.json +1 -0
- data/spec/parsing/fixtures/pass.contacts.json +1 -0
- data/spec/parsing/fixtures/pass.db100.xml.json +1 -0
- data/spec/parsing/fixtures/pass.db1000.xml.json +1 -0
- data/spec/parsing/fixtures/pass.dc_simple_with_comments.json +11 -0
- data/spec/parsing/fixtures/pass.deep_arrays.json +1 -0
- data/spec/parsing/fixtures/pass.difficult_json_c_test_case.json +1 -0
- data/spec/parsing/fixtures/pass.difficult_json_c_test_case_with_comments.json +1 -0
- data/spec/parsing/fixtures/pass.doubles.json +1 -0
- data/spec/parsing/fixtures/pass.empty_array.json +1 -0
- data/spec/parsing/fixtures/pass.empty_string.json +1 -0
- data/spec/parsing/fixtures/pass.escaped_bulgarian.json +4 -0
- data/spec/parsing/fixtures/pass.escaped_foobar.json +1 -0
- data/spec/parsing/fixtures/pass.item.json +1 -0
- data/spec/parsing/fixtures/pass.json-org-sample1.json +23 -0
- data/spec/parsing/fixtures/pass.json-org-sample2.json +11 -0
- data/spec/parsing/fixtures/pass.json-org-sample3.json +26 -0
- data/spec/parsing/fixtures/pass.json-org-sample4-nows.json +88 -0
- data/spec/parsing/fixtures/pass.json-org-sample4.json +89 -0
- data/spec/parsing/fixtures/pass.json-org-sample5.json +27 -0
- data/spec/parsing/fixtures/pass.map-spain.xml.json +1 -0
- data/spec/parsing/fixtures/pass.ns-invoice100.xml.json +1 -0
- data/spec/parsing/fixtures/pass.ns-soap.xml.json +1 -0
- data/spec/parsing/fixtures/pass.numbers-fp-4k.json +6 -0
- data/spec/parsing/fixtures/pass.numbers-fp-64k.json +61 -0
- data/spec/parsing/fixtures/pass.numbers-int-4k.json +11 -0
- data/spec/parsing/fixtures/pass.numbers-int-64k.json +154 -0
- data/spec/parsing/fixtures/pass.twitter-search.json +1 -0
- data/spec/parsing/fixtures/pass.twitter-search2.json +1 -0
- data/spec/parsing/fixtures/pass.unicode.json +3315 -0
- data/spec/parsing/fixtures/pass.yelp.json +1 -0
- data/spec/parsing/fixtures/pass1.json +56 -0
- data/spec/parsing/fixtures/pass2.json +1 -0
- data/spec/parsing/fixtures/pass3.json +6 -0
- data/spec/parsing/fixtures_spec.rb +41 -0
- data/spec/parsing/one_off_spec.rb +54 -0
- data/spec/rcov.opts +4 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +6 -0
- data/yajl-ruby.gemspec +179 -0
- metadata +198 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
|
|
3
|
+
require 'yajl/bzip2'
|
|
4
|
+
require 'yajl/gzip'
|
|
5
|
+
require 'yajl/deflate'
|
|
6
|
+
require 'yajl/http_stream'
|
|
7
|
+
|
|
8
|
+
def parse_off_headers(io)
|
|
9
|
+
io.each_line do |line|
|
|
10
|
+
if line == "\r\n" # end of the headers
|
|
11
|
+
break
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "Yajl HTTP GET request" do
|
|
17
|
+
before(:all) do
|
|
18
|
+
raw = File.new(File.expand_path(File.dirname(__FILE__) + '/fixtures/http.raw.dump'), 'r')
|
|
19
|
+
parse_off_headers(raw)
|
|
20
|
+
@template_hash = Yajl::Parser.parse(raw)
|
|
21
|
+
|
|
22
|
+
raw.rewind
|
|
23
|
+
parse_off_headers(raw)
|
|
24
|
+
@template_hash_symbolized = Yajl::Parser.parse(raw, :symbolize_keys => true)
|
|
25
|
+
|
|
26
|
+
@deflate = File.new(File.expand_path(File.dirname(__FILE__) + '/fixtures/http.deflate.dump'), 'r')
|
|
27
|
+
@gzip = File.new(File.expand_path(File.dirname(__FILE__) + '/fixtures/http.gzip.dump'), 'r')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
after(:each) do
|
|
31
|
+
@file_path = nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def prepare_mock_request_dump(format=:raw)
|
|
35
|
+
@request = File.new(File.expand_path(File.dirname(__FILE__) + "/fixtures/http.#{format}.dump"), 'r')
|
|
36
|
+
@uri = 'file://'+File.expand_path(File.dirname(__FILE__) + "/fixtures/http/http.#{format}.dump")
|
|
37
|
+
TCPSocket.should_receive(:new).and_return(@request)
|
|
38
|
+
@request.should_receive(:write)
|
|
39
|
+
@uri.should_receive(:host).at_least(2).times
|
|
40
|
+
@uri.should_receive(:port)
|
|
41
|
+
@uri.should_receive(:path)
|
|
42
|
+
@uri.should_receive(:query)
|
|
43
|
+
@uri.should_receive(:userinfo)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should parse a raw response" do
|
|
47
|
+
prepare_mock_request_dump :raw
|
|
48
|
+
@template_hash.should == Yajl::HttpStream.get(@uri)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should parse a raw response and symbolize keys" do
|
|
52
|
+
prepare_mock_request_dump :raw
|
|
53
|
+
@template_hash_symbolized.should == Yajl::HttpStream.get(@uri, :symbolize_keys => true)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should parse a bzip2 compressed response" do
|
|
57
|
+
prepare_mock_request_dump :bzip2
|
|
58
|
+
@template_hash.should == Yajl::HttpStream.get(@uri)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should parse a bzip2 compressed response and symbolize keys" do
|
|
62
|
+
prepare_mock_request_dump :bzip2
|
|
63
|
+
@template_hash_symbolized.should == Yajl::HttpStream.get(@uri, :symbolize_keys => true)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should parse a deflate compressed response" do
|
|
67
|
+
prepare_mock_request_dump :deflate
|
|
68
|
+
@template_hash.should == Yajl::HttpStream.get(@uri)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should parse a deflate compressed response and symbolize keys" do
|
|
72
|
+
prepare_mock_request_dump :deflate
|
|
73
|
+
@template_hash_symbolized.should == Yajl::HttpStream.get(@uri, :symbolize_keys => true)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should parse a gzip compressed response" do
|
|
77
|
+
prepare_mock_request_dump :gzip
|
|
78
|
+
@template_hash.should == Yajl::HttpStream.get(@uri)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should parse a gzip compressed response and symbolize keys" do
|
|
82
|
+
prepare_mock_request_dump :gzip
|
|
83
|
+
@template_hash_symbolized.should == Yajl::HttpStream.get(@uri, :symbolize_keys => true)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe "Yajl HTTP POST request" do
|
|
88
|
+
before(:all) do
|
|
89
|
+
raw = File.new(File.expand_path(File.dirname(__FILE__) + '/fixtures/http.raw.dump'), 'r')
|
|
90
|
+
parse_off_headers(raw)
|
|
91
|
+
@template_hash = Yajl::Parser.parse(raw)
|
|
92
|
+
|
|
93
|
+
raw.rewind
|
|
94
|
+
parse_off_headers(raw)
|
|
95
|
+
@template_hash_symbolized = Yajl::Parser.parse(raw, :symbolize_keys => true)
|
|
96
|
+
|
|
97
|
+
@deflate = File.new(File.expand_path(File.dirname(__FILE__) + '/fixtures/http.deflate.dump'), 'r')
|
|
98
|
+
@gzip = File.new(File.expand_path(File.dirname(__FILE__) + '/fixtures/http.gzip.dump'), 'r')
|
|
99
|
+
|
|
100
|
+
@params = {:a => 1, :b => 'has spaces'}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
after(:each) do
|
|
104
|
+
@file_path = nil
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def prepare_mock_request_dump(format=:raw)
|
|
108
|
+
@request = File.new(File.expand_path(File.dirname(__FILE__) + "/fixtures/http.#{format}.dump"), 'r')
|
|
109
|
+
@uri = 'file://'+File.expand_path(File.dirname(__FILE__) + "/fixtures/http/http.#{format}.dump")
|
|
110
|
+
TCPSocket.should_receive(:new).and_return(@request)
|
|
111
|
+
@request.should_receive(:write)
|
|
112
|
+
@uri.should_receive(:host).at_least(2).times
|
|
113
|
+
@uri.should_receive(:port)
|
|
114
|
+
@uri.should_receive(:path)
|
|
115
|
+
@uri.should_receive(:query)
|
|
116
|
+
@uri.should_receive(:userinfo)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should parse a raw response" do
|
|
120
|
+
prepare_mock_request_dump :raw
|
|
121
|
+
@template_hash.should == Yajl::HttpStream.post(@uri, @params)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should parse a raw response and symbolize keys" do
|
|
125
|
+
prepare_mock_request_dump :raw
|
|
126
|
+
@template_hash_symbolized.should == Yajl::HttpStream.post(@uri, @params, :symbolize_keys => true)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "should parse a bzip2 compressed response" do
|
|
130
|
+
prepare_mock_request_dump :bzip2
|
|
131
|
+
@template_hash.should == Yajl::HttpStream.post(@uri, @params)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "should parse a bzip2 compressed response and symbolize keys" do
|
|
135
|
+
prepare_mock_request_dump :bzip2
|
|
136
|
+
@template_hash_symbolized.should == Yajl::HttpStream.post(@uri, @params, :symbolize_keys => true)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "should parse a deflate compressed response" do
|
|
140
|
+
prepare_mock_request_dump :deflate
|
|
141
|
+
@template_hash.should == Yajl::HttpStream.post(@uri, @params)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should parse a deflate compressed response and symbolize keys" do
|
|
145
|
+
prepare_mock_request_dump :deflate
|
|
146
|
+
@template_hash_symbolized.should == Yajl::HttpStream.post(@uri, @params, :symbolize_keys => true)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "should parse a gzip compressed response" do
|
|
150
|
+
prepare_mock_request_dump :gzip
|
|
151
|
+
@template_hash.should == Yajl::HttpStream.post(@uri, @params)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "should parse a gzip compressed response and symbolize keys" do
|
|
155
|
+
prepare_mock_request_dump :gzip
|
|
156
|
+
@template_hash_symbolized.should == Yajl::HttpStream.post(@uri, @params, :symbolize_keys => true)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
|
|
3
|
+
|
|
4
|
+
class Dummy; end
|
|
5
|
+
|
|
6
|
+
describe "JSON Gem compatability API" do
|
|
7
|
+
it "shoud not mixin #to_json on base objects until compatability has been enabled" do
|
|
8
|
+
d = Dummy.new
|
|
9
|
+
|
|
10
|
+
d.respond_to?(:to_json).should_not be_true
|
|
11
|
+
"".respond_to?(:to_json).should_not be_true
|
|
12
|
+
1.respond_to?(:to_json).should_not be_true
|
|
13
|
+
"1.5".to_f.respond_to?(:to_json).should_not be_true
|
|
14
|
+
[].respond_to?(:to_json).should_not be_true
|
|
15
|
+
{:foo => "bar"}.respond_to?(:to_json).should_not be_true
|
|
16
|
+
true.respond_to?(:to_json).should_not be_true
|
|
17
|
+
false.respond_to?(:to_json).should_not be_true
|
|
18
|
+
nil.respond_to?(:to_json).should_not be_true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should mixin #to_json on base objects after compatability has been enabled" do
|
|
22
|
+
Yajl::Encoder.enable_json_gem_compatability
|
|
23
|
+
d = Dummy.new
|
|
24
|
+
|
|
25
|
+
d.respond_to?(:to_json).should be_true
|
|
26
|
+
"".respond_to?(:to_json).should be_true
|
|
27
|
+
1.respond_to?(:to_json).should be_true
|
|
28
|
+
"1.5".to_f.respond_to?(:to_json).should be_true
|
|
29
|
+
[].respond_to?(:to_json).should be_true
|
|
30
|
+
{:foo => "bar"}.respond_to?(:to_json).should be_true
|
|
31
|
+
true.respond_to?(:to_json).should be_true
|
|
32
|
+
false.respond_to?(:to_json).should be_true
|
|
33
|
+
nil.respond_to?(:to_json).should be_true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should require yajl/json_gem to enable the compatability API" do
|
|
37
|
+
require 'yajl/json_gem'
|
|
38
|
+
|
|
39
|
+
defined?(JSON).should be_true
|
|
40
|
+
|
|
41
|
+
JSON.respond_to?(:parse).should be_true
|
|
42
|
+
JSON.respond_to?(:generate).should be_true
|
|
43
|
+
JSON.respond_to?(:pretty_generate).should be_true
|
|
44
|
+
JSON.respond_to?(:load).should be_true
|
|
45
|
+
JSON.respond_to?(:dump).should be_true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should allow default parsing options be set with JSON.default_options" do
|
|
49
|
+
default = JSON.default_options[:symbolize_keys]
|
|
50
|
+
JSON.parse('{"foo": 1234}').should === {"foo" => 1234}
|
|
51
|
+
JSON.default_options[:symbolize_keys] = true
|
|
52
|
+
JSON.parse('{"foo": 1234}').should === {:foo => 1234}
|
|
53
|
+
JSON.default_options[:symbolize_keys] = default # ensure the rest of the test cases expect the default
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "ported tests for Unicode" do
|
|
57
|
+
it "should be able to encode and parse unicode" do
|
|
58
|
+
pending if RUBY_VERSION.include?('1.9') # FIXME: Some string encoding problem with 1.9
|
|
59
|
+
'""'.should eql(''.to_json)
|
|
60
|
+
'"\\b"'.should eql("\b".to_json)
|
|
61
|
+
'"\u0001"'.should eql(0x1.chr.to_json)
|
|
62
|
+
'"\u001F"'.should eql(0x1f.chr.to_json)
|
|
63
|
+
'" "'.should eql(' '.to_json)
|
|
64
|
+
"\"#{0x7f.chr}\"".should eql(0x7f.chr.to_json)
|
|
65
|
+
utf8 = [ "© ≠ €! \01" ]
|
|
66
|
+
json = '["© ≠ €! \u0001"]'
|
|
67
|
+
json.should eql(utf8.to_json)
|
|
68
|
+
utf8.should eql(JSON.parse(json))
|
|
69
|
+
utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
|
|
70
|
+
json = "[\"あいうえお\"]"
|
|
71
|
+
json.should eql(utf8.to_json)
|
|
72
|
+
utf8.should eql(JSON.parse(json))
|
|
73
|
+
utf8 = ['საქართველო']
|
|
74
|
+
json = "[\"საქართველო\"]"
|
|
75
|
+
json.should eql(utf8.to_json)
|
|
76
|
+
utf8.should eql(JSON.parse(json))
|
|
77
|
+
'["Ã"]'.should eql(JSON.generate(["Ã"]))
|
|
78
|
+
["€"].should eql(JSON.parse('["\u20ac"]'))
|
|
79
|
+
utf8_str = "\xf0\xa0\x80\x81"
|
|
80
|
+
utf8 = [utf8_str]
|
|
81
|
+
json = "[\"#{utf8_str}\"]"
|
|
82
|
+
json.should eql(JSON.generate(utf8))
|
|
83
|
+
utf8.should eql(JSON.parse(json))
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "ported tests for generation" do
|
|
88
|
+
before(:all) do
|
|
89
|
+
@hash = {
|
|
90
|
+
'a' => 2,
|
|
91
|
+
'b' => 3.141,
|
|
92
|
+
'c' => 'c',
|
|
93
|
+
'd' => [ 1, "b", 3.14 ],
|
|
94
|
+
'e' => { 'foo' => 'bar' },
|
|
95
|
+
'g' => "blah",
|
|
96
|
+
'h' => 1000.0,
|
|
97
|
+
'i' => 0.001
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},"g":"blah","h":1000.0,"i":0.001}'
|
|
101
|
+
|
|
102
|
+
@json3 = %{
|
|
103
|
+
{
|
|
104
|
+
"a": 2,
|
|
105
|
+
"b": 3.141,
|
|
106
|
+
"c": "c",
|
|
107
|
+
"d": [1, "b", 3.14],
|
|
108
|
+
"e": {"foo": "bar"},
|
|
109
|
+
"g": "blah",
|
|
110
|
+
"h": 1000.0,
|
|
111
|
+
"i": 0.001
|
|
112
|
+
}
|
|
113
|
+
}.chomp
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should be able to unparse" do
|
|
117
|
+
json = JSON.generate(@hash)
|
|
118
|
+
JSON.parse(@json2).should == JSON.parse(json)
|
|
119
|
+
parsed_json = JSON.parse(json)
|
|
120
|
+
@hash.should == parsed_json
|
|
121
|
+
json = JSON.generate({1=>2})
|
|
122
|
+
'{"1":2}'.should eql(json)
|
|
123
|
+
parsed_json = JSON.parse(json)
|
|
124
|
+
{"1"=>2}.should == parsed_json
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should be able to unparse pretty" do
|
|
128
|
+
json = JSON.pretty_generate(@hash)
|
|
129
|
+
JSON.parse(@json3).should == JSON.parse(json)
|
|
130
|
+
parsed_json = JSON.parse(json)
|
|
131
|
+
@hash.should == parsed_json
|
|
132
|
+
json = JSON.pretty_generate({1=>2})
|
|
133
|
+
test = "{\n \"1\": 2\n}".chomp
|
|
134
|
+
test.should == json
|
|
135
|
+
parsed_json = JSON.parse(json)
|
|
136
|
+
{"1"=>2}.should == parsed_json
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
context "ported fixture tests" do
|
|
141
|
+
fixtures = File.join(File.dirname(__FILE__), '../parsing/fixtures/*.json')
|
|
142
|
+
passed, failed = Dir[fixtures].partition { |f| f['pass'] }
|
|
143
|
+
JSON_PASSED = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
|
|
144
|
+
JSON_FAILED = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
|
|
145
|
+
|
|
146
|
+
JSON_FAILED.each do |name, source|
|
|
147
|
+
it "should not be able to parse #{File.basename(name)} as an IO" do
|
|
148
|
+
lambda {
|
|
149
|
+
JSON.parse(StringIO.new(source))
|
|
150
|
+
}.should raise_error(Yajl::ParseError)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
JSON_FAILED.each do |name, source|
|
|
155
|
+
it "should not be able to parse #{File.basename(name)} as a string" do
|
|
156
|
+
lambda {
|
|
157
|
+
JSON.parse(source)
|
|
158
|
+
}.should raise_error(Yajl::ParseError)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
JSON_PASSED.each do |name, source|
|
|
163
|
+
it "should be able to parse #{File.basename(name)} as an IO" do
|
|
164
|
+
lambda {
|
|
165
|
+
JSON.parse(StringIO.new(source))
|
|
166
|
+
}.should_not raise_error(Yajl::ParseError)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
JSON_PASSED.each do |name, source|
|
|
171
|
+
it "should be able to parse #{File.basename(name)} as a string" do
|
|
172
|
+
lambda {
|
|
173
|
+
JSON.parse(source)
|
|
174
|
+
}.should_not raise_error(Yajl::ParseError)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
|
|
3
|
+
|
|
4
|
+
describe "ActiveSupport test cases" do
|
|
5
|
+
TESTS = {
|
|
6
|
+
%q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
|
|
7
|
+
%q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
|
|
8
|
+
%q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
|
|
9
|
+
%({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
|
|
10
|
+
%({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
|
|
11
|
+
%({"a": "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
|
|
12
|
+
%({"a": "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
|
|
13
|
+
# multibyte
|
|
14
|
+
%({"matzue": "松江", "asakusa": "浅草"}) => {"matzue" => "松江", "asakusa" => "浅草"},
|
|
15
|
+
%({"a": "2007-01-01"}) => {'a' => "2007-01-01"},
|
|
16
|
+
%({"a": "2007-01-01 01:12:34 Z"}) => {'a' => "2007-01-01 01:12:34 Z"},
|
|
17
|
+
# no time zone
|
|
18
|
+
%({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
|
|
19
|
+
# needs to be *exact*
|
|
20
|
+
%({"a": " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
|
|
21
|
+
%({"a": "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
|
|
22
|
+
%([]) => [],
|
|
23
|
+
%({}) => {},
|
|
24
|
+
%({"a":1}) => {"a" => 1},
|
|
25
|
+
%({"a": ""}) => {"a" => ""},
|
|
26
|
+
%({"a":"\\""}) => {"a" => "\""},
|
|
27
|
+
%({"a": null}) => {"a" => nil},
|
|
28
|
+
%({"a": true}) => {"a" => true},
|
|
29
|
+
%({"a": false}) => {"a" => false},
|
|
30
|
+
%q({"a": "http:\/\/test.host\/posts\/1"}) => {"a" => "http://test.host/posts/1"},
|
|
31
|
+
%q({"a": "\u003cunicode\u0020escape\u003e"}) => {"a" => "<unicode escape>"},
|
|
32
|
+
%q({"a": "\\\\u0020skip double backslashes"}) => {"a" => "\\u0020skip double backslashes"},
|
|
33
|
+
%q({"a": "\u003cbr /\u003e"}) => {'a' => "<br />"},
|
|
34
|
+
%q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["<i>","<b>","<u>"]}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
TESTS.each do |json, expected|
|
|
38
|
+
it "should be able to parse #{json} as an IO" do
|
|
39
|
+
lambda {
|
|
40
|
+
Yajl::Parser.parse(StringIO.new(json)).should == expected
|
|
41
|
+
}.should_not raise_error(Yajl::ParseError)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
TESTS.each do |json, expected|
|
|
46
|
+
it "should be able to parse #{json} as a string" do
|
|
47
|
+
lambda {
|
|
48
|
+
Yajl::Parser.parse(json).should == expected
|
|
49
|
+
}.should_not raise_error(Yajl::ParseError)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "should fail parsing {: 1} as an IO" do
|
|
54
|
+
lambda {
|
|
55
|
+
Yajl::Parser.parse(StringIO.new("{: 1}"))
|
|
56
|
+
}.should raise_error(Yajl::ParseError)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should fail parsing {: 1} as a string" do
|
|
60
|
+
lambda {
|
|
61
|
+
Yajl::Parser.parse("{: 1}")
|
|
62
|
+
}.should raise_error(Yajl::ParseError)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
|
|
3
|
+
require 'stringio'
|
|
4
|
+
|
|
5
|
+
describe "Chunked parser" do
|
|
6
|
+
before(:all) do
|
|
7
|
+
@final = [{"abc" => 123}, {"def" => 456}]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
before(:each) do
|
|
11
|
+
@callback = lambda { |hash|
|
|
12
|
+
# no-op
|
|
13
|
+
}
|
|
14
|
+
@parser = Yajl::Parser.new
|
|
15
|
+
@parser.on_parse_complete = @callback
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should parse a single chunk" do
|
|
19
|
+
@callback.should_receive(:call).with(@final)
|
|
20
|
+
@parser << '[{"abc": 123},{"def": 456}]'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should parse a single chunk, 3 times" do
|
|
24
|
+
@callback.should_receive(:call).with(@final).exactly(3).times
|
|
25
|
+
@parser << '[{"abc": 123},{"def": 456}]'
|
|
26
|
+
@parser << '[{"abc": 123},{"def": 456}]'
|
|
27
|
+
@parser << '[{"abc": 123},{"def": 456}]'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should parse in two chunks" do
|
|
31
|
+
@callback.should_receive(:call).with(@final)
|
|
32
|
+
@parser << '[{"abc": 123},'
|
|
33
|
+
@parser << '{"def": 456}]'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should parse in 2 chunks, twice" do
|
|
37
|
+
@callback.should_receive(:call).with(@final).exactly(2).times
|
|
38
|
+
@parser << '[{"abc": 123},'
|
|
39
|
+
@parser << '{"def": 456}]'
|
|
40
|
+
@parser << '[{"abc": 123},'
|
|
41
|
+
@parser << '{"def": 456}]'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should parse 2 JSON strings, in 3 chunks" do
|
|
45
|
+
@callback.should_receive(:call).with(@final).exactly(2).times
|
|
46
|
+
@parser << '[{"abc": 123},'
|
|
47
|
+
@parser << '{"def": 456}][{"abc": 123},{"def":'
|
|
48
|
+
@parser << ' 456}]'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should parse 2 JSON strings in 1 chunk" do
|
|
52
|
+
@callback.should_receive(:call).with(@final).exactly(2).times
|
|
53
|
+
@parser << '[{"abc": 123},{"def": 456}][{"abc": 123},{"def": 456}]'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should parse 2 JSON strings from an IO" do
|
|
57
|
+
@callback.should_receive(:call).with(@final).exactly(2).times
|
|
58
|
+
@parser.parse(StringIO.new('[{"abc": 123},{"def": 456}][{"abc": 123},{"def": 456}]'))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should parse a JSON string an IO and fire callback once" do
|
|
62
|
+
@callback.should_receive(:call).with(@final)
|
|
63
|
+
@parser.parse(StringIO.new('[{"abc": 123},{"def": 456}]'))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should parse twitter_stream.json and fire callback 430 times" do
|
|
67
|
+
path = File.expand_path(File.dirname(__FILE__) + '/../../benchmark/subjects/twitter_stream.json')
|
|
68
|
+
json = File.new(path, 'r')
|
|
69
|
+
@callback.should_receive(:call).exactly(430).times
|
|
70
|
+
lambda {
|
|
71
|
+
@parser.parse(json)
|
|
72
|
+
}.should_not raise_error(Yajl::ParseError)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should parse twitter_stream.json and fire callback 430 times, with a block as the callback" do
|
|
76
|
+
path = File.expand_path(File.dirname(__FILE__) + '/../../benchmark/subjects/twitter_stream.json')
|
|
77
|
+
json = File.new(path, 'r')
|
|
78
|
+
@callback.should_receive(:call).exactly(0).times
|
|
79
|
+
@parser.on_parse_complete = nil
|
|
80
|
+
lambda {
|
|
81
|
+
times = 0
|
|
82
|
+
@parser.parse(json) do |hsh|
|
|
83
|
+
times += 1
|
|
84
|
+
end
|
|
85
|
+
times.should eql(430)
|
|
86
|
+
}.should_not raise_error(Yajl::ParseError)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should raise a Yajl::ParseError error if multiple JSON strings were found when no on_parse_complete callback assigned" do
|
|
90
|
+
path = File.expand_path(File.dirname(__FILE__) + '/../../benchmark/subjects/twitter_stream.json')
|
|
91
|
+
json = File.new(path, 'r')
|
|
92
|
+
@parser.on_parse_complete = nil
|
|
93
|
+
@callback.should_receive(:call).exactly(0).times
|
|
94
|
+
lambda {
|
|
95
|
+
@parser.parse(json)
|
|
96
|
+
}.should raise_error(Yajl::ParseError)
|
|
97
|
+
end
|
|
98
|
+
end
|