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.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.hound.yml +2 -0
  4. data/.kick +17 -0
  5. data/.rubocop.yml +239 -0
  6. data/.travis.yml +11 -0
  7. data/CHANGELOG.md +200 -0
  8. data/CONTRIBUTING.md +64 -0
  9. data/Gemfile +9 -0
  10. data/LICENSE.txt +61 -0
  11. data/README.md +93 -0
  12. data/Rakefile +26 -0
  13. data/assets/report.html.erb +172 -0
  14. data/bin/xcpretty +85 -0
  15. data/features/assets/RACCommandSpec, line 80, hello xcpretty.png +0 -0
  16. data/features/assets/apple_raw.png +0 -0
  17. data/features/custom_formatter.feature +15 -0
  18. data/features/fixtures/xcodebuild.log +5963 -0
  19. data/features/html_report.feature +54 -0
  20. data/features/json_compilation_database_report.feature +21 -0
  21. data/features/junit_report.feature +44 -0
  22. data/features/knock_format.feature +11 -0
  23. data/features/simple_format.feature +204 -0
  24. data/features/steps/formatting_steps.rb +330 -0
  25. data/features/steps/html_steps.rb +32 -0
  26. data/features/steps/json_steps.rb +37 -0
  27. data/features/steps/junit_steps.rb +39 -0
  28. data/features/steps/report_steps.rb +22 -0
  29. data/features/steps/xcpretty_steps.rb +31 -0
  30. data/features/support/env.rb +117 -0
  31. data/features/tap_format.feature +31 -0
  32. data/features/test_format.feature +49 -0
  33. data/features/xcpretty.feature +14 -0
  34. data/lib/xcpretty/ansi.rb +72 -0
  35. data/lib/xcpretty/formatters/formatter.rb +177 -0
  36. data/lib/xcpretty/formatters/knock.rb +35 -0
  37. data/lib/xcpretty/formatters/rspec.rb +33 -0
  38. data/lib/xcpretty/formatters/simple.rb +200 -0
  39. data/lib/xcpretty/formatters/tap.rb +40 -0
  40. data/lib/xcpretty/parser.rb +591 -0
  41. data/lib/xcpretty/printer.rb +24 -0
  42. data/lib/xcpretty/reporters/html.rb +98 -0
  43. data/lib/xcpretty/reporters/json_compilation_database.rb +62 -0
  44. data/lib/xcpretty/reporters/junit.rb +102 -0
  45. data/lib/xcpretty/snippet.rb +38 -0
  46. data/lib/xcpretty/syntax.rb +51 -0
  47. data/lib/xcpretty/term.rb +14 -0
  48. data/lib/xcpretty/version.rb +4 -0
  49. data/lib/xcpretty.rb +37 -0
  50. data/spec/fixtures/NSStringTests.m +64 -0
  51. data/spec/fixtures/constants.rb +600 -0
  52. data/spec/fixtures/custom_formatter.rb +18 -0
  53. data/spec/fixtures/oneliner.m +1 -0
  54. data/spec/fixtures/raw_kiwi_compilation_fail.txt +24 -0
  55. data/spec/fixtures/raw_kiwi_fail.txt +1896 -0
  56. data/spec/fixtures/raw_specta_fail.txt +3110 -0
  57. data/spec/spec_helper.rb +7 -0
  58. data/spec/support/matchers/colors.rb +21 -0
  59. data/spec/xcpretty/ansi_spec.rb +47 -0
  60. data/spec/xcpretty/formatters/formatter_spec.rb +140 -0
  61. data/spec/xcpretty/formatters/rspec_spec.rb +56 -0
  62. data/spec/xcpretty/formatters/simple_spec.rb +173 -0
  63. data/spec/xcpretty/parser_spec.rb +542 -0
  64. data/spec/xcpretty/printer_spec.rb +55 -0
  65. data/spec/xcpretty/snippet_spec.rb +46 -0
  66. data/spec/xcpretty/syntax_spec.rb +39 -0
  67. data/spec/xcpretty/term_spec.rb +26 -0
  68. data/xcpretty.gemspec +37 -0
  69. 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
+
@@ -0,0 +1,14 @@
1
+
2
+ module XCPretty
3
+ module Term
4
+
5
+ def self.unicode?
6
+ Encoding.default_external == Encoding::UTF_8
7
+ end
8
+
9
+ def self.color?
10
+ STDOUT.tty?
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,4 @@
1
+ module XCPretty
2
+ VERSION = "0.1.12.bb1"
3
+ end
4
+
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