sketchup_json 0.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.
- data/lib/sketchup_json/generator.rb +61 -0
- data/lib/sketchup_json/parser.rb +257 -0
- data/sketchup_json.gemspec +20 -0
- data/sketchup_json.rb +5 -0
- data/spec/fixtures/so-alltags.json +287 -0
- data/spec/sketchup_json/generator_spec.rb +35 -0
- data/spec/sketchup_json/parser_spec.rb +75 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +11 -0
- metadata +76 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module SketchUpJSON
|
|
2
|
+
JSONEncodeError = Class.new(StandardError)
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
class String
|
|
6
|
+
def to_json
|
|
7
|
+
%Q["#{ self.escape_quotes }"]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def escape_quotes
|
|
11
|
+
self.gsub('"', '\"')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Numeric
|
|
16
|
+
def to_json
|
|
17
|
+
to_s
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class TrueClass
|
|
22
|
+
def to_json
|
|
23
|
+
to_s
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class FalseClass
|
|
28
|
+
def to_json
|
|
29
|
+
to_s
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class NilClass
|
|
34
|
+
def to_json
|
|
35
|
+
"null"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class Array
|
|
40
|
+
def to_json
|
|
41
|
+
values = collect { |item| item.to_json }
|
|
42
|
+
"[#{ values.join(", ") }]"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class Hash
|
|
47
|
+
def to_json
|
|
48
|
+
values = collect do |k, v|
|
|
49
|
+
validate_key! k
|
|
50
|
+
%Q["#{k.to_s}" : #{v.to_json}]
|
|
51
|
+
end
|
|
52
|
+
"{#{ values.join(", ") }}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# In valid json all object keys are strings
|
|
56
|
+
def validate_key!(key)
|
|
57
|
+
unless key.is_a?(String) or key.is_a?(Symbol)
|
|
58
|
+
raise SketchUpJSON::JSONEncodeError, "This hash can not generate valid JSON"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
class String
|
|
2
|
+
def char_at(n)
|
|
3
|
+
self[n] and self[n].chr
|
|
4
|
+
end
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module SketchUpJSON
|
|
8
|
+
SyntaxError = Class.new(StandardError)
|
|
9
|
+
|
|
10
|
+
class Parser
|
|
11
|
+
ESCAPEE = {
|
|
12
|
+
'"' => '"',
|
|
13
|
+
'\\' => '\\',
|
|
14
|
+
'/' => '/',
|
|
15
|
+
'b' => 'b',
|
|
16
|
+
'f' => '\f',
|
|
17
|
+
'n' => '\n',
|
|
18
|
+
't' => '\t',
|
|
19
|
+
'r' => '\r',
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
def initialize(json_string)
|
|
23
|
+
@at, @ch = 0, nil
|
|
24
|
+
@openned_brackets = 0
|
|
25
|
+
@openned_square_brackets = 0
|
|
26
|
+
@openned_quotes = 0
|
|
27
|
+
@text = json_string
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def parse
|
|
31
|
+
value
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def value
|
|
37
|
+
white
|
|
38
|
+
case @ch
|
|
39
|
+
when '{'
|
|
40
|
+
return object
|
|
41
|
+
when '['
|
|
42
|
+
return array
|
|
43
|
+
when '"'
|
|
44
|
+
return string
|
|
45
|
+
when '-', '+', /\d/
|
|
46
|
+
return number
|
|
47
|
+
else
|
|
48
|
+
return word
|
|
49
|
+
end
|
|
50
|
+
raise SyntaxError.new "Invalid syntax. Index #{@at}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def object
|
|
54
|
+
obj = {}
|
|
55
|
+
|
|
56
|
+
if @ch == '{'
|
|
57
|
+
update_delimiter_counter! @ch
|
|
58
|
+
next_char '{'
|
|
59
|
+
white
|
|
60
|
+
|
|
61
|
+
if @ch == '}'
|
|
62
|
+
update_delimiter_counter! @ch
|
|
63
|
+
next_char '}'
|
|
64
|
+
return obj
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
while @ch
|
|
68
|
+
key = string
|
|
69
|
+
white
|
|
70
|
+
next_char ':'
|
|
71
|
+
obj[key] = value
|
|
72
|
+
white
|
|
73
|
+
|
|
74
|
+
if @ch == '}'
|
|
75
|
+
update_delimiter_counter! @ch
|
|
76
|
+
next_char '}'
|
|
77
|
+
return obj
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
next_char ','
|
|
81
|
+
white
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
raise SyntaxError.new "Bad object"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def array
|
|
89
|
+
arr = []
|
|
90
|
+
|
|
91
|
+
if @ch == '['
|
|
92
|
+
next_char '['
|
|
93
|
+
white
|
|
94
|
+
|
|
95
|
+
if @ch == ']'
|
|
96
|
+
next_char ']'
|
|
97
|
+
return arr
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
while @ch
|
|
101
|
+
arr.push(value)
|
|
102
|
+
white
|
|
103
|
+
|
|
104
|
+
if @ch == ']'
|
|
105
|
+
next_char ']'
|
|
106
|
+
return arr
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
next_char ','
|
|
110
|
+
white
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
raise SyntaxError.new "Bad array"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def string
|
|
118
|
+
str = ''
|
|
119
|
+
|
|
120
|
+
if @ch == '"'
|
|
121
|
+
while next_char
|
|
122
|
+
if @ch == '"'
|
|
123
|
+
next_char
|
|
124
|
+
return str
|
|
125
|
+
|
|
126
|
+
elsif @ch == '\\'
|
|
127
|
+
next_char
|
|
128
|
+
|
|
129
|
+
if @ch == 'u'
|
|
130
|
+
uffff = 0
|
|
131
|
+
4.times do
|
|
132
|
+
hex = next_char.to_i(16)
|
|
133
|
+
break unless hex.is_a? Numeric
|
|
134
|
+
uffff = uffff * 16 + hex
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
str += uffff.chr
|
|
138
|
+
elsif ESCAPEE[@ch]
|
|
139
|
+
str += ESCAPEE[@ch]
|
|
140
|
+
else
|
|
141
|
+
break
|
|
142
|
+
end
|
|
143
|
+
else
|
|
144
|
+
str += @ch
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
raise SyntaxError.new "Bad string"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def number
|
|
153
|
+
string = ''
|
|
154
|
+
|
|
155
|
+
if @ch == '-'
|
|
156
|
+
string = '-'
|
|
157
|
+
next_char '-'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
while decimal?(@ch)
|
|
161
|
+
string += @ch
|
|
162
|
+
next_char
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
if @ch == '.'
|
|
166
|
+
string += '.'
|
|
167
|
+
|
|
168
|
+
while next_char && decimal?(@ch)
|
|
169
|
+
string += @ch
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
if @ch == 'e' || @ch == 'E'
|
|
174
|
+
string += @ch
|
|
175
|
+
next_char
|
|
176
|
+
|
|
177
|
+
if @ch == '-' || @ch == '+'
|
|
178
|
+
string += @ch
|
|
179
|
+
next_char
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
while decimal?(@ch)
|
|
183
|
+
string += @ch
|
|
184
|
+
next_char
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
raise SyntaxError.new "Bad number" unless number?(string)
|
|
189
|
+
string.send convertion_method(string)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def word
|
|
193
|
+
proc = Proc.new { |l| next_char l }
|
|
194
|
+
case @ch
|
|
195
|
+
when 't'
|
|
196
|
+
%w(t r u e).map &proc
|
|
197
|
+
return true
|
|
198
|
+
when 'f'
|
|
199
|
+
%w(f a l s e).map &proc
|
|
200
|
+
return false
|
|
201
|
+
when 'n'
|
|
202
|
+
%w(n u l l).map &proc
|
|
203
|
+
return nil
|
|
204
|
+
end
|
|
205
|
+
raise SyntaxError.new "Unexpected #{@ch}"
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def next_char(c = nil)
|
|
209
|
+
ensure_ended_chars!
|
|
210
|
+
if c && c != @ch
|
|
211
|
+
raise SyntaxError.new "Expected #{c} instead of #{@ch}"
|
|
212
|
+
else
|
|
213
|
+
@ch = @text.char_at(@at)
|
|
214
|
+
@at += 1
|
|
215
|
+
@ch
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def convertion_method(str)
|
|
220
|
+
str.index('.') || str.index('e') || str.index('E') ? :to_f : :to_i
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def number?(str)
|
|
224
|
+
str.match /[-]?([1-9]|(0\.))[0-9]*[eE]?[+-]?[0-9]*/
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def decimal?(n)
|
|
228
|
+
n && n.match(/\d/)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def white
|
|
232
|
+
next_char while @ch.nil? || @ch.strip.empty?
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def ensure_ended_chars!
|
|
236
|
+
if @at == @text.size
|
|
237
|
+
counters = [@openned_brackets, @openned_square_brackets, @openned_quotes]
|
|
238
|
+
counters.map do |counter|
|
|
239
|
+
raise SyntaxError unless counter.zero?
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def update_delimiter_counter!(char)
|
|
245
|
+
case char
|
|
246
|
+
when '{'
|
|
247
|
+
@openned_brackets += 1
|
|
248
|
+
when '}'
|
|
249
|
+
@openned_brackets -= 1
|
|
250
|
+
when '['
|
|
251
|
+
@openned_square_brackets +=1
|
|
252
|
+
when ']'
|
|
253
|
+
@openned_square_brackets -=1
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Gem::Specification.new do |gem|
|
|
2
|
+
gem.name = "sketchup_json"
|
|
3
|
+
gem.version = "0.1.0"
|
|
4
|
+
gem.authors = ["Dalto Curvelano Junior", "Superficie.org"]
|
|
5
|
+
gem.description = "A simple JSON parser/generator suited to be used in Google Sketchup"
|
|
6
|
+
gem.summary = "Google Sketchup's Ruby version doesn't have any standard libraries. This gem provides a simple API for parsing and generating JSON data."
|
|
7
|
+
|
|
8
|
+
gem.files = [
|
|
9
|
+
"sketchup_json.rb",
|
|
10
|
+
"sketchup_json.gemspec",
|
|
11
|
+
"lib/sketchup_json/generator.rb",
|
|
12
|
+
"lib/sketchup_json/parser.rb",
|
|
13
|
+
"spec/fixtures/so-alltags.json",
|
|
14
|
+
"spec/sketchup_json/generator_spec.rb",
|
|
15
|
+
"spec/sketchup_json/parser_spec.rb",
|
|
16
|
+
"spec/spec.opts",
|
|
17
|
+
"spec/spec_helper.rb"
|
|
18
|
+
]
|
|
19
|
+
gem.homepage = ""
|
|
20
|
+
end
|
data/sketchup_json.rb
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
{
|
|
2
|
+
"total": 29199,
|
|
3
|
+
"page": 1,
|
|
4
|
+
"pagesize": 70,
|
|
5
|
+
"tags": [
|
|
6
|
+
{
|
|
7
|
+
"name": "c#",
|
|
8
|
+
"count": 84875
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"name": "java",
|
|
12
|
+
"count": 50661
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": ".net",
|
|
16
|
+
"count": 42982
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "php",
|
|
20
|
+
"count": 42359
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "asp.net",
|
|
24
|
+
"count": 38560
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "javascript",
|
|
28
|
+
"count": 37024
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "c++",
|
|
32
|
+
"count": 31709
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "jquery",
|
|
36
|
+
"count": 29607
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "iphone",
|
|
40
|
+
"count": 26442
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "python",
|
|
44
|
+
"count": 25583
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "sql",
|
|
48
|
+
"count": 20885
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "mysql",
|
|
52
|
+
"count": 18581
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "html",
|
|
56
|
+
"count": 17460
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "sql-server",
|
|
60
|
+
"count": 15911
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "ruby-on-rails",
|
|
64
|
+
"count": 14369
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "c",
|
|
68
|
+
"count": 13986
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"name": "asp.net-mvc",
|
|
72
|
+
"count": 13154
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "css",
|
|
76
|
+
"count": 13126
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "wpf",
|
|
80
|
+
"count": 13074
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "objective-c",
|
|
84
|
+
"count": 12652
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "windows",
|
|
88
|
+
"count": 10966
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "xml",
|
|
92
|
+
"count": 10172
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"name": "ruby",
|
|
96
|
+
"count": 10157
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "database",
|
|
100
|
+
"count": 9314
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "best-practices",
|
|
104
|
+
"count": 9280
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "android",
|
|
108
|
+
"count": 9129
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"name": "vb.net",
|
|
112
|
+
"count": 8826
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "visual-studio",
|
|
116
|
+
"count": 8564
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "ajax",
|
|
120
|
+
"count": 8168
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "winforms",
|
|
124
|
+
"count": 8154
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "regex",
|
|
128
|
+
"count": 8120
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "linux",
|
|
132
|
+
"count": 8031
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "django",
|
|
136
|
+
"count": 7724
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"name": "iphone-sdk",
|
|
140
|
+
"count": 7322
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "visual-studio-2008",
|
|
144
|
+
"count": 6996
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"name": "beginner",
|
|
148
|
+
"count": 6687
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"name": "web-development",
|
|
152
|
+
"count": 6485
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"name": "flex",
|
|
156
|
+
"count": 6404
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"name": "subjective",
|
|
160
|
+
"count": 6229
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"name": "flash",
|
|
164
|
+
"count": 6086
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"name": "linq",
|
|
168
|
+
"count": 5998
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "wcf",
|
|
172
|
+
"count": 5865
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"name": "silverlight",
|
|
176
|
+
"count": 5761
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "cocoa",
|
|
180
|
+
"count": 5659
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"name": "actionscript-3",
|
|
184
|
+
"count": 5359
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"name": "sql-server-2005",
|
|
188
|
+
"count": 5329
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"name": "cocoa-touch",
|
|
192
|
+
"count": 5257
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"name": "performance",
|
|
196
|
+
"count": 5236
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"name": "algorithm",
|
|
200
|
+
"count": 5142
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"name": "perl",
|
|
204
|
+
"count": 5081
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"name": "eclipse",
|
|
208
|
+
"count": 5072
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"name": "oracle",
|
|
212
|
+
"count": 5045
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"name": "web-services",
|
|
216
|
+
"count": 4859
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"name": "security",
|
|
220
|
+
"count": 4848
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"name": "svn",
|
|
224
|
+
"count": 4837
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"name": "delphi",
|
|
228
|
+
"count": 4778
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"name": "multithreading",
|
|
232
|
+
"count": 4762
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"name": "sharepoint",
|
|
236
|
+
"count": 4760
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"name": "arrays",
|
|
240
|
+
"count": 4395
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"name": "unit-testing",
|
|
244
|
+
"count": 4292
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"name": "nhibernate",
|
|
248
|
+
"count": 4216
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"name": "linq-to-sql",
|
|
252
|
+
"count": 4171
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"name": "tsql",
|
|
256
|
+
"count": 4031
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"name": "apache",
|
|
260
|
+
"count": 3882
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"name": "string",
|
|
264
|
+
"count": 3790
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"name": "homework",
|
|
268
|
+
"count": 3664
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"name": "excel",
|
|
272
|
+
"count": 3629
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"name": "design",
|
|
276
|
+
"count": 3506
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"name": "xcode",
|
|
280
|
+
"count": 3472
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"name": "mvc",
|
|
284
|
+
"count": 3427
|
|
285
|
+
}
|
|
286
|
+
]
|
|
287
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "JSON Generator" do
|
|
4
|
+
|
|
5
|
+
it "should generate json from strings" do
|
|
6
|
+
"text".to_json.should == '"text"'
|
|
7
|
+
'nested "quotes"'.to_json.should == '"nested \"quotes\""'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "should generate json from integers" do
|
|
11
|
+
1.to_json.should == "1"
|
|
12
|
+
10000.to_json.should == "10000"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should generate json from numerics" do
|
|
16
|
+
1.4901.to_json.should == "1.4901"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should generate json from booleans" do
|
|
20
|
+
true.to_json.should == "true"
|
|
21
|
+
false.to_json.should == "false"
|
|
22
|
+
nil.to_json.should == "null"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should generate json from arrays" do
|
|
26
|
+
[1, 2, 3].to_json.should == "[1, 2, 3]"
|
|
27
|
+
["oi", "como", "vai?"].to_json.should == '["oi", "como", "vai?"]'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should generate json from hashes" do
|
|
31
|
+
{ "text" => "text", "array" => [1, 2, 3] }.to_json.should == '{"text" : "text", "array" : [1, 2, 3]}'
|
|
32
|
+
{ :ratio => 1.534 }.to_json.should == '{"ratio" : 1.534}'
|
|
33
|
+
lambda { { 6 => [] }.to_json }.should raise_exception SketchUpJSON::JSONEncodeError
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
include SketchUpJSON
|
|
3
|
+
|
|
4
|
+
describe "JSON parser" do
|
|
5
|
+
it "should parse keywords" do
|
|
6
|
+
Parser.new("true").parse.should be_true
|
|
7
|
+
Parser.new("false").parse.should be_false
|
|
8
|
+
Parser.new("null").parse.should be_nil
|
|
9
|
+
|
|
10
|
+
lambda { Parser.new("puts").parse }.should raise_exception SketchUpJSON::SyntaxError
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should parse numbers" do
|
|
14
|
+
Parser.new("1").parse.should == 1
|
|
15
|
+
Parser.new("10").parse.should == 10
|
|
16
|
+
Parser.new("12345").parse.should == 12345
|
|
17
|
+
Parser.new("1.1").parse.should == 1.1
|
|
18
|
+
Parser.new("0.1234").parse.should == 0.1234
|
|
19
|
+
Parser.new("-1").parse.should == -1
|
|
20
|
+
Parser.new("-0.98").parse.should == -0.98
|
|
21
|
+
Parser.new("0.2e1").parse.should == 0.2e1
|
|
22
|
+
Parser.new("0.2e+1").parse.should == 0.2e+1
|
|
23
|
+
Parser.new("0.2e-1").parse.should == 0.2e-1
|
|
24
|
+
Parser.new("0.2e1").parse.should == 0.2E1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should parse arrays" do
|
|
28
|
+
Parser.new("[]").parse.should == []
|
|
29
|
+
Parser.new("[1]").parse.should == [1]
|
|
30
|
+
Parser.new("[1, 3, 4]").parse.should == [1, 3, 4]
|
|
31
|
+
Parser.new("[null, true, false, []]").parse.should == [nil, true, false, []]
|
|
32
|
+
Parser.new("[[], {}, 1]").parse.should == [[], {}, 1]
|
|
33
|
+
|
|
34
|
+
lambda { Parser.new("[;]").parse }.should raise_exception SketchUpJSON::SyntaxError
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should parse objects" do
|
|
38
|
+
Parser.new("{}").parse.should == {}
|
|
39
|
+
Parser.new(%Q[{ "number" : 1, "text" : "text"}]).parse.should == { 'number' => 1, 'text' => 'text' }
|
|
40
|
+
Parser.new(%Q[{ "array" : [], "object" : {}}]).parse.should == { 'array' => [], 'object' => {} }
|
|
41
|
+
Parser.new(%Q[{ "array" : [1, 2, 3], "null" : null}]).parse.should == { 'array' => [1, 2, 3], 'null' => nil }
|
|
42
|
+
|
|
43
|
+
lambda { Parser.new(%Q[{ "t" : }]).parse }.should raise_exception SketchUpJSON::SyntaxError
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should parse strings" do
|
|
47
|
+
Parser.new('""').parse.should == ""
|
|
48
|
+
Parser.new('"hello world"').parse.should == "hello world"
|
|
49
|
+
Parser.new('" "').parse.should == " "
|
|
50
|
+
Parser.new('"abracadabra666"').parse.should == "abracadabra666"
|
|
51
|
+
Parser.new('" }:8)"').parse.should == " }:8)"
|
|
52
|
+
Parser.new('"nested \"quotes\""').parse.should == "nested \"quotes\""
|
|
53
|
+
Parser.new('"\u005C"').parse.should == "\\"
|
|
54
|
+
Parser.new('"\u0022"').parse.should == '"'
|
|
55
|
+
Parser.new('"\u002F"').parse.should == "/"
|
|
56
|
+
Parser.new('"\u0008"').parse.should == "\b"
|
|
57
|
+
Parser.new('"\u000C"').parse.should == "\f"
|
|
58
|
+
Parser.new('"\u000A"').parse.should == "\n"
|
|
59
|
+
Parser.new('"\u000D"').parse.should == "\r"
|
|
60
|
+
Parser.new('"\u0009"').parse.should == "\t"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should parse BIG json strings" do
|
|
64
|
+
parsed = Parser.new(read_fixture_contents("so-alltags.json")).parse
|
|
65
|
+
parsed['total'].should == 29199
|
|
66
|
+
parsed['tags'].size.should == 70
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should raise an exception when trying to parse a malformed json string" do
|
|
70
|
+
lambda { Parser.new('{{{{}').parse }.should raise_exception SketchUpJSON::SyntaxError
|
|
71
|
+
lambda { Parser.new('}{}').parse }.should raise_exception SketchUpJSON::SyntaxError
|
|
72
|
+
lambda { Parser.new('}[]}').parse }.should raise_exception SketchUpJSON::SyntaxError
|
|
73
|
+
lambda { Parser.new('{[[[}').parse }.should raise_exception SketchUpJSON::SyntaxError
|
|
74
|
+
end
|
|
75
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
lib_path = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
2
|
+
$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include? lib_path
|
|
3
|
+
|
|
4
|
+
require "spec"
|
|
5
|
+
require "sketchup_json"
|
|
6
|
+
|
|
7
|
+
FIXTURES_PATH = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
|
|
8
|
+
|
|
9
|
+
def read_fixture_contents(file_name)
|
|
10
|
+
File.read(FIXTURES_PATH + "/#{file_name}")
|
|
11
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sketchup_json
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 27
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
- 0
|
|
10
|
+
version: 0.1.0
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Dalto Curvelano Junior
|
|
14
|
+
- Superficie.org
|
|
15
|
+
autorequire:
|
|
16
|
+
bindir: bin
|
|
17
|
+
cert_chain: []
|
|
18
|
+
|
|
19
|
+
date: 2010-07-30 00:00:00 -03:00
|
|
20
|
+
default_executable:
|
|
21
|
+
dependencies: []
|
|
22
|
+
|
|
23
|
+
description: A simple JSON parser/generator suited to be used in Google Sketchup
|
|
24
|
+
email:
|
|
25
|
+
executables: []
|
|
26
|
+
|
|
27
|
+
extensions: []
|
|
28
|
+
|
|
29
|
+
extra_rdoc_files: []
|
|
30
|
+
|
|
31
|
+
files:
|
|
32
|
+
- sketchup_json.rb
|
|
33
|
+
- sketchup_json.gemspec
|
|
34
|
+
- lib/sketchup_json/generator.rb
|
|
35
|
+
- lib/sketchup_json/parser.rb
|
|
36
|
+
- spec/fixtures/so-alltags.json
|
|
37
|
+
- spec/sketchup_json/generator_spec.rb
|
|
38
|
+
- spec/sketchup_json/parser_spec.rb
|
|
39
|
+
- spec/spec.opts
|
|
40
|
+
- spec/spec_helper.rb
|
|
41
|
+
has_rdoc: true
|
|
42
|
+
homepage: ""
|
|
43
|
+
licenses: []
|
|
44
|
+
|
|
45
|
+
post_install_message:
|
|
46
|
+
rdoc_options: []
|
|
47
|
+
|
|
48
|
+
require_paths:
|
|
49
|
+
- lib
|
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
51
|
+
none: false
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
hash: 3
|
|
56
|
+
segments:
|
|
57
|
+
- 0
|
|
58
|
+
version: "0"
|
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
|
+
none: false
|
|
61
|
+
requirements:
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
hash: 3
|
|
65
|
+
segments:
|
|
66
|
+
- 0
|
|
67
|
+
version: "0"
|
|
68
|
+
requirements: []
|
|
69
|
+
|
|
70
|
+
rubyforge_project:
|
|
71
|
+
rubygems_version: 1.3.7
|
|
72
|
+
signing_key:
|
|
73
|
+
specification_version: 3
|
|
74
|
+
summary: Google Sketchup's Ruby version doesn't have any standard libraries. This gem provides a simple API for parsing and generating JSON data.
|
|
75
|
+
test_files: []
|
|
76
|
+
|