xcpretty 0.1.4 → 0.1.5

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.
@@ -0,0 +1,364 @@
1
+ require 'strscan'
2
+
3
+ module JSON
4
+
5
+ def self.parse source
6
+ Pure::Parser.new(source).parse
7
+ end
8
+
9
+ module Pure
10
+ # This class implements the JSON parser that is used to parse a JSON string
11
+ # into a Ruby data structure.
12
+ class Parser < StringScanner
13
+ STRING = /" ((?:[^\x0-\x1f"\\] |
14
+ # escaped special characters:
15
+ \\["\\\/bfnrt] |
16
+ \\u[0-9a-fA-F]{4} |
17
+ # match all but escaped special characters:
18
+ \\[\x20-\x21\x23-\x2e\x30-\x5b\x5d-\x61\x63-\x65\x67-\x6d\x6f-\x71\x73\x75-\xff])*)
19
+ "/nx
20
+ INTEGER = /(-?0|-?[1-9]\d*)/
21
+ FLOAT = /(-?
22
+ (?:0|[1-9]\d*)
23
+ (?:
24
+ \.\d+(?i:e[+-]?\d+) |
25
+ \.\d+ |
26
+ (?i:e[+-]?\d+)
27
+ )
28
+ )/x
29
+ NAN = /NaN/
30
+ INFINITY = /Infinity/
31
+ MINUS_INFINITY = /-Infinity/
32
+ OBJECT_OPEN = /\{/
33
+ OBJECT_CLOSE = /\}/
34
+ ARRAY_OPEN = /\[/
35
+ ARRAY_CLOSE = /\]/
36
+ PAIR_DELIMITER = /:/
37
+ COLLECTION_DELIMITER = /,/
38
+ TRUE = /true/
39
+ FALSE = /false/
40
+ NULL = /null/
41
+ IGNORE = %r(
42
+ (?:
43
+ //[^\n\r]*[\n\r]| # line comments
44
+ /\* # c-style comments
45
+ (?:
46
+ [^*/]| # normal chars
47
+ /[^*]| # slashes that do not start a nested comment
48
+ \*[^/]| # asterisks that do not end this comment
49
+ /(?=\*/) # single slash before this comment's end
50
+ )*
51
+ \*/ # the End of this comment
52
+ |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
53
+ )+
54
+ )mx
55
+
56
+ UNPARSED = Object.new
57
+
58
+ # Creates a new JSON::Pure::Parser instance for the string _source_.
59
+ #
60
+ # It will be configured by the _opts_ hash. _opts_ can have the following
61
+ # keys:
62
+ # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
63
+ # structures. Disable depth checking with :max_nesting => false|nil|0,
64
+ # it defaults to 100.
65
+ # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
66
+ # defiance of RFC 4627 to be parsed by the Parser. This option defaults
67
+ # to false.
68
+ # * *symbolize_names*: If set to true, returns symbols for the names
69
+ # (keys) in a JSON object. Otherwise strings are returned, which is also
70
+ # the default.
71
+ # * *create_additions*: If set to true, the Parser creates
72
+ # additions when if a matching class and create_id was found. This
73
+ # option defaults to false.
74
+ # * *object_class*: Defaults to Hash
75
+ # * *array_class*: Defaults to Array
76
+ # * *quirks_mode*: Enables quirks_mode for parser, that is for example
77
+ # parsing single JSON values instead of documents is possible.
78
+ def initialize(source, opts = {})
79
+ opts ||= {}
80
+ unless @quirks_mode = opts[:quirks_mode]
81
+ source = convert_encoding source
82
+ end
83
+ super source
84
+ if !opts.key?(:max_nesting) # defaults to 100
85
+ @max_nesting = 100
86
+ elsif opts[:max_nesting]
87
+ @max_nesting = opts[:max_nesting]
88
+ else
89
+ @max_nesting = 0
90
+ end
91
+ @allow_nan = !!opts[:allow_nan]
92
+ @symbolize_names = !!opts[:symbolize_names]
93
+ if opts.key?(:create_additions)
94
+ @create_additions = !!opts[:create_additions]
95
+ else
96
+ @create_additions = false
97
+ end
98
+ @create_id = @create_additions ? JSON.create_id : nil
99
+ @object_class = opts[:object_class] || Hash
100
+ @array_class = opts[:array_class] || Array
101
+ @match_string = opts[:match_string]
102
+ end
103
+
104
+ alias source string
105
+
106
+ def quirks_mode?
107
+ !!@quirks_mode
108
+ end
109
+
110
+ def reset
111
+ super
112
+ @current_nesting = 0
113
+ end
114
+
115
+ # Parses the current JSON string _source_ and returns the complete data
116
+ # structure as a result.
117
+ def parse
118
+ reset
119
+ obj = nil
120
+ if @quirks_mode
121
+ while !eos? && skip(IGNORE)
122
+ end
123
+ if eos?
124
+ raise ParserError, "source did not contain any JSON!"
125
+ else
126
+ obj = parse_value
127
+ obj == UNPARSED and raise ParserError, "source did not contain any JSON!"
128
+ end
129
+ else
130
+ until eos?
131
+ case
132
+ when scan(OBJECT_OPEN)
133
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
134
+ @current_nesting = 1
135
+ obj = parse_object
136
+ when scan(ARRAY_OPEN)
137
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
138
+ @current_nesting = 1
139
+ obj = parse_array
140
+ when skip(IGNORE)
141
+ ;
142
+ else
143
+ raise ParserError, "source '#{peek(20)}' not in JSON!"
144
+ end
145
+ end
146
+ obj or raise ParserError, "source did not contain any JSON!"
147
+ end
148
+ obj
149
+ end
150
+
151
+ private
152
+
153
+ def convert_encoding(source)
154
+ if source.respond_to?(:to_str)
155
+ source = source.to_str
156
+ else
157
+ raise TypeError, "#{source.inspect} is not like a string"
158
+ end
159
+ if defined?(::Encoding)
160
+ if source.encoding == ::Encoding::ASCII_8BIT
161
+ b = source[0, 4].bytes.to_a
162
+ source =
163
+ case
164
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
165
+ source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
166
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
167
+ source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
168
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
169
+ source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
170
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
171
+ source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
172
+ else
173
+ source.dup
174
+ end
175
+ else
176
+ source = source.encode(::Encoding::UTF_8)
177
+ end
178
+ source.force_encoding(::Encoding::ASCII_8BIT)
179
+ else
180
+ b = source
181
+ source =
182
+ case
183
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
184
+ JSON.iconv('utf-8', 'utf-32be', b)
185
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
186
+ JSON.iconv('utf-8', 'utf-16be', b)
187
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
188
+ JSON.iconv('utf-8', 'utf-32le', b)
189
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
190
+ JSON.iconv('utf-8', 'utf-16le', b)
191
+ else
192
+ b
193
+ end
194
+ end
195
+ source
196
+ end
197
+
198
+ # Unescape characters in strings.
199
+ UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
200
+ UNESCAPE_MAP.update({
201
+ ?" => '"',
202
+ ?\\ => '\\',
203
+ ?/ => '/',
204
+ ?b => "\b",
205
+ ?f => "\f",
206
+ ?n => "\n",
207
+ ?r => "\r",
208
+ ?t => "\t",
209
+ ?u => nil,
210
+ })
211
+
212
+ EMPTY_8BIT_STRING = ''
213
+ if ::String.method_defined?(:encode)
214
+ EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
215
+ end
216
+
217
+ def parse_string
218
+ if scan(STRING)
219
+ return '' if self[1].empty?
220
+ string = self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
221
+ if u = UNESCAPE_MAP[$&[1]]
222
+ u
223
+ else # \uXXXX
224
+ bytes = EMPTY_8BIT_STRING.dup
225
+ i = 0
226
+ while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
227
+ bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
228
+ i += 1
229
+ end
230
+ JSON.iconv('utf-8', 'utf-16be', bytes)
231
+ end
232
+ end
233
+ if string.respond_to?(:force_encoding)
234
+ string.force_encoding(::Encoding::UTF_8)
235
+ end
236
+ if @create_additions and @match_string
237
+ for (regexp, klass) in @match_string
238
+ klass.json_creatable? or next
239
+ string =~ regexp and return klass.json_create(string)
240
+ end
241
+ end
242
+ string
243
+ else
244
+ UNPARSED
245
+ end
246
+ rescue => e
247
+ raise ParserError, "Caught #{e.class} at '#{peek(20)}': #{e}"
248
+ end
249
+
250
+ def parse_value
251
+ case
252
+ when scan(FLOAT)
253
+ Float(self[1])
254
+ when scan(INTEGER)
255
+ Integer(self[1])
256
+ when scan(TRUE)
257
+ true
258
+ when scan(FALSE)
259
+ false
260
+ when scan(NULL)
261
+ nil
262
+ when (string = parse_string) != UNPARSED
263
+ string
264
+ when scan(ARRAY_OPEN)
265
+ @current_nesting += 1
266
+ ary = parse_array
267
+ @current_nesting -= 1
268
+ ary
269
+ when scan(OBJECT_OPEN)
270
+ @current_nesting += 1
271
+ obj = parse_object
272
+ @current_nesting -= 1
273
+ obj
274
+ when @allow_nan && scan(NAN)
275
+ NaN
276
+ when @allow_nan && scan(INFINITY)
277
+ Infinity
278
+ when @allow_nan && scan(MINUS_INFINITY)
279
+ MinusInfinity
280
+ else
281
+ UNPARSED
282
+ end
283
+ end
284
+
285
+ def parse_array
286
+ raise NestingError, "nesting of #@current_nesting is too deep" if
287
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
288
+ result = @array_class.new
289
+ delim = false
290
+ until eos?
291
+ case
292
+ when (value = parse_value) != UNPARSED
293
+ delim = false
294
+ result << value
295
+ skip(IGNORE)
296
+ if scan(COLLECTION_DELIMITER)
297
+ delim = true
298
+ elsif match?(ARRAY_CLOSE)
299
+ ;
300
+ else
301
+ raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
302
+ end
303
+ when scan(ARRAY_CLOSE)
304
+ if delim
305
+ raise ParserError, "expected next element in array at '#{peek(20)}'!"
306
+ end
307
+ break
308
+ when skip(IGNORE)
309
+ ;
310
+ else
311
+ raise ParserError, "unexpected token in array at '#{peek(20)}'!"
312
+ end
313
+ end
314
+ result
315
+ end
316
+
317
+ def parse_object
318
+ raise NestingError, "nesting of #@current_nesting is too deep" if
319
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
320
+ result = @object_class.new
321
+ delim = false
322
+ until eos?
323
+ case
324
+ when (string = parse_string) != UNPARSED
325
+ skip(IGNORE)
326
+ unless scan(PAIR_DELIMITER)
327
+ raise ParserError, "expected ':' in object at '#{peek(20)}'!"
328
+ end
329
+ skip(IGNORE)
330
+ unless (value = parse_value).equal? UNPARSED
331
+ result[@symbolize_names ? string.to_sym : string] = value
332
+ delim = false
333
+ skip(IGNORE)
334
+ if scan(COLLECTION_DELIMITER)
335
+ delim = true
336
+ elsif match?(OBJECT_CLOSE)
337
+ ;
338
+ else
339
+ raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
340
+ end
341
+ else
342
+ raise ParserError, "expected value in object at '#{peek(20)}'!"
343
+ end
344
+ when scan(OBJECT_CLOSE)
345
+ if delim
346
+ raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
347
+ end
348
+ if @create_additions and klassname = result[@create_id]
349
+ klass = JSON.deep_const_get klassname
350
+ break unless klass and klass.json_creatable?
351
+ result = klass.json_create(result)
352
+ end
353
+ break
354
+ when skip(IGNORE)
355
+ ;
356
+ else
357
+ raise ParserError, "unexpected token in object at '#{peek(20)}'!"
358
+ end
359
+ end
360
+ result
361
+ end
362
+ end
363
+ end
364
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcpretty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marin Usalj
@@ -9,62 +9,62 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-23 00:00:00.000000000 Z
12
+ date: 2014-04-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ~>
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
20
  version: '1.3'
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ~>
25
+ - - "~>"
26
26
  - !ruby/object:Gem::Version
