xcpretty-bb 0.1.12.bb1
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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.hound.yml +2 -0
- data/.kick +17 -0
- data/.rubocop.yml +239 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +200 -0
- data/CONTRIBUTING.md +64 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +61 -0
- data/README.md +93 -0
- data/Rakefile +26 -0
- data/assets/report.html.erb +172 -0
- data/bin/xcpretty +85 -0
- data/features/assets/RACCommandSpec, line 80, hello xcpretty.png +0 -0
- data/features/assets/apple_raw.png +0 -0
- data/features/custom_formatter.feature +15 -0
- data/features/fixtures/xcodebuild.log +5963 -0
- data/features/html_report.feature +54 -0
- data/features/json_compilation_database_report.feature +21 -0
- data/features/junit_report.feature +44 -0
- data/features/knock_format.feature +11 -0
- data/features/simple_format.feature +204 -0
- data/features/steps/formatting_steps.rb +330 -0
- data/features/steps/html_steps.rb +32 -0
- data/features/steps/json_steps.rb +37 -0
- data/features/steps/junit_steps.rb +39 -0
- data/features/steps/report_steps.rb +22 -0
- data/features/steps/xcpretty_steps.rb +31 -0
- data/features/support/env.rb +117 -0
- data/features/tap_format.feature +31 -0
- data/features/test_format.feature +49 -0
- data/features/xcpretty.feature +14 -0
- data/lib/xcpretty/ansi.rb +72 -0
- data/lib/xcpretty/formatters/formatter.rb +177 -0
- data/lib/xcpretty/formatters/knock.rb +35 -0
- data/lib/xcpretty/formatters/rspec.rb +33 -0
- data/lib/xcpretty/formatters/simple.rb +200 -0
- data/lib/xcpretty/formatters/tap.rb +40 -0
- data/lib/xcpretty/parser.rb +591 -0
- data/lib/xcpretty/printer.rb +24 -0
- data/lib/xcpretty/reporters/html.rb +98 -0
- data/lib/xcpretty/reporters/json_compilation_database.rb +62 -0
- data/lib/xcpretty/reporters/junit.rb +102 -0
- data/lib/xcpretty/snippet.rb +38 -0
- data/lib/xcpretty/syntax.rb +51 -0
- data/lib/xcpretty/term.rb +14 -0
- data/lib/xcpretty/version.rb +4 -0
- data/lib/xcpretty.rb +37 -0
- data/spec/fixtures/NSStringTests.m +64 -0
- data/spec/fixtures/constants.rb +600 -0
- data/spec/fixtures/custom_formatter.rb +18 -0
- data/spec/fixtures/oneliner.m +1 -0
- data/spec/fixtures/raw_kiwi_compilation_fail.txt +24 -0
- data/spec/fixtures/raw_kiwi_fail.txt +1896 -0
- data/spec/fixtures/raw_specta_fail.txt +3110 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/matchers/colors.rb +21 -0
- data/spec/xcpretty/ansi_spec.rb +47 -0
- data/spec/xcpretty/formatters/formatter_spec.rb +140 -0
- data/spec/xcpretty/formatters/rspec_spec.rb +56 -0
- data/spec/xcpretty/formatters/simple_spec.rb +173 -0
- data/spec/xcpretty/parser_spec.rb +542 -0
- data/spec/xcpretty/printer_spec.rb +55 -0
- data/spec/xcpretty/snippet_spec.rb +46 -0
- data/spec/xcpretty/syntax_spec.rb +39 -0
- data/spec/xcpretty/term_spec.rb +26 -0
- data/xcpretty.gemspec +37 -0
- metadata +237 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module XCPretty
|
|
2
|
+
class JSONCompilationDatabase
|
|
3
|
+
|
|
4
|
+
include XCPretty::FormatMethods
|
|
5
|
+
FILE_PATH = 'build/reports/compilation_db.json'
|
|
6
|
+
|
|
7
|
+
def load_dependencies
|
|
8
|
+
unless @@loaded ||= false
|
|
9
|
+
require 'fileutils'
|
|
10
|
+
require 'pathname'
|
|
11
|
+
require 'json'
|
|
12
|
+
@@loaded = true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize(options)
|
|
17
|
+
load_dependencies
|
|
18
|
+
@file_path = options[:path] || FILE_PATH
|
|
19
|
+
@parser = Parser.new(self)
|
|
20
|
+
@compilation_units = []
|
|
21
|
+
@pch_path = nil
|
|
22
|
+
@current_file = nil
|
|
23
|
+
@current_path = nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def handle(line)
|
|
27
|
+
@parser.parse(line)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def format_process_pch_command(file_path)
|
|
31
|
+
@pch_path = file_path
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def format_compile(file_name, file_path)
|
|
35
|
+
@current_file = file_name
|
|
36
|
+
@current_path = file_path
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def format_compile_command(compiler_command, file_path)
|
|
40
|
+
directory = file_path.gsub("#{@current_path}", '').gsub(/\/$/, '')
|
|
41
|
+
directory = '/' if directory.empty?
|
|
42
|
+
cmd = compiler_command.gsub(/(\-include)\s.*\.pch/, "\\1 #{@pch_path}")
|
|
43
|
+
@compilation_units << {command: cmd,
|
|
44
|
+
file: @current_path,
|
|
45
|
+
directory: directory}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def finish
|
|
49
|
+
FileUtils.mkdir_p(File.dirname(@file_path))
|
|
50
|
+
write_report
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def write_report
|
|
56
|
+
File.open(@file_path, 'w') do |f|
|
|
57
|
+
f.write(@compilation_units.to_json)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
module XCPretty
|
|
2
|
+
class JUnit
|
|
3
|
+
|
|
4
|
+
include XCPretty::FormatMethods
|
|
5
|
+
FILEPATH = 'build/reports/junit.xml'
|
|
6
|
+
|
|
7
|
+
def load_dependencies
|
|
8
|
+
unless @@loaded ||= false
|
|
9
|
+
require 'fileutils'
|
|
10
|
+
require 'pathname'
|
|
11
|
+
require 'rexml/document'
|
|
12
|
+
require 'rexml/formatters/pretty'
|
|
13
|
+
@@loaded = true
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize(options)
|
|
18
|
+
load_dependencies
|
|
19
|
+
@filepath = options[:path] || FILEPATH
|
|
20
|
+
@directory = `pwd`.strip
|
|
21
|
+
@document = REXML::Document.new
|
|
22
|
+
@document << REXML::XMLDecl.new('1.0', 'UTF-8')
|
|
23
|
+
@document.add_element('testsuites')
|
|
24
|
+
@parser = Parser.new(self)
|
|
25
|
+
@total_tests = 0
|
|
26
|
+
@total_fails = 0
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def handle(line)
|
|
30
|
+
@parser.parse(line)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def format_passing_test(classname, test_case, time)
|
|
34
|
+
test_node = suite(classname).add_element('testcase')
|
|
35
|
+
test_node.attributes['classname'] = classname
|
|
36
|
+
test_node.attributes['name'] = test_case
|
|
37
|
+
test_node.attributes['time'] = time
|
|
38
|
+
@test_count += 1
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def format_pending_test(classname, test_case)
|
|
42
|
+
test_node = suite(classname).add_element('testcase')
|
|
43
|
+
test_node.attributes['classname'] = classname
|
|
44
|
+
test_node.attributes['name'] = test_case
|
|
45
|
+
test_node.add_element('skipped')
|
|
46
|
+
@test_count += 1
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def format_failing_test(classname, test_case, reason, file)
|
|
50
|
+
test_node = suite(classname).add_element('testcase')
|
|
51
|
+
test_node.attributes['classname'] = classname
|
|
52
|
+
test_node.attributes['name'] = test_case
|
|
53
|
+
fail_node = test_node.add_element('failure')
|
|
54
|
+
fail_node.attributes['message'] = reason
|
|
55
|
+
fail_node.text = file.sub(@directory + '/', '')
|
|
56
|
+
@test_count += 1
|
|
57
|
+
@fail_count += 1
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def finish
|
|
61
|
+
set_test_counters
|
|
62
|
+
@document.root.attributes['tests'] = @total_tests
|
|
63
|
+
@document.root.attributes['failures'] = @total_fails
|
|
64
|
+
write_report_file
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def write_report_file
|
|
70
|
+
FileUtils.mkdir_p(File.dirname(@filepath))
|
|
71
|
+
formatter = REXML::Formatters::Pretty.new(2)
|
|
72
|
+
formatter.compact = true
|
|
73
|
+
output_file = File.open(@filepath, 'w+')
|
|
74
|
+
result = formatter.write(@document, output_file)
|
|
75
|
+
output_file.close
|
|
76
|
+
result
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def suite(classname)
|
|
80
|
+
if @last_suite && @last_suite.attributes['name'] == classname
|
|
81
|
+
return @last_suite
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
set_test_counters
|
|
85
|
+
@last_suite = @document.root.add_element('testsuite')
|
|
86
|
+
@last_suite.attributes['name'] = classname
|
|
87
|
+
@last_suite
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def set_test_counters
|
|
91
|
+
if @last_suite
|
|
92
|
+
@last_suite.attributes['tests'] = @test_count
|
|
93
|
+
@last_suite.attributes['failures'] = @fail_count
|
|
94
|
+
end
|
|
95
|
+
@total_fails += @fail_count || 0
|
|
96
|
+
@total_tests += @test_count || 0
|
|
97
|
+
@test_count = 0
|
|
98
|
+
@fail_count = 0
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module XCPretty
|
|
2
|
+
class Snippet
|
|
3
|
+
attr_reader :contents, :file_path
|
|
4
|
+
|
|
5
|
+
def initialize(contents = '', file_path = '')
|
|
6
|
+
@contents = contents
|
|
7
|
+
@file_path = file_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.from_filepath(filepath)
|
|
11
|
+
path, line = filepath.split(':')
|
|
12
|
+
file = File.open(path)
|
|
13
|
+
|
|
14
|
+
text = read_snippet(file, line)
|
|
15
|
+
|
|
16
|
+
file.close
|
|
17
|
+
new(text, filepath)
|
|
18
|
+
rescue
|
|
19
|
+
new('', filepath)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def self.read_snippet(file, around_line)
|
|
24
|
+
text = ''
|
|
25
|
+
starting_position = around_line.to_i - 2
|
|
26
|
+
starting_position.times { file.gets }
|
|
27
|
+
3.times { text += readline(file) }
|
|
28
|
+
text
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.readline(file)
|
|
32
|
+
file.gets
|
|
33
|
+
$_ || ''
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'rouge'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
# rubocop:disable Style/ConstantName
|
|
5
|
+
Rouge = nil
|
|
6
|
+
# rubocop:enable Style/ConstantName
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'xcpretty/snippet'
|
|
10
|
+
|
|
11
|
+
module XCPretty
|
|
12
|
+
module Syntax
|
|
13
|
+
def self.highlight(snippet)
|
|
14
|
+
return snippet.contents unless Rouge
|
|
15
|
+
|
|
16
|
+
if snippet.file_path.include?(':')
|
|
17
|
+
filename = snippet.file_path.rpartition(':').first
|
|
18
|
+
else
|
|
19
|
+
filename = snippet.file_path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
lexer = find_lexer(filename, snippet.contents)
|
|
23
|
+
if lexer
|
|
24
|
+
formatter = Rouge::Formatters::Terminal256.new
|
|
25
|
+
formatter.format(lexer.lex(snippet.contents))
|
|
26
|
+
else
|
|
27
|
+
snippet.contents
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param [String] filename The filename
|
|
32
|
+
# @param [String] contents The contents of the file
|
|
33
|
+
# @return [Rouge::Lexer]
|
|
34
|
+
def self.find_lexer(filename, contents)
|
|
35
|
+
case File.extname(filename)
|
|
36
|
+
when '.cpp', '.cc', '.c++', '.cxx', '.hpp', '.h++', '.hxx'
|
|
37
|
+
Rouge::Lexers::Cpp
|
|
38
|
+
when '.m', '.h' then Rouge::Lexers::ObjectiveC
|
|
39
|
+
when '.swift' then Rouge::Lexers::Swift
|
|
40
|
+
when '.ruby', '.rb' then Rouge::Lexers::Ruby
|
|
41
|
+
else
|
|
42
|
+
options = {
|
|
43
|
+
filename: File.basename(filename),
|
|
44
|
+
source: contents
|
|
45
|
+
}
|
|
46
|
+
Rouge::Lexer.guesses(options).first
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
data/lib/xcpretty.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'xcpretty/version'
|
|
2
|
+
require 'xcpretty/printer'
|
|
3
|
+
require 'xcpretty/syntax'
|
|
4
|
+
require 'xcpretty/snippet'
|
|
5
|
+
require 'xcpretty/term'
|
|
6
|
+
require 'xcpretty/formatters/formatter'
|
|
7
|
+
require 'xcpretty/formatters/simple'
|
|
8
|
+
require 'xcpretty/formatters/rspec'
|
|
9
|
+
require 'xcpretty/formatters/knock'
|
|
10
|
+
require 'xcpretty/formatters/tap'
|
|
11
|
+
require 'xcpretty/reporters/junit'
|
|
12
|
+
require 'xcpretty/reporters/html'
|
|
13
|
+
require 'xcpretty/reporters/json_compilation_database'
|
|
14
|
+
|
|
15
|
+
module XCPretty
|
|
16
|
+
|
|
17
|
+
def self.class_from_path(path)
|
|
18
|
+
source = File.read(path)
|
|
19
|
+
klass = eval(source, nil, path)
|
|
20
|
+
raise unless klass.is_a?(Class)
|
|
21
|
+
klass
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.load_custom_formatter(path)
|
|
25
|
+
$LOAD_PATH.unshift File.dirname(path)
|
|
26
|
+
class_from_path(path)
|
|
27
|
+
rescue SyntaxError => e
|
|
28
|
+
exit_with_error("Expected formatter source file to return a class. #{e}")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.exit_with_error(message)
|
|
32
|
+
$stderr.puts "[!] #{message}"
|
|
33
|
+
exit 1
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
//
|
|
2
|
+
// NSStringTests.m
|
|
3
|
+
// SampleProject
|
|
4
|
+
//
|
|
5
|
+
// Created by Neil on 05/12/2012.
|
|
6
|
+
// Copyright (c) 2012 @supermarin | supermar.in | All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import "Kiwi.h"
|
|
10
|
+
#import "ObjectiveSugar.h"
|
|
11
|
+
|
|
12
|
+
SPEC_BEGIN(StringAdditions)
|
|
13
|
+
|
|
14
|
+
describe(@"Foundation-style functions", ^{
|
|
15
|
+
|
|
16
|
+
it(@"NSStringWithFormat makes NSString -stringWithFormat", ^{
|
|
17
|
+
|
|
18
|
+
[[NSStringWithFormat(@"This is %@", @1) should] equal:@"This is 1"];
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe(@"Additions", ^{
|
|
24
|
+
|
|
25
|
+
NSString *sentence = @"Jane Doe's going in a shop,and,yeah;";
|
|
26
|
+
|
|
27
|
+
it(@"-split splits by whitespace", ^{
|
|
28
|
+
[[[@" the\r\nquick brown\t \tfox\n" split] should] equal:@[@"the", @"quick", @"brown", @"fox"]];
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it(@"-split: splits with given delimiter", ^{
|
|
32
|
+
[[[sentence split:@","] should] equal:@[@"Jane Doe's going in a shop", @"and", @"yeah;"]];
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it(@"-split: splits with delimiter string, not just a char", ^{
|
|
36
|
+
[[[@"one / two / three" split:@" / "] should] equal:@[@"one", @"two", @"three"]];
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it(@"contains string", ^{
|
|
40
|
+
[[@([sentence containsString:@"jane doe"]) should] beTrue];
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
context(@"CamelCase and snake_case", ^{
|
|
44
|
+
|
|
45
|
+
it(@"converts snake_cased to CamelCased", ^{
|
|
46
|
+
[[[@"snake_case" camelCase] should] equal:@"SnakeCase"];
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it(@"handles correctly snake case on beginning and at the end", ^{
|
|
50
|
+
[[[@"_snake_case" camelCase] should] equal:@"SnakeCase"];
|
|
51
|
+
[[[@"snake_case_" camelCase] should] equal:@"SnakeCase"];
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it(@"-strip strips whitespaces and newlines from both ends", ^{
|
|
57
|
+
[[[@" Look mo, no empties! " strip] should] equal:@"Look mo, no empties!"];
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
SPEC_END
|