yajl-ruby-zenjoy 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +14 -0
  4. data/CHANGELOG.md +332 -0
  5. data/Gemfile +3 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +361 -0
  8. data/Rakefile +2 -0
  9. data/benchmark/encode.rb +72 -0
  10. data/benchmark/encode_json_and_marshal.rb +42 -0
  11. data/benchmark/encode_json_and_yaml.rb +53 -0
  12. data/benchmark/http.rb +32 -0
  13. data/benchmark/parse.rb +94 -0
  14. data/benchmark/parse_json_and_marshal.rb +50 -0
  15. data/benchmark/parse_json_and_yaml.rb +55 -0
  16. data/benchmark/parse_stream.rb +54 -0
  17. data/benchmark/subjects/item.json +1 -0
  18. data/benchmark/subjects/ohai.json +1216 -0
  19. data/benchmark/subjects/ohai.marshal_dump +0 -0
  20. data/benchmark/subjects/ohai.yml +975 -0
  21. data/benchmark/subjects/twitter_search.json +1 -0
  22. data/benchmark/subjects/twitter_stream.json +430 -0
  23. data/benchmark/subjects/unicode.json +1 -0
  24. data/examples/encoding/chunked_encoding.rb +27 -0
  25. data/examples/encoding/one_shot.rb +13 -0
  26. data/examples/encoding/to_an_io.rb +12 -0
  27. data/examples/http/twitter_search_api.rb +12 -0
  28. data/examples/http/twitter_stream_api.rb +26 -0
  29. data/examples/parsing/from_file.rb +14 -0
  30. data/examples/parsing/from_stdin.rb +9 -0
  31. data/examples/parsing/from_string.rb +13 -0
  32. data/ext/yajl/api/yajl_common.h +89 -0
  33. data/ext/yajl/api/yajl_gen.h +161 -0
  34. data/ext/yajl/api/yajl_parse.h +196 -0
  35. data/ext/yajl/api/yajl_version.h +23 -0
  36. data/ext/yajl/extconf.rb +7 -0
  37. data/ext/yajl/yajl.c +164 -0
  38. data/ext/yajl/yajl_alloc.c +65 -0
  39. data/ext/yajl/yajl_alloc.h +51 -0
  40. data/ext/yajl/yajl_buf.c +119 -0
  41. data/ext/yajl/yajl_buf.h +80 -0
  42. data/ext/yajl/yajl_bytestack.h +85 -0
  43. data/ext/yajl/yajl_encode.c +201 -0
  44. data/ext/yajl/yajl_encode.h +55 -0
  45. data/ext/yajl/yajl_ext.c +906 -0
  46. data/ext/yajl/yajl_ext.h +135 -0
  47. data/ext/yajl/yajl_gen.c +344 -0
  48. data/ext/yajl/yajl_lex.c +748 -0
  49. data/ext/yajl/yajl_lex.h +146 -0
  50. data/ext/yajl/yajl_parser.c +450 -0
  51. data/ext/yajl/yajl_parser.h +84 -0
  52. data/ext/yajl/yajl_version.c +7 -0
  53. data/lib/yajl.rb +75 -0
  54. data/lib/yajl/bzip2.rb +11 -0
  55. data/lib/yajl/bzip2/stream_reader.rb +31 -0
  56. data/lib/yajl/bzip2/stream_writer.rb +14 -0
  57. data/lib/yajl/deflate.rb +6 -0
  58. data/lib/yajl/deflate/stream_reader.rb +43 -0
  59. data/lib/yajl/deflate/stream_writer.rb +20 -0
  60. data/lib/yajl/gzip.rb +6 -0
  61. data/lib/yajl/gzip/stream_reader.rb +30 -0
  62. data/lib/yajl/gzip/stream_writer.rb +13 -0
  63. data/lib/yajl/http_stream.rb +212 -0
  64. data/lib/yajl/json_gem.rb +13 -0
  65. data/lib/yajl/json_gem/encoding.rb +50 -0
  66. data/lib/yajl/json_gem/parsing.rb +26 -0
  67. data/lib/yajl/version.rb +3 -0
  68. data/spec/encoding/encoding_spec.rb +274 -0
  69. data/spec/global/global_spec.rb +54 -0
  70. data/spec/http/fixtures/http.bzip2.dump +0 -0
  71. data/spec/http/fixtures/http.chunked.dump +11 -0
  72. data/spec/http/fixtures/http.deflate.dump +0 -0
  73. data/spec/http/fixtures/http.error.dump +12 -0
  74. data/spec/http/fixtures/http.gzip.dump +0 -0
  75. data/spec/http/fixtures/http.html.dump +1220 -0
  76. data/spec/http/fixtures/http.raw.dump +1226 -0
  77. data/spec/http/http_delete_spec.rb +98 -0
  78. data/spec/http/http_error_spec.rb +32 -0
  79. data/spec/http/http_get_spec.rb +109 -0
  80. data/spec/http/http_post_spec.rb +123 -0
  81. data/spec/http/http_put_spec.rb +105 -0
  82. data/spec/http/http_stream_options_spec.rb +27 -0
  83. data/spec/json_gem_compatibility/compatibility_spec.rb +207 -0
  84. data/spec/parsing/active_support_spec.rb +64 -0
  85. data/spec/parsing/chunked_spec.rb +96 -0
  86. data/spec/parsing/fixtures/fail.15.json +1 -0
  87. data/spec/parsing/fixtures/fail.16.json +1 -0
  88. data/spec/parsing/fixtures/fail.17.json +1 -0
  89. data/spec/parsing/fixtures/fail.26.json +1 -0
  90. data/spec/parsing/fixtures/fail11.json +1 -0
  91. data/spec/parsing/fixtures/fail12.json +1 -0
  92. data/spec/parsing/fixtures/fail13.json +1 -0
  93. data/spec/parsing/fixtures/fail14.json +1 -0
  94. data/spec/parsing/fixtures/fail19.json +1 -0
  95. data/spec/parsing/fixtures/fail20.json +1 -0
  96. data/spec/parsing/fixtures/fail21.json +1 -0
  97. data/spec/parsing/fixtures/fail22.json +1 -0
  98. data/spec/parsing/fixtures/fail23.json +1 -0
  99. data/spec/parsing/fixtures/fail24.json +1 -0
  100. data/spec/parsing/fixtures/fail25.json +1 -0
  101. data/spec/parsing/fixtures/fail27.json +2 -0
  102. data/spec/parsing/fixtures/fail28.json +2 -0
  103. data/spec/parsing/fixtures/fail3.json +1 -0
  104. data/spec/parsing/fixtures/fail4.json +1 -0
  105. data/spec/parsing/fixtures/fail5.json +1 -0
  106. data/spec/parsing/fixtures/fail6.json +1 -0
  107. data/spec/parsing/fixtures/fail9.json +1 -0
  108. data/spec/parsing/fixtures/pass.array.json +6 -0
  109. data/spec/parsing/fixtures/pass.codepoints_from_unicode_org.json +1 -0
  110. data/spec/parsing/fixtures/pass.contacts.json +1 -0
  111. data/spec/parsing/fixtures/pass.db100.xml.json +1 -0
  112. data/spec/parsing/fixtures/pass.db1000.xml.json +1 -0
  113. data/spec/parsing/fixtures/pass.dc_simple_with_comments.json +11 -0
  114. data/spec/parsing/fixtures/pass.deep_arrays.json +1 -0
  115. data/spec/parsing/fixtures/pass.difficult_json_c_test_case.json +1 -0
  116. data/spec/parsing/fixtures/pass.difficult_json_c_test_case_with_comments.json +1 -0
  117. data/spec/parsing/fixtures/pass.doubles.json +1 -0
  118. data/spec/parsing/fixtures/pass.empty_array.json +1 -0
  119. data/spec/parsing/fixtures/pass.empty_string.json +1 -0
  120. data/spec/parsing/fixtures/pass.escaped_bulgarian.json +4 -0
  121. data/spec/parsing/fixtures/pass.escaped_foobar.json +1 -0
  122. data/spec/parsing/fixtures/pass.item.json +1 -0
  123. data/spec/parsing/fixtures/pass.json-org-sample1.json +23 -0
  124. data/spec/parsing/fixtures/pass.json-org-sample2.json +11 -0
  125. data/spec/parsing/fixtures/pass.json-org-sample3.json +26 -0
  126. data/spec/parsing/fixtures/pass.json-org-sample4-nows.json +88 -0
  127. data/spec/parsing/fixtures/pass.json-org-sample4.json +89 -0
  128. data/spec/parsing/fixtures/pass.json-org-sample5.json +27 -0
  129. data/spec/parsing/fixtures/pass.map-spain.xml.json +1 -0
  130. data/spec/parsing/fixtures/pass.ns-invoice100.xml.json +1 -0
  131. data/spec/parsing/fixtures/pass.ns-soap.xml.json +1 -0
  132. data/spec/parsing/fixtures/pass.numbers-fp-4k.json +6 -0
  133. data/spec/parsing/fixtures/pass.numbers-fp-64k.json +61 -0
  134. data/spec/parsing/fixtures/pass.numbers-int-4k.json +11 -0
  135. data/spec/parsing/fixtures/pass.numbers-int-64k.json +154 -0
  136. data/spec/parsing/fixtures/pass.twitter-search.json +1 -0
  137. data/spec/parsing/fixtures/pass.twitter-search2.json +1 -0
  138. data/spec/parsing/fixtures/pass.unicode.json +3315 -0
  139. data/spec/parsing/fixtures/pass.yelp.json +1 -0
  140. data/spec/parsing/fixtures/pass1.json +56 -0
  141. data/spec/parsing/fixtures/pass2.json +1 -0
  142. data/spec/parsing/fixtures/pass3.json +6 -0
  143. data/spec/parsing/fixtures_spec.rb +40 -0
  144. data/spec/parsing/one_off_spec.rb +85 -0
  145. data/spec/rcov.opts +3 -0
  146. data/spec/spec_helper.rb +16 -0
  147. data/tasks/compile.rake +35 -0
  148. data/tasks/rspec.rake +16 -0
  149. data/yajl-ruby.gemspec +25 -0
  150. metadata +346 -0
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+ require 'yajl/http_stream'
3
+ require 'socket'
4
+
5
+ describe "Passing options to HttpStream instance methods" do
6
+ before(:all) do
7
+ @stream = Yajl::HttpStream.new
8
+ end
9
+
10
+ it "should not create a new socket it one is provided" do
11
+ TCPSocket.should_not_receive(:new)
12
+ options = {:socket => :my_provided_socket}
13
+
14
+ @stream.send(:initialize_socket, URI.parse("http://google.com"), options)
15
+
16
+ options[:socket].should == :my_provided_socket
17
+ end
18
+
19
+ it "should create a new socket if one is not provided" do
20
+ TCPSocket.should_receive(:new).with("google.com", 80).and_return( :tcp_socket )
21
+ options = {}
22
+
23
+ @stream.send(:initialize_socket, URI.parse("http://google.com"), options)
24
+
25
+ options[:socket].should == :tcp_socket
26
+ end
27
+ end
@@ -0,0 +1,207 @@
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
+ require 'yajl/json_gem'
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
+ defined?(JSON).should be_true
38
+
39
+ JSON.respond_to?(:parse).should be_true
40
+ JSON.respond_to?(:generate).should be_true
41
+ JSON.respond_to?(:pretty_generate).should be_true
42
+ JSON.respond_to?(:load).should be_true
43
+ JSON.respond_to?(:dump).should be_true
44
+ end
45
+
46
+ it "should allow default parsing options be set with JSON.default_options" do
47
+ default = JSON.default_options[:symbolize_keys]
48
+ JSON.parse('{"foo": 1234}').should === {"foo" => 1234}
49
+ JSON.default_options[:symbolize_keys] = true
50
+ JSON.parse('{"foo": 1234}').should === {:foo => 1234}
51
+ JSON.default_options[:symbolize_keys] = default # ensure the rest of the test cases expect the default
52
+ end
53
+
54
+ it "should also allow the json gem's symbolize_names key" do
55
+ JSON.parse('{"foo": 1234}', :symbolize_names => true).should === {:foo => 1234}
56
+ end
57
+
58
+ it "should encode arbitrary classes via their default to_json method" do
59
+ d = Dummy.new
60
+ d.to_json.should == "\"#{d.to_s}\""
61
+
62
+ t = Time.now
63
+ t.to_json.should == "\"#{t.to_s}\""
64
+
65
+ da = Date.today
66
+ da.to_json.should == "\"#{da.to_s}\""
67
+
68
+ dt = DateTime.new
69
+ dt.to_json.should == "\"#{dt.to_s}\""
70
+ end
71
+
72
+ it "should have the standard parsing and encoding exceptions mapped" do
73
+ JSON::JSONError.new.is_a?(StandardError).should be_true
74
+ JSON::ParserError.new.is_a?(JSON::JSONError).should be_true
75
+ JSON::GeneratorError.new.is_a?(JSON::JSONError).should be_true
76
+
77
+ lambda {
78
+ JSON.parse("blah")
79
+ }.should raise_error(JSON::ParserError)
80
+
81
+ lambda {
82
+ JSON.generate(0.0/0.0)
83
+ }.should raise_error(JSON::GeneratorError)
84
+ end
85
+
86
+ context "ported tests for Unicode" do
87
+ it "should be able to encode and parse unicode" do
88
+ '""'.should eql(''.to_json)
89
+ '"\\b"'.should eql("\b".to_json)
90
+ '"\u0001"'.should eql(0x1.chr.to_json)
91
+ '"\u001F"'.should eql(0x1f.chr.to_json)
92
+ '" "'.should eql(' '.to_json)
93
+ "\"#{0x7f.chr}\"".should eql(0x7f.chr.to_json)
94
+ utf8 = [ "© ≠ €! \01" ]
95
+ json = "[\"© ≠ €! \\u0001\"]"
96
+ json.should eql(utf8.to_json)
97
+ utf8.should eql(JSON.parse(json))
98
+ utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
99
+ json = "[\"あいうえお\"]"
100
+ json.should eql(utf8.to_json)
101
+ utf8.should eql(JSON.parse(json))
102
+ utf8 = ['საქართველო']
103
+ json = "[\"საქართველო\"]"
104
+ json.should eql(utf8.to_json)
105
+ utf8.should eql(JSON.parse(json))
106
+ '["Ã"]'.should eql(JSON.generate(["Ã"]))
107
+ ["€"].should eql(JSON.parse('["\u20ac"]'))
108
+ utf8_str = "\xf0\xa0\x80\x81"
109
+ utf8 = [utf8_str]
110
+ json = "[\"#{utf8_str}\"]"
111
+ json.should eql(JSON.generate(utf8))
112
+ utf8.should eql(JSON.parse(json))
113
+ end
114
+ end
115
+
116
+ context "ported tests for generation" do
117
+ before(:all) do
118
+ @hash = {
119
+ 'a' => 2,
120
+ 'b' => 3.141,
121
+ 'c' => 'c',
122
+ 'd' => [ 1, "b", 3.14 ],
123
+ 'e' => { 'foo' => 'bar' },
124
+ 'g' => "blah",
125
+ 'h' => 1000.0,
126
+ 'i' => 0.001
127
+ }
128
+
129
+ @json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},"g":"blah","h":1000.0,"i":0.001}'
130
+
131
+ @json3 = %{
132
+ {
133
+ "a": 2,
134
+ "b": 3.141,
135
+ "c": "c",
136
+ "d": [1, "b", 3.14],
137
+ "e": {"foo": "bar"},
138
+ "g": "blah",
139
+ "h": 1000.0,
140
+ "i": 0.001
141
+ }
142
+ }.chomp
143
+ end
144
+
145
+ it "should be able to unparse" do
146
+ json = JSON.generate(@hash)
147
+ JSON.parse(@json2).should == JSON.parse(json)
148
+ parsed_json = JSON.parse(json)
149
+ @hash.should == parsed_json
150
+ json = JSON.generate({1=>2})
151
+ '{"1":2}'.should eql(json)
152
+ parsed_json = JSON.parse(json)
153
+ {"1"=>2}.should == parsed_json
154
+ end
155
+
156
+ it "should be able to unparse pretty" do
157
+ json = JSON.pretty_generate(@hash)
158
+ JSON.parse(@json3).should == JSON.parse(json)
159
+ parsed_json = JSON.parse(json)
160
+ @hash.should == parsed_json
161
+ json = JSON.pretty_generate({1=>2})
162
+ test = "{\n \"1\": 2\n}".chomp
163
+ test.should == json
164
+ parsed_json = JSON.parse(json)
165
+ {"1"=>2}.should == parsed_json
166
+ end
167
+ end
168
+
169
+ context "ported fixture tests" do
170
+ fixtures = File.join(File.dirname(__FILE__), '../parsing/fixtures/*.json')
171
+ passed, failed = Dir[fixtures].partition { |f| f['pass'] }
172
+ JSON_PASSED = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
173
+ JSON_FAILED = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
174
+
175
+ JSON_FAILED.each do |name, source|
176
+ it "should not be able to parse #{File.basename(name)} as an IO" do
177
+ lambda {
178
+ JSON.parse(StringIO.new(source))
179
+ }.should raise_error(JSON::ParserError)
180
+ end
181
+ end
182
+
183
+ JSON_FAILED.each do |name, source|
184
+ it "should not be able to parse #{File.basename(name)} as a string" do
185
+ lambda {
186
+ JSON.parse(source)
187
+ }.should raise_error(JSON::ParserError)
188
+ end
189
+ end
190
+
191
+ JSON_PASSED.each do |name, source|
192
+ it "should be able to parse #{File.basename(name)} as an IO" do
193
+ lambda {
194
+ JSON.parse(StringIO.new(source))
195
+ }.should_not raise_error(JSON::ParserError)
196
+ end
197
+ end
198
+
199
+ JSON_PASSED.each do |name, source|
200
+ it "should be able to parse #{File.basename(name)} as a string" do
201
+ lambda {
202
+ JSON.parse(source)
203
+ }.should_not raise_error(JSON::ParserError)
204
+ end
205
+ end
206
+ end
207
+ 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,96 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+
3
+ describe "Chunked parser" do
4
+ before(:all) do
5
+ @final = [{"abc" => 123}, {"def" => 456}]
6
+ end
7
+
8
+ before(:each) do
9
+ @callback = lambda { |hash|
10
+ # no-op
11
+ }
12
+ @parser = Yajl::Parser.new
13
+ @parser.on_parse_complete = @callback
14
+ end
15
+
16
+ it "should parse a single chunk" do
17
+ @callback.should_receive(:call).with(@final)
18
+ @parser << '[{"abc": 123},{"def": 456}]'
19
+ end
20
+
21
+ it "should parse a single chunk, 3 times" do
22
+ @callback.should_receive(:call).with(@final).exactly(3).times
23
+ @parser << '[{"abc": 123},{"def": 456}]'
24
+ @parser << '[{"abc": 123},{"def": 456}]'
25
+ @parser << '[{"abc": 123},{"def": 456}]'
26
+ end
27
+
28
+ it "should parse in two chunks" do
29
+ @callback.should_receive(:call).with(@final)
30
+ @parser << '[{"abc": 123},'
31
+ @parser << '{"def": 456}]'
32
+ end
33
+
34
+ it "should parse in 2 chunks, twice" do
35
+ @callback.should_receive(:call).with(@final).exactly(2).times
36
+ @parser << '[{"abc": 123},'
37
+ @parser << '{"def": 456}]'
38
+ @parser << '[{"abc": 123},'
39
+ @parser << '{"def": 456}]'
40
+ end
41
+
42
+ it "should parse 2 JSON strings, in 3 chunks" do
43
+ @callback.should_receive(:call).with(@final).exactly(2).times
44
+ @parser << '[{"abc": 123},'
45
+ @parser << '{"def": 456}][{"abc": 123},{"def":'
46
+ @parser << ' 456}]'
47
+ end
48
+
49
+ it "should parse 2 JSON strings in 1 chunk" do
50
+ @callback.should_receive(:call).with(@final).exactly(2).times
51
+ @parser << '[{"abc": 123},{"def": 456}][{"abc": 123},{"def": 456}]'
52
+ end
53
+
54
+ it "should parse 2 JSON strings from an IO" do
55
+ @callback.should_receive(:call).with(@final).exactly(2).times
56
+ @parser.parse(StringIO.new('[{"abc": 123},{"def": 456}][{"abc": 123},{"def": 456}]'))
57
+ end
58
+
59
+ it "should parse a JSON string an IO and fire callback once" do
60
+ @callback.should_receive(:call).with(@final)
61
+ @parser.parse(StringIO.new('[{"abc": 123},{"def": 456}]'))
62
+ end
63
+
64
+ it "should parse twitter_stream.json and fire callback 430 times" do
65
+ path = File.expand_path(File.dirname(__FILE__) + '/../../benchmark/subjects/twitter_stream.json')
66
+ json = File.new(path, 'r')
67
+ @callback.should_receive(:call).exactly(430).times
68
+ lambda {
69
+ @parser.parse(json)
70
+ }.should_not raise_error(Yajl::ParseError)
71
+ end
72
+
73
+ it "should parse twitter_stream.json and fire callback 430 times, with a block as the callback" do
74
+ path = File.expand_path(File.dirname(__FILE__) + '/../../benchmark/subjects/twitter_stream.json')
75
+ json = File.new(path, 'r')
76
+ @callback.should_receive(:call).exactly(0).times
77
+ @parser.on_parse_complete = nil
78
+ lambda {
79
+ times = 0
80
+ @parser.parse(json) do |hsh|
81
+ times += 1
82
+ end
83
+ times.should eql(430)
84
+ }.should_not raise_error(Yajl::ParseError)
85
+ end
86
+
87
+ it "should raise a Yajl::ParseError error if multiple JSON strings were found when no on_parse_complete callback assigned" do
88
+ path = File.expand_path(File.dirname(__FILE__) + '/../../benchmark/subjects/twitter_stream.json')
89
+ json = File.new(path, 'r')
90
+ @parser.on_parse_complete = nil
91
+ @callback.should_receive(:call).exactly(0).times
92
+ lambda {
93
+ @parser.parse(json)
94
+ }.should raise_error(Yajl::ParseError)
95
+ end
96
+ end
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \x15"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \'"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \017"]
@@ -0,0 +1 @@
1
+ ["tab\ character\ in\ string\ "]
@@ -0,0 +1 @@
1
+ {"Illegal expression": 1 + 2}
@@ -0,0 +1 @@
1
+ {"Illegal invocation": alert()}
@@ -0,0 +1 @@
1
+ {"Numbers cannot have leading zeroes": 013}
@@ -0,0 +1 @@
1
+ {"Numbers cannot be hex": 0x14}
@@ -0,0 +1 @@
1
+ {"Missing colon" null}
@@ -0,0 +1 @@
1
+ {"Double colon":: null}
@@ -0,0 +1 @@
1
+ {"Comma instead of colon", null}
@@ -0,0 +1 @@
1
+ ["Colon instead of comma": false]
@@ -0,0 +1 @@
1
+ ["Bad value", truth]
@@ -0,0 +1 @@
1
+ ['single quote']
@@ -0,0 +1 @@
1
+ ["tab character in string "]
@@ -0,0 +1,2 @@
1
+ ["line
2
+ break"]
@@ -0,0 +1,2 @@
1
+ ["line\
2
+ break"]