benofsky-yajl-ruby 0.7.6

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 (143) hide show
  1. data/.gitignore +9 -0
  2. data/CHANGELOG.md +281 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +320 -0
  5. data/Rakefile +40 -0
  6. data/VERSION.yml +5 -0
  7. data/benchmark/encode.rb +58 -0
  8. data/benchmark/encode_json_and_marshal.rb +42 -0
  9. data/benchmark/encode_json_and_yaml.rb +53 -0
  10. data/benchmark/http.rb +32 -0
  11. data/benchmark/parse.rb +59 -0
  12. data/benchmark/parse_json_and_marshal.rb +50 -0
  13. data/benchmark/parse_json_and_yaml.rb +55 -0
  14. data/benchmark/parse_stream.rb +54 -0
  15. data/benchmark/subjects/item.json +1 -0
  16. data/benchmark/subjects/ohai.json +1216 -0
  17. data/benchmark/subjects/ohai.marshal_dump +0 -0
  18. data/benchmark/subjects/ohai.yml +975 -0
  19. data/benchmark/subjects/twitter_search.json +1 -0
  20. data/benchmark/subjects/twitter_stream.json +430 -0
  21. data/benchmark/subjects/unicode.json +1 -0
  22. data/examples/encoding/chunked_encoding.rb +27 -0
  23. data/examples/encoding/one_shot.rb +13 -0
  24. data/examples/encoding/to_an_io.rb +12 -0
  25. data/examples/http/twitter_search_api.rb +12 -0
  26. data/examples/http/twitter_stream_api.rb +26 -0
  27. data/examples/parsing/from_file.rb +14 -0
  28. data/examples/parsing/from_stdin.rb +9 -0
  29. data/examples/parsing/from_string.rb +13 -0
  30. data/ext/api/yajl_common.h +85 -0
  31. data/ext/api/yajl_gen.h +159 -0
  32. data/ext/api/yajl_parse.h +196 -0
  33. data/ext/extconf.rb +9 -0
  34. data/ext/yajl.c +164 -0
  35. data/ext/yajl_alloc.c +65 -0
  36. data/ext/yajl_alloc.h +50 -0
  37. data/ext/yajl_buf.c +119 -0
  38. data/ext/yajl_buf.h +73 -0
  39. data/ext/yajl_bytestack.h +85 -0
  40. data/ext/yajl_encode.c +188 -0
  41. data/ext/yajl_encode.h +50 -0
  42. data/ext/yajl_ext.c +911 -0
  43. data/ext/yajl_ext.h +128 -0
  44. data/ext/yajl_gen.c +317 -0
  45. data/ext/yajl_lex.c +747 -0
  46. data/ext/yajl_lex.h +135 -0
  47. data/ext/yajl_parser.c +450 -0
  48. data/ext/yajl_parser.h +82 -0
  49. data/lib/yajl/bzip2/stream_reader.rb +32 -0
  50. data/lib/yajl/bzip2/stream_writer.rb +15 -0
  51. data/lib/yajl/bzip2.rb +11 -0
  52. data/lib/yajl/deflate/stream_reader.rb +44 -0
  53. data/lib/yajl/deflate/stream_writer.rb +21 -0
  54. data/lib/yajl/deflate.rb +6 -0
  55. data/lib/yajl/gzip/stream_reader.rb +31 -0
  56. data/lib/yajl/gzip/stream_writer.rb +14 -0
  57. data/lib/yajl/gzip.rb +6 -0
  58. data/lib/yajl/http_stream.rb +197 -0
  59. data/lib/yajl/json_gem/encoding.rb +50 -0
  60. data/lib/yajl/json_gem/parsing.rb +27 -0
  61. data/lib/yajl/json_gem.rb +14 -0
  62. data/lib/yajl.rb +93 -0
  63. data/spec/encoding/encoding_spec.rb +234 -0
  64. data/spec/global/global_spec.rb +55 -0
  65. data/spec/http/fixtures/http.bzip2.dump +0 -0
  66. data/spec/http/fixtures/http.chunked.dump +11 -0
  67. data/spec/http/fixtures/http.deflate.dump +0 -0
  68. data/spec/http/fixtures/http.error.dump +12 -0
  69. data/spec/http/fixtures/http.gzip.dump +0 -0
  70. data/spec/http/fixtures/http.html.dump +1220 -0
  71. data/spec/http/fixtures/http.raw.dump +1226 -0
  72. data/spec/http/http_delete_spec.rb +99 -0
  73. data/spec/http/http_error_spec.rb +33 -0
  74. data/spec/http/http_get_spec.rb +110 -0
  75. data/spec/http/http_post_spec.rb +124 -0
  76. data/spec/http/http_put_spec.rb +106 -0
  77. data/spec/json_gem_compatibility/compatibility_spec.rb +203 -0
  78. data/spec/parsing/active_support_spec.rb +64 -0
  79. data/spec/parsing/chunked_spec.rb +98 -0
  80. data/spec/parsing/fixtures/fail.15.json +1 -0
  81. data/spec/parsing/fixtures/fail.16.json +1 -0
  82. data/spec/parsing/fixtures/fail.17.json +1 -0
  83. data/spec/parsing/fixtures/fail.26.json +1 -0
  84. data/spec/parsing/fixtures/fail11.json +1 -0
  85. data/spec/parsing/fixtures/fail12.json +1 -0
  86. data/spec/parsing/fixtures/fail13.json +1 -0
  87. data/spec/parsing/fixtures/fail14.json +1 -0
  88. data/spec/parsing/fixtures/fail19.json +1 -0
  89. data/spec/parsing/fixtures/fail20.json +1 -0
  90. data/spec/parsing/fixtures/fail21.json +1 -0
  91. data/spec/parsing/fixtures/fail22.json +1 -0
  92. data/spec/parsing/fixtures/fail23.json +1 -0
  93. data/spec/parsing/fixtures/fail24.json +1 -0
  94. data/spec/parsing/fixtures/fail25.json +1 -0
  95. data/spec/parsing/fixtures/fail27.json +2 -0
  96. data/spec/parsing/fixtures/fail28.json +2 -0
  97. data/spec/parsing/fixtures/fail3.json +1 -0
  98. data/spec/parsing/fixtures/fail4.json +1 -0
  99. data/spec/parsing/fixtures/fail5.json +1 -0
  100. data/spec/parsing/fixtures/fail6.json +1 -0
  101. data/spec/parsing/fixtures/fail9.json +1 -0
  102. data/spec/parsing/fixtures/pass.array.json +6 -0
  103. data/spec/parsing/fixtures/pass.codepoints_from_unicode_org.json +1 -0
  104. data/spec/parsing/fixtures/pass.contacts.json +1 -0
  105. data/spec/parsing/fixtures/pass.db100.xml.json +1 -0
  106. data/spec/parsing/fixtures/pass.db1000.xml.json +1 -0
  107. data/spec/parsing/fixtures/pass.dc_simple_with_comments.json +11 -0
  108. data/spec/parsing/fixtures/pass.deep_arrays.json +1 -0
  109. data/spec/parsing/fixtures/pass.difficult_json_c_test_case.json +1 -0
  110. data/spec/parsing/fixtures/pass.difficult_json_c_test_case_with_comments.json +1 -0
  111. data/spec/parsing/fixtures/pass.doubles.json +1 -0
  112. data/spec/parsing/fixtures/pass.empty_array.json +1 -0
  113. data/spec/parsing/fixtures/pass.empty_string.json +1 -0
  114. data/spec/parsing/fixtures/pass.escaped_bulgarian.json +4 -0
  115. data/spec/parsing/fixtures/pass.escaped_foobar.json +1 -0
  116. data/spec/parsing/fixtures/pass.item.json +1 -0
  117. data/spec/parsing/fixtures/pass.json-org-sample1.json +23 -0
  118. data/spec/parsing/fixtures/pass.json-org-sample2.json +11 -0
  119. data/spec/parsing/fixtures/pass.json-org-sample3.json +26 -0
  120. data/spec/parsing/fixtures/pass.json-org-sample4-nows.json +88 -0
  121. data/spec/parsing/fixtures/pass.json-org-sample4.json +89 -0
  122. data/spec/parsing/fixtures/pass.json-org-sample5.json +27 -0
  123. data/spec/parsing/fixtures/pass.map-spain.xml.json +1 -0
  124. data/spec/parsing/fixtures/pass.ns-invoice100.xml.json +1 -0
  125. data/spec/parsing/fixtures/pass.ns-soap.xml.json +1 -0
  126. data/spec/parsing/fixtures/pass.numbers-fp-4k.json +6 -0
  127. data/spec/parsing/fixtures/pass.numbers-fp-64k.json +61 -0
  128. data/spec/parsing/fixtures/pass.numbers-int-4k.json +11 -0
  129. data/spec/parsing/fixtures/pass.numbers-int-64k.json +154 -0
  130. data/spec/parsing/fixtures/pass.twitter-search.json +1 -0
  131. data/spec/parsing/fixtures/pass.twitter-search2.json +1 -0
  132. data/spec/parsing/fixtures/pass.unicode.json +3315 -0
  133. data/spec/parsing/fixtures/pass.yelp.json +1 -0
  134. data/spec/parsing/fixtures/pass1.json +56 -0
  135. data/spec/parsing/fixtures/pass2.json +1 -0
  136. data/spec/parsing/fixtures/pass3.json +6 -0
  137. data/spec/parsing/fixtures_spec.rb +41 -0
  138. data/spec/parsing/one_off_spec.rb +81 -0
  139. data/spec/rcov.opts +3 -0
  140. data/spec/spec.opts +2 -0
  141. data/spec/spec_helper.rb +16 -0
  142. data/yajl-ruby.gemspec +203 -0
  143. metadata +232 -0