27
27
  version: '1.3'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - '>='
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '0'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - '>='
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rspec
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - '>='
46
+ - - ">="
47
47
  - !ruby/object:Gem::Version
48
48
  version: '0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - '>='
53
+ - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: cucumber
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - '>='
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - '>='
67
+ - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  description: "\n Xcodebuild formatter designed to be piped with `xcodebuild`,\n and
@@ -78,9 +78,9 @@ executables:
78
78
  extensions: []
79
79
  extra_rdoc_files: []
80
80
  files:
81
- - .gitignore
82
- - .kick
83
- - .travis.yml
81
+ - ".gitignore"
82
+ - ".kick"
83
+ - ".travis.yml"
84
84
  - CHANGELOG.md
85
85
  - CONTRIBUTING.md
86
86
  - Gemfile
@@ -92,11 +92,13 @@ files:
92
92
  - features/custom_formatter.feature
93
93
  - features/fixtures/xcodebuild.log
94
94
  - features/html_report.feature
95
+ - features/json_compilation_database_report.feature
95
96
  - features/junit_report.feature
96
97
  - features/knock_format.feature
97
98
  - features/simple_format.feature
98
99
  - features/steps/formatting_steps.rb
99
100
  - features/steps/html_steps.rb
101
+ - features/steps/json_steps.rb
100
102
  - features/steps/junit_steps.rb
