xcpretty 0.1.12 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +2 -10
  3. data/.rubocop.yml +239 -0
  4. data/.travis.yml +1 -8
  5. data/CHANGELOG.md +35 -0
  6. data/Gemfile +1 -0
  7. data/README.md +23 -76
  8. data/Rakefile +10 -8
  9. data/bin/xcpretty +14 -14
  10. data/features/simple_format.feature +39 -17
  11. data/features/steps/formatting_steps.rb +33 -4
  12. data/features/steps/html_steps.rb +1 -0
  13. data/features/steps/json_steps.rb +2 -1
  14. data/features/steps/junit_steps.rb +4 -3
  15. data/features/steps/report_steps.rb +1 -0
  16. data/features/support/env.rb +4 -3
  17. data/features/test_format.feature +4 -4
  18. data/lib/xcpretty/ansi.rb +14 -13
  19. data/lib/xcpretty/formatters/formatter.rb +24 -8
  20. data/lib/xcpretty/formatters/knock.rb +2 -1
  21. data/lib/xcpretty/formatters/rspec.rb +1 -0
  22. data/lib/xcpretty/formatters/simple.rb +18 -3
  23. data/lib/xcpretty/formatters/tap.rb +3 -2
  24. data/lib/xcpretty/parser.rb +38 -15
  25. data/lib/xcpretty/printer.rb +1 -0
  26. data/lib/xcpretty/reporters/html.rb +7 -5
  27. data/lib/xcpretty/reporters/json_compilation_database.rb +6 -10
  28. data/lib/xcpretty/reporters/junit.rb +6 -3
  29. data/lib/xcpretty/snippet.rb +0 -2
  30. data/lib/xcpretty/syntax.rb +38 -31
  31. data/lib/xcpretty/term.rb +14 -0
  32. data/lib/xcpretty/version.rb +2 -1
  33. data/lib/xcpretty.rb +5 -6
  34. data/spec/fixtures/constants.rb +15 -2
  35. data/spec/fixtures/custom_formatter.rb +2 -1
  36. data/spec/spec_helper.rb +2 -1
  37. data/spec/support/matchers/colors.rb +1 -0
  38. data/spec/xcpretty/ansi_spec.rb +1 -0
  39. data/spec/xcpretty/formatters/formatter_spec.rb +27 -16
  40. data/spec/xcpretty/formatters/rspec_spec.rb +1 -0
  41. data/spec/xcpretty/formatters/simple_spec.rb +22 -3
  42. data/spec/xcpretty/parser_spec.rb +39 -10
  43. data/spec/xcpretty/printer_spec.rb +15 -13
  44. data/spec/xcpretty/syntax_spec.rb +24 -48
  45. data/spec/xcpretty/term_spec.rb +26 -0
  46. data/xcpretty.gemspec +15 -11
  47. metadata +42 -14
  48. data/vendor/json_pure/COPYING +0 -57
  49. data/vendor/json_pure/LICENSE +0 -340
  50. data/vendor/json_pure/generator.rb +0 -443
  51. data/vendor/json_pure/parser.rb +0 -364
@@ -1,364 +0,0 @@
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