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 +0 -0
- data/LICENSE +14 -0
- data/README.md +60 -0
- data/json-endure.gemspec +21 -0
- data/lib/json-endure.rb +2 -0
- data/lib/json-endure/array.rb +6 -0
- data/lib/json-endure/json.rb +205 -0
- data/lib/json-endure/string.rb +17 -0
- data/spec/array_spec.rb +13 -0
- data/spec/json_spec.rb +376 -0
- data/spec/string_spec.rb +27 -0
- metadata +70 -0
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/
|
data/json-endure.gemspec
ADDED
@@ -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
|
data/lib/json-endure.rb
ADDED
@@ -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:
|
data/spec/array_spec.rb
ADDED
@@ -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:
|
data/spec/string_spec.rb
ADDED
@@ -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
|