101
103
  - features/steps/report_steps.rb
102
104
  - features/steps/xcpretty_steps.rb
@@ -114,6 +116,7 @@ files:
114
116
  - lib/xcpretty/parser.rb
115
117
  - lib/xcpretty/printer.rb
116
118
  - lib/xcpretty/reporters/html.rb
119
+ - lib/xcpretty/reporters/json_compilation_database.rb
117
120
  - lib/xcpretty/reporters/junit.rb
118
121
  - lib/xcpretty/syntax.rb
119
122
  - lib/xcpretty/version.rb
@@ -131,6 +134,10 @@ files:
131
134
  - spec/xcpretty/parser_spec.rb
132
135
  - spec/xcpretty/printer_spec.rb
133
136
  - spec/xcpretty/syntax_spec.rb
137
+ - vendor/json_pure/COPYING
138
+ - vendor/json_pure/LICENSE
139
+ - vendor/json_pure/generator.rb
140
+ - vendor/json_pure/parser.rb
134
141
  - xcpretty.gemspec
135
142
  homepage: https://github.com/mneorr/xcpretty
136
143
  licenses:
@@ -142,17 +149,17 @@ require_paths:
142
149
  - lib
143
150
  required_ruby_version: !ruby/object:Gem::Requirement
144
151
  requirements:
145
- - - '>='
152
+ - - ">="
146
153
  - !ruby/object:Gem::Version
147
154
  version: 1.8.7
148
155
  required_rubygems_version: !ruby/object:Gem::Requirement
149
156
  requirements:
150
- - - '>='
157
+ - - ">="
151
158
  - !ruby/object:Gem::Version
152
159
  version: '0'
153
160
  requirements: []
154
161
  rubyforge_project:
155
- rubygems_version: 2.0.3
162
+ rubygems_version: 2.2.0
156
163
  signing_key:
157
164
  specification_version: 4
158
165
  summary: xcodebuild formatter done right
@@ -160,11 +167,13 @@ test_files:
160
167
  - features/custom_formatter.feature
161
168
  - features/fixtures/xcodebuild.log
162
169
  - features/html_report.feature
170
+ - features/json_compilation_database_report.feature
163
171
  - features/junit_report.feature
164
172
  - features/knock_format.feature
165
173
  - features/simple_format.feature
166
174
  - features/steps/formatting_steps.rb
167
175
  - features/steps/html_steps.rb
176
+ - features/steps/json_steps.rb
168
177
  - features/steps/junit_steps.rb
169
178
  - features/steps/report_steps.rb
170
179
  - features/steps/xcpretty_steps.rb