@@ -0,0 +1,234 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
3
+
4
+ class Dummy2
5
+ def to_json
6
+ "{\"hawtness\":true}"
7
+ end
8
+ end
9
+
10
+ describe "Yajl JSON encoder" do
11
+ FILES = Dir[File.dirname(__FILE__)+'/../../benchmark/subjects/*.json']
12
+
13
+ FILES.each do |file|
14
+ it "should encode #{File.basename(file)} to an IO" do
15
+ # we don't care about testing the stream subject as it has multiple JSON strings in it
16
+ if File.basename(file) != 'twitter_stream.json'
17
+ input = File.new(File.expand_path(file), 'r')
18
+ io = StringIO.new
19
+ encoder = Yajl::Encoder.new
20
+ hash = Yajl::Parser.parse(input)
21
+ encoder.encode(hash, io)
22
+ io.rewind
23
+ hash2 = Yajl::Parser.parse(io)
24
+ io.close
25
+ input.close
26
+ hash.should == hash2
27
+ end
28
+ end
29
+ end
30
+
31
+ FILES.each do |file|
32
+ it "should encode #{File.basename(file)} and return a String" do
33
+ # we don't care about testing the stream subject as it has multiple JSON strings in it
34
+ if File.basename(file) != 'twitter_stream.json'
35
+ input = File.new(File.expand_path(file), 'r')
36
+ encoder = Yajl::Encoder.new
37
+ hash = Yajl::Parser.parse(input)
38
+ output = encoder.encode(hash)
39
+ hash2 = Yajl::Parser.parse(output)
40
+ input.close
41
+ hash.should == hash2
42
+ end
43
+ end
44
+ end
45
+
46
+ FILES.each do |file|
47
+ it "should encode #{File.basename(file)} call the passed block, passing it a String" do
48
+ # we don't care about testing the stream subject as it has multiple JSON strings in it
49
+ if File.basename(file) != 'twitter_stream.json'
50
+ input = File.new(File.expand_path(file), 'r')
51
+ encoder = Yajl::Encoder.new
52
+ hash = Yajl::Parser.parse(input)
53
+ output = ''
54
+ encoder.encode(hash) do |json_str|
55
+ output << json_str
56
+ end
57
+ hash2 = Yajl::Parser.parse(output)
58
+ input.close
59
+ hash.should == hash2
60
+ end
61
+ end
62
+ end
63
+
64
+ it "should encode with :pretty turned on and a single space indent, to an IO" do
65
+ output = "{\n \"foo\": 1234\n}"
66
+ obj = {:foo => 1234}
67
+ io = StringIO.new
68
+ encoder = Yajl::Encoder.new(:pretty => true, :indent => ' ')
69
+ encoder.encode(obj, io)
70
+ io.rewind
71
+ io.read.should == output
72
+ end
73
+
74
+ it "should encode with :pretty turned on and a single space indent, and return a String" do
75
+ output = "{\n \"foo\": 1234\n}"
76
+ obj = {:foo => 1234}
77
+ encoder = Yajl::Encoder.new(:pretty => true, :indent => ' ')
78
+ output = encoder.encode(obj)
79
+ output.should == output
80
+ end
81
+
82
+ it "should encode with :pretty turned on and a tab character indent, to an IO" do
83
+ output = "{\n\t\"foo\": 1234\n}"
84
+ obj = {:foo => 1234}
85
+ io = StringIO.new
86
+ encoder = Yajl::Encoder.new(:pretty => true, :indent => "\t")
87
+ encoder.encode(obj, io)
88
+ io.rewind
89
+ io.read.should == output
90
+ end
91
+
92
+ it "should encode with :pretty turned on and a tab character indent, and return a String" do
93
+ output = "{\n\t\"foo\": 1234\n}"
94
+ obj = {:foo => 1234}
95
+ encoder = Yajl::Encoder.new(:pretty => true, :indent => "\t")
96
+ output = encoder.encode(obj)
97
+ output.should == output
98
+ end
99
+
100
+ it "should encode with it's class method with :pretty and a tab character indent options set, to an IO" do
101
+ output = "{\n\t\"foo\": 1234\n}"
102
+ obj = {:foo => 1234}
103
+ io = StringIO.new
104
+ Yajl::Encoder.encode(obj, io, :pretty => true, :indent => "\t")
105
+ io.rewind
106
+ io.read.should == output
107
+ end
108
+
109
+ it "should encode with it's class method with :pretty and a tab character indent options set, and return a String" do
110
+ output = "{\n\t\"foo\": 1234\n}"
111
+ obj = {:foo => 1234}
112
+ output = Yajl::Encoder.encode(obj, :pretty => true, :indent => "\t")
113
+ output.should == output
114
+ end
115
+
116
+ it "should encode with it's class method with :pretty and a tab character indent options set, to a block" do
117
+ output = "{\n\t\"foo\": 1234\n}"
118
+ obj = {:foo => 1234}
119
+ output = ''
120
+ Yajl::Encoder.encode(obj, :pretty => true, :indent => "\t") do |json_str|
121
+ output = json_str
122
+ end
123
+ output.should == output
124
+ end
125
+
126
+ it "should encode multiple objects into a single stream, to an IO" do
127
+ io = StringIO.new
128
+ obj = {:foo => 1234}
129
+ encoder = Yajl::Encoder.new
130
+ 5.times do
131
+ encoder.encode(obj, io)
132
+ end
133
+ io.rewind
134
+ output = "{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}"
135
+ io.read.should == output
136
+ end
137
+
138
+ it "should encode multiple objects into a single stream, and return a String" do
139
+ obj = {:foo => 1234}
140
+ encoder = Yajl::Encoder.new
141
+ json_output = ''
142
+ 5.times do
143
+ json_output << encoder.encode(obj)
144
+ end
145
+ output = "{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}"
146
+ json_output.should == output
147
+ end
148
+
149
+ it "should encode all map keys as strings" do
150
+ Yajl::Encoder.encode({1=>1}).should eql("{\"1\":1}")
151
+ end
152
+
153
+ it "should check for and call #to_json if it exists on custom objects" do
154
+ d = Dummy2.new
155
+ Yajl::Encoder.encode({:foo => d}).should eql('{"foo":{"hawtness":true}}')
156
+ end
157
+
158
+ it "should encode a hash where the key and value can be symbols" do
159
+ Yajl::Encoder.encode({:foo => :bar}).should eql('{"foo":"bar"}')
160
+ end
161
+
162
+ it "should encode using a newline or nil terminator" do
163
+ Yajl::Encoder.new(:terminator => "\n").encode({:foo => :bar}).should eql("{\"foo\":\"bar\"}\n")
164
+ Yajl::Encoder.new(:terminator => nil).encode({:foo => :bar}).should eql("{\"foo\":\"bar\"}")
165
+ end
166
+
167
+ it "should encode using a newline or nil terminator, to an IO" do
168
+ s = StringIO.new
169
+ Yajl::Encoder.new(:terminator => "\n").encode({:foo => :bar}, s)
170
+ s.rewind
171
+ s.read.should eql("{\"foo\":\"bar\"}\n")
172
+
173
+ s = StringIO.new
174
+ Yajl::Encoder.new(:terminator => nil).encode({:foo => :bar}, s)
175
+ s.rewind
176
+ s.read.should eql("{\"foo\":\"bar\"}")
177
+ end
178
+
179
+ it "should encode using a newline or nil terminator, using a block" do
180
+ s = StringIO.new
181
+ Yajl::Encoder.new(:terminator => "\n").encode({:foo => :bar}) do |chunk|
182
+ s << chunk
183
+ end
184
+ s.rewind
185
+ s.read.should eql("{\"foo\":\"bar\"}\n")
186
+
187
+ s = StringIO.new
188
+ nilpassed = false
189
+ Yajl::Encoder.new(:terminator => nil).encode({:foo => :bar}) do |chunk|
190
+ nilpassed = true if chunk.nil?
191
+ s << chunk
192
+ end
193
+ nilpassed.should be_true
194
+ s.rewind
195
+ s.read.should eql("{\"foo\":\"bar\"}")
196
+ end
197
+
198
+ it "should not encode NaN" do
199
+ lambda {
200
+ Yajl::Encoder.encode(0.0/0.0)
201
+ }.should raise_error(Yajl::EncodeError)
202
+ end
203
+
204
+ it "should not encode Infinity or -Infinity" do
205
+ lambda {
206
+ Yajl::Encoder.encode(1.0/0.0)
207
+ }.should raise_error(Yajl::EncodeError)
208
+ lambda {
209
+ Yajl::Encoder.encode(-1.0/0.0)
210
+ }.should raise_error(Yajl::EncodeError)
211
+ end
212
+
213
+ it "should encode with unicode chars in the key" do
214
+ hash = {"浅草" => "<- those are unicode"}
215
+ Yajl::Encoder.encode(hash).should eql("{\"浅草\":\"<- those are unicode\"}")
216
+ end
217
+
218
+ if RUBY_VERSION =~ /^1.9/
219
+ it "should return a string encoded in utf-8 if Encoding.default_internal is nil" do
220
+ Encoding.default_internal = nil
221
+ hash = {"浅草" => "<- those are unicode"}
222
+ Yajl::Encoder.encode(hash).encoding.should eql(Encoding.find('utf-8'))
223
+ end
224
+
225
+ it "should return a string encoded in utf-8 even if Encoding.default_internal *is* set" do
226
+ Encoding.default_internal = Encoding.find('utf-8')
227
+ hash = {"浅草" => "<- those are unicode"}
228
+ Yajl::Encoder.encode(hash).encoding.should eql(Encoding.default_internal)
229
+ Encoding.default_internal = Encoding.find('us-ascii')
230
+ hash = {"浅草" => "<- those are unicode"}
231
+ Yajl::Encoder.encode(hash).encoding.should eql(Encoding.find('utf-8'))
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
3
+
4
+ describe "Yajl" do
5
+ context "dump" do
6
+ it "should exist as a class-method" do
7
+ Yajl.should respond_to(:dump)
8
+ end
9
+
10
+ it "should be able to encode to a string" do
11
+ Yajl.dump({:a => 1234}).should eql('{"a":1234}')
12
+ end
13
+
14
+ it "should be able to encode to an IO" do
15
+ io = StringIO.new
16
+ Yajl.dump({:a => 1234}, io)
17
+ io.rewind
18
+ io.read.should eql('{"a":1234}')
19
+ end
20
+
21
+ it "should be able to encode with a block supplied" do
22
+ Yajl.dump({:a => 1234}) do |chunk|
23
+ chunk.should eql('{"a":1234}')
24
+ end
25
+ end
26
+ end
27
+
28
+ context "load" do
29
+ it "should exist as a class-method" do
30
+ Yajl.should respond_to(:load)
31
+ end
32
+
33
+ it "should be able to parse from a string" do
34
+ Yajl.load('{"a":1234}').should eql({"a" => 1234})
35
+ end
36
+
37
+ it "should be able to parse from an IO" do
38
+ io = StringIO.new('{"a":1234}')
39
+ Yajl.load(io).should eql({"a" => 1234})
40
+ end
41
+
42
+ it "should be able to parse from a string with a block supplied" do
43
+ Yajl.load('{"a":1234}') do |h|
44
+ h.should eql({"a" => 1234})
45
+ end
46
+ end
47
+
48
+ it "should be able to parse from an IO with a block supplied" do
49
+ io = StringIO.new('{"a":1234}')
50
+ Yajl.load(io) do |h|
51
+ h.should eql({"a" => 1234})
52
+ end
53
+ end
54
+ end
55
+ end
Binary file
@@ -0,0 +1,11 @@
1
+ HTTP/1.1 200 OK
2
+ Content-Type: application/json
3
+ Transfer-Encoding: chunked
4
+
5
+ 12f
6
+ {"item": {"name": "generated", "cached_tag_list": "", "updated_at": "2009-03-24T05:25:09Z", "updated_by_id": null, "price": 1.99, "delta": false, "cost": 0.597, "account_id": 16, "unit": null, "import_tag": null, "taxable": true, "id": 1, "created_by_id": null, "description": null, "company_id": 0, "sk
7
+
8
+ 48
9
+ u": "06317-0306", "created_at": "2009-03-24T05:25:09Z", "active": true}}
10
+
11
+ 0
@@ -0,0 +1,12 @@
1
+ HTTP/1.1 404 NOT FOUND
2
+ Vary: Accept-Encoding
3
+ Content-Type: text/html
4
+ Accept-Ranges: bytes
5
+ ETag: "-1274243775"
6
+ Last-Modified: Thu, 30 Apr 2009 04:36:11 GMT
7
+ Content-Length: 32444
8
+ Date: Wed, 24 Jun 2009 06:02:18 GMT
9
+ Server: lighttpd/1.4.22
10
+ Transfer-Encoding: chunked
11
+
12
+ <html>THIS PAGE COULD NOT BE FOUND!</html>
Binary file