json-endure 0.2.2

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/.rspec ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ This work is licensed under the Creative Commons Attribution 3.0 Unported License.
2
+
3
+ To view a copy of this license, visit :
4
+
5
+ http://creativecommons.org/licenses/by/3.0/
6
+
7
+ Or send a letter to :
8
+
9
+ Creative Commons,
10
+ 444 Castro Street,
11
+ Suite 900,
12
+ Mountain View,
13
+ California, 94041,
14
+ USA.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ json-endure
2
+ ===========
3
+
4
+ `json-endure` provides helper methods to the JSON and String classes to
5
+ make-do with truncated JSON text. It does so by closing
6
+ double-quotes, brackets and braces, whether the truncation occurs in
7
+ an array value, hash key, or hash value. These methods may be helpful
8
+ in a case where you want to examine the first bunch of bytes of a very
9
+ large file, without downloading all of it.
10
+
11
+ It will not repair bad JSON encountered before the truncation.
12
+
13
+ License
14
+ -------
15
+
16
+ `json-endure` is licensed under the Creative Commons 3.0 License.
17
+ Details can be found in the file LICENSE.
18
+
19
+ License-file referencing and other doc. formatting taken from
20
+ [damiendallimore](https://github.com/damiendallimore "damiendallimore on GitHub").
21
+
22
+ Install
23
+ -------
24
+
25
+ > gem install json-endure
26
+
27
+ Usage
28
+ -----
29
+
30
+ >> require 'json-endure' #=> true
31
+ >> broken = String.new('{ "123": "90", "abc": { "30') #=> "{ \"123\": \"90\", \"abc\": { \"30"
32
+ >> good_hash = JSON.endure_and_parse broken #=> {"123"=>"90", "abc"=>{"30"=>""}}
33
+ >> fixed = broken.coax_into_json! #=> "{ \"123\": \"90\", \"abc\": { \"30\":\"\"}}"
34
+ >> broken #=> "{ \"123\": \"90\", \"abc\": { \"30\":\"\"}}"
35
+
36
+ Contribute
37
+ ----------
38
+
39
+ Please fork the GitHub project (https://github.com/aburnheimer/json-endure),
40
+ make any changes, commit and push to GitHub, and submit a pull request. Including
41
+ tests for your changes would be greatly appreciated!
42
+
43
+ Resources
44
+ ---------
45
+
46
+ JSON format reference
47
+
48
+ * http://www.json.org/
49
+
50
+ Contact
51
+ -------
52
+
53
+ This project was initiated by Andrew Burnheimer.
54
+
55
+ * Email:
56
+ * aburnheimer@gmail.com
57
+ * Twitter:
58
+ * @aburnheimer
59
+ * Github:
60
+ * https://github.com/aburnheimer/
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |s|
2
+ s.platform = Gem::Platform::RUBY
3
+ s.name = 'json-endure'
4
+ s.version = '0.2.2'
5
+ s.summary = %q{Handle truncated JSON-text}
6
+
7
+ s.description = %q{Helper methods to JSON and String to make-do } +
8
+ %q{with truncated JSON text.}
9
+
10
+ s.license = 'CC-BY-3.0'
11
+
12
+ s.author = 'Andrew Burnheimer'
13
+ s.email = 'Andrew_Burnheimer@cable.comcast.com'
14
+ s.homepage = 'https://github.com/aburnheimer/json-endure'
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+
19
+ # specify any dependencies here:
20
+ s.add_dependency("json")
21
+ end
@@ -0,0 +1,2 @@
1
+ require 'json-endure/json'
2
+ require 'json-endure/string'
@@ -0,0 +1,6 @@
1
+ class Array
2
+ def last=(arg)
3
+ self.pop
4
+ self << arg
5
+ end
6
+ end
@@ -0,0 +1,205 @@
1
+ require 'json'
2
+ require File.expand_path File.join(File.dirname(__FILE__), 'array')
3
+
4
+ module JsonStateVariable
5
+ INIT = 10
6
+ IN_ARRAY_PRE_VALUE = 20
7
+ IN_ARRAY_IN_VALUE = 30
8
+ IN_ARRAY_IN_STR_VALUE = 35
9
+ IN_ARRAY_POST_VALUE = 40
10
+ IN_HASH_PRE_KEY = 50
11
+ IN_HASH_IN_KEY = 60
12
+ IN_HASH_POST_KEY = 70
13
+ IN_HASH_PRE_VALUE = 80
14
+ IN_HASH_IN_VALUE = 90
15
+ IN_HASH_IN_STR_VALUE = 95
16
+ IN_HASH_POST_VALUE = 100
17
+ end
18
+
19
+ module JSON
20
+
21
+ module_function
22
+
23
+ def endure_and_parse(str)
24
+ parse endure str
25
+ end
26
+
27
+ def endure(str)
28
+
29
+ literal_mark = literal_char = false
30
+ state_stack = Array.new
31
+
32
+ state_stack << JsonStateVariable::INIT
33
+
34
+ str.chomp!
35
+ arr = str.split(//)
36
+ arr.each do |c|
37
+
38
+ if literal_mark && ! literal_char
39
+ literal_char = true
40
+ elsif literal_mark && literal_char
41
+ literal_mark = false
42
+ literal_char = false
43
+ end
44
+
45
+ case state_stack.last
46
+ when JsonStateVariable::INIT
47
+ if c == '['
48
+ state_stack << JsonStateVariable::IN_ARRAY_PRE_VALUE
49
+ elsif c == '{'
50
+ state_stack << JsonStateVariable::IN_HASH_PRE_KEY
51
+ end
52
+
53
+ when JsonStateVariable::IN_ARRAY_PRE_VALUE
54
+ if c == '['
55
+ state_stack.last = JsonStateVariable::IN_ARRAY_POST_VALUE
56
+ state_stack << JsonStateVariable::IN_ARRAY_PRE_VALUE
57
+ elsif c == '{'
58
+ state_stack.last = JsonStateVariable::IN_ARRAY_POST_VALUE
59
+ state_stack << JsonStateVariable::IN_HASH_PRE_KEY
60
+ elsif c == ','
61
+ state_stack.last = JsonStateVariable::IN_ARRAY_PRE_VALUE
62
+ elsif c == '"'
63
+ state_stack.last = JsonStateVariable::IN_ARRAY_IN_STR_VALUE
64
+ elsif c == ']'
65
+ state_stack.pop
66
+ elsif c =~ /\S/
67
+ state_stack.last = JsonStateVariable::IN_ARRAY_IN_VALUE
68
+ end
69
+
70
+ when JsonStateVariable::IN_ARRAY_IN_VALUE
71
+ if c == ','
72
+ state_stack.last = JsonStateVariable::IN_ARRAY_PRE_VALUE
73
+ elsif c == ']'
74
+ state_stack.pop
75
+ end
76
+
77
+ when JsonStateVariable::IN_ARRAY_IN_STR_VALUE
78
+ if c == '\\'
79
+ literal_mark = true
80
+ break
81
+ elsif c == '"'
82
+ state_stack.last = JsonStateVariable::IN_ARRAY_POST_VALUE
83
+ end
84
+
85
+ when JsonStateVariable::IN_ARRAY_POST_VALUE
86
+ if c == ','
87
+ state_stack.last = JsonStateVariable::IN_ARRAY_PRE_VALUE
88
+ elsif c == ']'
89
+ state_stack.pop
90
+ end
91
+
92
+ when JsonStateVariable::IN_HASH_PRE_KEY
93
+ if c == '"'
94
+ state_stack.last = JsonStateVariable::IN_HASH_IN_KEY
95
+ elsif c == '}'
96
+ state_stack.pop
97
+ end
98
+
99
+ when JsonStateVariable::IN_HASH_IN_KEY
100
+ state_stack.last = JsonStateVariable::IN_HASH_POST_KEY if c == '"'
101
+
102
+ when JsonStateVariable::IN_HASH_POST_KEY
103
+ state_stack.last = JsonStateVariable::IN_HASH_PRE_VALUE if c == ':'
104
+
105
+ when JsonStateVariable::IN_HASH_PRE_VALUE
106
+ if c == '['
107
+ state_stack.last = JsonStateVariable::IN_HASH_POST_VALUE
108
+ state_stack << JsonStateVariable::IN_ARRAY_PRE_VALUE
109
+ elsif c == '{'
110
+ state_stack.last = JsonStateVariable::IN_HASH_POST_VALUE
111
+ state_stack << JsonStateVariable::IN_HASH_PRE_KEY
112
+ elsif c == ','
113
+ state_stack.last = JsonStateVariable::IN_HASH_PRE_KEY
114
+ elsif c == '"'
115
+ state_stack.last = JsonStateVariable::IN_HASH_IN_STR_VALUE
116
+ elsif c =~ /\S/
117
+ state_stack.last = JsonStateVariable::IN_HASH_IN_VALUE
118
+ end
119
+
120
+ when JsonStateVariable::IN_HASH_IN_VALUE
121
+ state_stack.last = JsonStateVariable::IN_HASH_PRE_KEY if c == ','
122
+
123
+ when JsonStateVariable::IN_HASH_IN_STR_VALUE
124
+ if c == '\\'
125
+ literal_mark = true
126
+ break
127
+ elsif c == '"'
128
+ state_stack.last = JsonStateVariable::IN_HASH_POST_VALUE
129
+ end
130
+
131
+ when JsonStateVariable::IN_HASH_POST_VALUE
132
+ if c == ','
133
+ state_stack.last = JsonStateVariable::IN_HASH_PRE_KEY
134
+ elsif c == '}'
135
+ state_stack.pop
136
+ end
137
+
138
+ end unless literal_mark
139
+
140
+ end
141
+
142
+ state_stack.reverse.each do |s|
143
+ catch(:redo) do
144
+ case s
145
+ when JsonStateVariable::INIT
146
+
147
+ when JsonStateVariable::IN_ARRAY_PRE_VALUE
148
+ str << '"'
149
+ s = JsonStateVariable::IN_ARRAY_IN_STR_VALUE
150
+ redo
151
+
152
+ when JsonStateVariable::IN_ARRAY_IN_VALUE
153
+ s = JsonStateVariable::IN_ARRAY_POST_VALUE
154
+ redo
155
+
156
+ when JsonStateVariable::IN_ARRAY_IN_STR_VALUE
157
+ str << '"'
158
+ s = JsonStateVariable::IN_ARRAY_POST_VALUE
159
+ redo
160
+
161
+ when JsonStateVariable::IN_ARRAY_POST_VALUE
162
+ str << ']'
163
+
164
+ when JsonStateVariable::IN_HASH_PRE_KEY
165
+ str << '"'
166
+ s = JsonStateVariable::IN_HASH_IN_KEY
167
+ redo
168
+
169
+ when JsonStateVariable::IN_HASH_IN_KEY
170
+ str << '"'
171
+ s = JsonStateVariable::IN_HASH_POST_KEY
172
+ redo
173
+
174
+ when JsonStateVariable::IN_HASH_POST_KEY
175
+ str << ':'
176
+ s = JsonStateVariable::IN_HASH_PRE_VALUE
177
+ redo
178
+
179
+ when JsonStateVariable::IN_HASH_PRE_VALUE
180
+ str << '"'
181
+ s = JsonStateVariable::IN_HASH_IN_STR_VALUE
182
+ redo
183
+
184
+ when JsonStateVariable::IN_HASH_IN_VALUE
185
+ s = JsonStateVariable::IN_HASH_POST_VALUE
186
+ redo
187
+
188
+ when JsonStateVariable::IN_HASH_IN_STR_VALUE
189
+ str << '"'
190
+ s = JsonStateVariable::IN_HASH_POST_VALUE
191
+ redo
192
+
193
+ when JsonStateVariable::IN_HASH_POST_VALUE
194
+ str << '}'
195
+
196
+ end
197
+ end
198
+ end
199
+
200
+ return str
201
+ end
202
+
203
+ end
204
+
205
+ # vim:set et ts=2 sts=2 sw=2 tw=72 wm=72 ai:
@@ -0,0 +1,17 @@
1
+ require File.expand_path File.join(File.dirname(__FILE__), 'json')
2
+
3
+ class String
4
+
5
+ def coax_into_json()
6
+ str = self.clone
7
+ str.coax_into_json!()
8
+ return str
9
+ end
10
+
11
+ def coax_into_json!()
12
+ self.replace(JSON.endure(self))
13
+ end
14
+
15
+ end
16
+
17
+ # vim:set et ts=2 sts=2 sw=2 tw=72 wm=72 ai:
@@ -0,0 +1,13 @@
1
+ require File.expand_path File.join(File.dirname(__FILE__), '../lib/json-endure/array')
2
+
3
+ describe Array, "#last=" do
4
+ it "sets the last element to a new value" do
5
+ array = Array.new
6
+ array = [ 1, 3, 5 ]
7
+ array.last = 4
8
+ array.last.should eq(4)
9
+ end
10
+ end
11
+
12
+ # vim:set et ts=2 sts=2 sw=2 tw=72 wm=72 ai:
13
+
data/spec/json_spec.rb ADDED
@@ -0,0 +1,376 @@
1
+ $:.delete(File.expand_path File.join(File.dirname(__FILE__), '../lib'))
2
+ require 'json'
3
+ require File.expand_path File.join(File.dirname(__FILE__), '../lib/json-endure/json')
4
+
5
+ describe JSON, "::endure" do
6
+
7
+ it "returns the endured string" do
8
+ string = String.new('{ "123": "90", "abc": { "30')
9
+ expected_value = String.new('{ "123": "90", "abc": { "30":""}}')
10
+
11
+ test_value = JSON.endure(string)
12
+
13
+ test_value.should eq(expected_value)
14
+ end
15
+ end
16
+
17
+ describe JSON, "::endure_and_parse" do
18
+
19
+ it "handles empty arrays" do
20
+ string = String.new('[]')
21
+ expected_value = Array.new
22
+
23
+ test_value = JSON.endure_and_parse(string)
24
+
25
+ test_value.should eq(expected_value)
26
+ end
27
+
28
+ it "handles empty hashes" do
29
+ string = String.new('{}')
30
+ expected_value = Hash.new
31
+
32
+ test_value = JSON.endure_and_parse(string)
33
+
34
+ test_value.should eq(expected_value)
35
+ end
36
+
37
+ # ----- IN_ARRAY -----
38
+
39
+ it "handles an array with a single value" do
40
+ string = String.new('[ 123 ]')
41
+ expected_value = Array.new
42
+ expected_value << 123
43
+
44
+ test_value = JSON.endure_and_parse(string)
45
+
46
+ test_value.should eq(expected_value)
47
+ end
48
+
49
+ it "handles empty hashes inside an array" do
50
+ string = String.new('[1, {}]')
51
+ expected_value = Array.new
52
+ expected_value << 1
53
+ expected_value << Hash.new
54
+
55
+ test_value = JSON.endure_and_parse(string)
56
+
57
+ test_value.should eq(expected_value)
58
+ end
59
+
60
+ it "handles empty arrays inside a hash" do
61
+ string = String.new('{"a": []}')
62
+ expected_value = Hash.new
63
+ expected_value["a"] = Array.new
64
+
65
+ test_value = JSON.endure_and_parse(string)
66
+
67
+ test_value.should eq(expected_value)
68
+ end
69
+
70
+ it "handles interrupted array, pre-value" do
71
+ string = String.new('[ ')
72
+ expected_value = Array.new
73
+ expected_value << ""
74
+
75
+ test_value = JSON.endure_and_parse(string)
76
+
77
+ test_value.should eq(expected_value)
78
+ end
79
+
80
+ it "handles interrupted array mid-value" do
81
+ string = String.new('[ 123, 90')
82
+ expected_value = Array.new
83
+ expected_value << 123
84
+ expected_value << 90
85
+
86
+ test_value = JSON.endure_and_parse(string)
87
+
88
+ test_value.should eq(expected_value)
89
+ end
90
+
91
+ it "handles interrupted array mid-string" do
92
+ string = String.new('[ 123, "90')
93
+ expected_value = Array.new
94
+ expected_value << 123
95
+ expected_value << "90"
96
+
97
+ test_value = JSON.endure_and_parse(string)
98
+
99
+ test_value.should eq(expected_value)
100
+ end
101
+
102
+ it "handles embedded literal \" characters mid-string" do
103
+ string = String.new('[ 123, "9\"0')
104
+ expected_value = Array.new
105
+ expected_value << 123
106
+ expected_value << '9"0'
107
+
108
+ test_value = JSON.endure_and_parse(string)
109
+
110
+ test_value.should eq(expected_value)
111
+ end
112
+
113
+ it "handles an interrupted array inside an array" do
114
+ string = String.new('[ 123, [ 30')
115
+ expected_value = Array.new
116
+ expected_value << 123
117
+ internal_array = Array.new
118
+ internal_array << 30
119
+ expected_value << internal_array
120
+
121
+ test_value = JSON.endure_and_parse(string)
122
+
123
+ test_value.should eq(expected_value)
124
+ end
125
+
126
+ it "handles an interrupted array with a complete internal array" do
127
+ string = String.new('[ 123, [ 30 ]')
128
+ expected_value = Array.new
129
+ expected_value << 123
130
+ internal_array = Array.new
131
+ internal_array << 30
132
+ expected_value << internal_array
133
+
134
+ test_value = JSON.endure_and_parse(string)
135
+
136
+ test_value.should eq(expected_value)
137
+ end
138
+
139
+ it "handles an interrupted array, mid-key, inside an array" do
140
+ string = String.new('[ 123, { "90')
141
+ expected_value = Array.new
142
+ expected_value << 123
143
+ internal_hash = Hash.new
144
+ internal_hash["90"] = ""
145
+ expected_value << internal_hash
146
+
147
+ test_value = JSON.endure_and_parse(string)
148
+
149
+ test_value.should eq(expected_value)
150
+ end
151
+
152
+ it "handles an interrupted array, mid-value, inside an array" do
153
+ string = String.new('[ 123, { "90": 123')
154
+ expected_value = Array.new
155
+ expected_value << 123
156
+ internal_hash = Hash.new
157
+ internal_hash["90"] = 123
158
+ expected_value << internal_hash
159
+
160
+ test_value = JSON.endure_and_parse(string)
161
+
162
+ test_value.should eq(expected_value)
163
+ end
164
+
165
+ it "handles an interrupted array, mid-string, inside an array" do
166
+ string = String.new('[ 123, { "90": "123')
167
+ expected_value = Array.new
168
+ expected_value << 123
169
+ internal_hash = Hash.new
170
+ internal_hash["90"] = "123"
171
+ expected_value << internal_hash
172
+
173
+ test_value = JSON.endure_and_parse(string)
174
+
175
+ test_value.should eq(expected_value)
176
+ end
177
+
178
+ it "handles an interrupted array with a complete internal hash" do
179
+ string = String.new('[ 123, { "90": "123" }' )
180
+ expected_value = Array.new
181
+ expected_value << 123
182
+ internal_hash = Hash.new
183
+ internal_hash["90"] = "123"
184
+ expected_value << internal_hash
185
+
186
+ test_value = JSON.endure_and_parse(string)
187
+
188
+ test_value.should eq(expected_value)
189
+ end
190
+
191
+ it "handles interrupted array after string" do
192
+ string = String.new('[ 123, "90"')
193
+ expected_value = Array.new
194
+ expected_value << 123
195
+ expected_value << "90"
196
+
197
+ test_value = JSON.endure_and_parse(string)
198
+
199
+ test_value.should eq(expected_value)
200
+ end
201
+
202
+ # ----- IN_HASH -----
203
+
204
+ it "handles an array with a single value" do
205
+ string = String.new('{ "123": 90')
206
+ expected_value = Hash.new
207
+ expected_value["123"] = 90
208
+
209
+ test_value = JSON.endure_and_parse(string)
210
+
211
+ test_value.should eq(expected_value)
212
+ end
213
+
214
+ it "handles interrupted hash, pre-key" do
215
+ string = String.new('{ ')
216
+ expected_value = Hash.new
217
+ expected_value[""] = ""
218
+
219
+ test_value = JSON.endure_and_parse(string)
220
+
221
+ test_value.should eq(expected_value)
222
+ end
223
+
224
+ it "handles interrupted hash, mid-key" do
225
+ string = String.new('{ "12')
226
+ expected_value = Hash.new
227
+ expected_value["12"] = ""
228
+
229
+ test_value = JSON.endure_and_parse(string)
230
+
231
+ test_value.should eq(expected_value)
232
+ end
233
+
234
+ it "handles interrupted hash, post-key" do
235
+ string = String.new('{ "12": ')
236
+ expected_value = Hash.new
237
+ expected_value["12"] = ""
238
+
239
+ test_value = JSON.endure_and_parse(string)
240
+
241
+ test_value.should eq(expected_value)
242
+ end
243
+
244
+ it "handles interrupted hash, mid-value" do
245
+ string = String.new('{ "123": 90')
246
+ expected_value = Hash.new
247
+ expected_value["123"] = 90
248
+
249
+ test_value = JSON.endure_and_parse(string)
250
+
251
+ test_value.should eq(expected_value)
252
+ end
253
+
254
+ it "handles interrupted hash, mid-string" do
255
+ string = String.new('{ "123": "90')
256
+ expected_value = Hash.new
257
+ expected_value["123"] = "90"
258
+
259
+ test_value = JSON.endure_and_parse(string)
260
+
261
+ test_value.should eq(expected_value)
262
+ end
263
+
264
+ it "handles embedded literal \" characters mid-string" do
265
+ string = String.new('{ "123": "9\"0')
266
+ expected_value = Hash.new
267
+ expected_value["123"] = '9"0'
268
+
269
+ test_value = JSON.endure_and_parse(string)
270
+
271
+ test_value.should eq(expected_value)
272
+ end
273
+
274
+
275
+ it "handles interrupted hash after string" do
276
+ string = String.new('{ "123": "90"')
277
+ expected_value = Hash.new
278
+ expected_value["123"] = "90"
279
+
280
+ test_value = JSON.endure_and_parse(string)
281
+
282
+ test_value.should eq(expected_value)
283
+ end
284
+
285
+ it "handles an interrupted hash with an interrupted internal array" do
286
+ string = String.new('{ "123": "90", "abc": [ 30')
287
+ expected_value = Hash.new
288
+ expected_value["123"] = "90"
289
+ internal_array = Array.new
290
+ internal_array << 30
291
+ expected_value["abc"] = internal_array
292
+
293
+ test_value = JSON.endure_and_parse(string)
294
+
295
+ test_value.should eq(expected_value)
296
+ end
297
+
298
+ it "handles an interrupted hash with a complete internal array" do
299
+ string = String.new('{ "123": "90", "abc": [ 30 ]')
300
+ expected_value = Hash.new
301
+ expected_value["123"] = "90"
302
+ internal_array = Array.new
303
+ internal_array << 30
304
+ expected_value["abc"] = internal_array
305
+
306
+ test_value = JSON.endure_and_parse(string)
307
+
308
+ test_value.should eq(expected_value)
309
+ end
310
+
311
+ it "handles an interrupted hash, mid-key, inside a hash" do
312
+ string = String.new('{ "123": "90", "abc": { "30')
313
+ expected_value = Hash.new
314
+ expected_value["123"] = "90"
315
+ internal_array = Hash.new
316
+ internal_array["30"] = ""
317
+ expected_value["abc"] = internal_array
318
+
319
+ test_value = JSON.endure_and_parse(string)
320
+
321
+ test_value.should eq(expected_value)
322
+ end
323
+
324
+ it "handles an interrupted hash, mid-value, inside a hash" do
325
+ string = String.new('{ "123": "90", "abc": { "30": 456')
326
+ expected_value = Hash.new
327
+ expected_value["123"] = "90"
328
+ internal_array = Hash.new
329
+ internal_array["30"] = 456
330
+ expected_value["abc"] = internal_array
331
+
332
+ test_value = JSON.endure_and_parse(string)
333
+
334
+ test_value.should eq(expected_value)
335
+ end
336
+
337
+ it "handles an interrupted hash, mid-string, inside a hash" do
338
+ string = String.new('{ "123": "90", "abc": { "30": "456')
339
+ expected_value = Hash.new
340
+ expected_value["123"] = "90"
341
+ internal_array = Hash.new
342
+ internal_array["30"] = "456"
343
+ expected_value["abc"] = internal_array
344
+
345
+ test_value = JSON.endure_and_parse(string)
346
+
347
+ test_value.should eq(expected_value)
348
+ end
349
+
350
+ it "handles an interrupted hash with a complete internal hash" do
351
+ string = String.new('{ "123": "90", "abc": { "30": "456" }')
352
+ expected_value = Hash.new
353
+ expected_value["123"] = "90"
354
+ internal_array = Hash.new
355
+ internal_array["30"] = "456"
356
+ expected_value["abc"] = internal_array
357
+
358
+ test_value = JSON.endure_and_parse(string)
359
+
360
+ test_value.should eq(expected_value)
361
+ end
362
+
363
+ it "handles interrupted hash, after pair, pre-key" do
364
+ string = String.new('{ "123": "90", ')
365
+ expected_value = Hash.new
366
+ expected_value["123"] = "90"
367
+ expected_value[""] = ""
368
+
369
+ test_value = JSON.endure_and_parse(string)
370
+
371
+ test_value.should eq(expected_value)
372
+ end
373
+
374
+ end
375
+
376
+ # vim:set et ts=2 sts=2 sw=2 tw=72 wm=72 ai:
@@ -0,0 +1,27 @@
1
+ require File.expand_path File.join(File.dirname(__FILE__), '../lib/json-endure/string')
2
+
3
+ describe String, "#coax_into_json" do
4
+
5
+ it "returns the string endured string" do
6
+ string = String.new('{ "123": "90", "abc": { "30')
7
+ expected_value = String.new('{ "123": "90", "abc": { "30":""}}')
8
+
9
+ test_value = string.coax_into_json
10
+
11
+ test_value.should eq(expected_value)
12
+ end
13
+ end
14
+
15
+ describe String, "#coax_into_json!" do
16
+
17
+ it "coaxes the string back into proper JSON" do
18
+ string = String.new('{ "123": "90", "abc": { "30')
19
+ expected_value = String.new('{ "123": "90", "abc": { "30":""}}')
20
+
21
+ string.coax_into_json!
22
+
23
+ expected_value.should eq(string)
24
+ end
25
+ end
26
+
27
+ # vim:set et ts=2 sts=2 sw=2 tw=72 wm=72 ai:
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: json-endure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Burnheimer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-11 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: &2168697580 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2168697580
25
+ description: Helper methods to JSON and String to make-do with truncated JSON text.
26
+ email: Andrew_Burnheimer@cable.comcast.com
27
+ executables: []
28
+ extensions: []
29
+ extra_rdoc_files: []
30
+ files:
31
+ - .rspec
32
+ - LICENSE
33
+ - README.md
34
+ - json-endure.gemspec
35
+ - lib/json-endure.rb
36
+ - lib/json-endure/array.rb
37
+ - lib/json-endure/json.rb
38
+ - lib/json-endure/string.rb
39
+ - spec/array_spec.rb
40
+ - spec/json_spec.rb
41
+ - spec/string_spec.rb
42
+ homepage: https://github.com/aburnheimer/json-endure
43
+ licenses:
44
+ - CC-BY-3.0
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.10
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Handle truncated JSON-text
67
+ test_files:
68
+ - spec/array_spec.rb
69
+ - spec/json_spec.rb
70
+ - spec/string_spec.rb