ashtonw-slather 1.8.2

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 (74) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +45 -0
  4. data/.travis.yml +19 -0
  5. data/CHANGELOG.md +132 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +206 -0
  9. data/Rakefile +1 -0
  10. data/assets/highlight.pack.js +1 -0
  11. data/assets/list.min.js +1 -0
  12. data/assets/slather.css +316 -0
  13. data/bin/slather +117 -0
  14. data/docs/logo.jpg +0 -0
  15. data/lib/cocoapods_plugin.rb +10 -0
  16. data/lib/slather.rb +20 -0
  17. data/lib/slather/coverage_file.rb +195 -0
  18. data/lib/slather/coverage_service/cobertura_xml_output.rb +183 -0
  19. data/lib/slather/coverage_service/coveralls.rb +186 -0
  20. data/lib/slather/coverage_service/gutter_json_output.rb +50 -0
  21. data/lib/slather/coverage_service/hardcover.rb +61 -0
  22. data/lib/slather/coverage_service/html_output.rb +244 -0
  23. data/lib/slather/coverage_service/simple_output.rb +31 -0
  24. data/lib/slather/coveralls_coverage_file.rb +13 -0
  25. data/lib/slather/project.rb +132 -0
  26. data/lib/slather/version.rb +3 -0
  27. data/slather.gemspec +32 -0
  28. data/spec/fixtures/fixtures.xcodeproj/project.pbxproj +496 -0
  29. data/spec/fixtures/fixtures.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  30. data/spec/fixtures/fixtures.xcodeproj/xcshareddata/xcschemes/fixtures.xcscheme +69 -0
  31. data/spec/fixtures/fixtures/Supporting Files/fixtures-Prefix.pch +9 -0
  32. data/spec/fixtures/fixtures/fixtures.h +16 -0
  33. data/spec/fixtures/fixtures/fixtures.m +23 -0
  34. data/spec/fixtures/fixtures/fixtures_cpp.cpp +9 -0
  35. data/spec/fixtures/fixtures/fixtures_cpp.h +6 -0
  36. data/spec/fixtures/fixtures/fixtures_m.h +5 -0
  37. data/spec/fixtures/fixtures/fixtures_m.m +5 -0
  38. data/spec/fixtures/fixtures/fixtures_mm.h +5 -0
  39. data/spec/fixtures/fixtures/fixtures_mm.mm +5 -0
  40. data/spec/fixtures/fixtures/more_files/Branches.h +15 -0
  41. data/spec/fixtures/fixtures/more_files/Branches.m +45 -0
  42. data/spec/fixtures/fixtures/more_files/Empty.h +13 -0
  43. data/spec/fixtures/fixtures/more_files/Empty.m +13 -0
  44. data/spec/fixtures/fixtures/more_files/peekaview.h +13 -0
  45. data/spec/fixtures/fixtures/more_files/peekaview.m +31 -0
  46. data/spec/fixtures/fixturesTests/BranchesTests.m +38 -0
  47. data/spec/fixtures/fixturesTests/Supporting Files/en.lproj/InfoPlist.strings +2 -0
  48. data/spec/fixtures/fixturesTests/Supporting Files/fixturesTests-Info.plist +22 -0
  49. data/spec/fixtures/fixturesTests/fixturesTests.m +36 -0
  50. data/spec/fixtures/fixturesTests/peekaviewTests.m +34 -0
  51. data/spec/fixtures/fixtures_html/Branches.m.html +261 -0
  52. data/spec/fixtures/fixtures_html/BranchesTests.m.html +228 -0
  53. data/spec/fixtures/fixtures_html/Empty.m.html +30 -0
  54. data/spec/fixtures/fixtures_html/fixtures.m.html +151 -0
  55. data/spec/fixtures/fixtures_html/fixturesTests.m.html +216 -0
  56. data/spec/fixtures/fixtures_html/fixtures_cpp.cpp.html +30 -0
  57. data/spec/fixtures/fixtures_html/fixtures_m.m.html +30 -0
  58. data/spec/fixtures/fixtures_html/fixtures_mm.mm.html +30 -0
  59. data/spec/fixtures/fixtures_html/index.html +134 -0
  60. data/spec/fixtures/fixtures_html/peekaview.m.html +190 -0
  61. data/spec/fixtures/fixtures_html/peekaviewTests.m.html +206 -0
  62. data/spec/fixtures/gutter.json +1 -0
  63. data/spec/slather/cocoapods_plugin_spec.rb +21 -0
  64. data/spec/slather/coverage_file_spec.rb +337 -0
  65. data/spec/slather/coverage_service/cobertura_xml_spec.rb +49 -0
  66. data/spec/slather/coverage_service/coveralls_spec.rb +122 -0
  67. data/spec/slather/coverage_service/gutter_json_spec.rb +28 -0
  68. data/spec/slather/coverage_service/hardcover_spec.rb +87 -0
  69. data/spec/slather/coverage_service/html_output_spec.rb +179 -0
  70. data/spec/slather/coverage_service/simple_output_spec.rb +35 -0
  71. data/spec/slather/fixtures.gcno +0 -0
  72. data/spec/slather/project_spec.rb +288 -0
  73. data/spec/spec_helper.rb +27 -0
  74. metadata +319 -0
@@ -0,0 +1 @@
1
+ {"meta":{"timestamp":"2014-10-12 15:21:21.865519"},"symbols_by_file":{"spec/fixtures/fixtures/more_files/Branches.m":[{"line":1,"long_text":"","short_text":"-"},{"line":2,"long_text":"","short_text":"-"},{"line":3,"long_text":"","short_text":"-"},{"line":4,"long_text":"","short_text":"-"},{"line":5,"long_text":"","short_text":"-"},{"line":6,"long_text":"","short_text":"-"},{"line":7,"long_text":"","short_text":"-"},{"line":8,"long_text":"","short_text":"-"},{"line":9,"long_text":"","short_text":"-"},{"line":10,"long_text":"","short_text":"-"},{"line":11,"long_text":"","short_text":"-"},{"line":12,"long_text":"","short_text":"-"},{"line":13,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":14,"long_text":"","short_text":"-"},{"line":15,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":16,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":17,"long_text":"","short_text":"-"},{"line":18,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":19,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":20,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":21,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":22,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":23,"long_text":"","short_text":"-"},{"line":24,"long_text":"","short_text":"-"},{"line":25,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":26,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":27,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":28,"long_text":"","short_text":"-"},{"line":29,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":30,"long_text":"","short_text":"-"},{"line":31,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":32,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":33,"long_text":"","short_text":"-"},{"line":34,"long_text":"","short_text":"-"},{"line":35,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":36,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":37,"long_text":"","short_text":"-"},{"line":38,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":39,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":40,"long_text":"","short_text":"-"},{"line":41,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":42,"long_text":"","short_text":"-"},{"line":43,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":44,"long_text":"","short_text":"-"},{"line":45,"long_text":"","short_text":"-"}],"spec/fixtures/fixtures/fixtures.m":[{"line":1,"long_text":"","short_text":"-"},{"line":2,"long_text":"","short_text":"-"},{"line":3,"long_text":"","short_text":"-"},{"line":4,"long_text":"","short_text":"-"},{"line":5,"long_text":"","short_text":"-"},{"line":6,"long_text":"","short_text":"-"},{"line":7,"long_text":"","short_text":"-"},{"line":8,"long_text":"","short_text":"-"},{"line":9,"long_text":"","short_text":"-"},{"line":10,"long_text":"","short_text":"-"},{"line":11,"long_text":"","short_text":"-"},{"line":12,"long_text":"","short_text":"-"},{"line":13,"long_text":"","short_text":"-"},{"line":14,"long_text":"","short_text":"-"},{"line":15,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":16,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":17,"long_text":"","short_text":"-"},{"line":18,"long_text":"","short_text":"-"},{"line":19,"long_text":"","short_text":"-"},{"line":20,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":21,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":22,"long_text":"","short_text":"-"},{"line":23,"long_text":"","short_text":"-"}],"spec/fixtures/fixtures/more_files/peekaview.m":[{"line":1,"long_text":"","short_text":"-"},{"line":2,"long_text":"","short_text":"-"},{"line":3,"long_text":"","short_text":"-"},{"line":4,"long_text":"","short_text":"-"},{"line":5,"long_text":"","short_text":"-"},{"line":6,"long_text":"","short_text":"-"},{"line":7,"long_text":"","short_text":"-"},{"line":8,"long_text":"","short_text":"-"},{"line":9,"long_text":"","short_text":"-"},{"line":10,"long_text":"","short_text":"-"},{"line":11,"long_text":"","short_text":"-"},{"line":12,"long_text":"","short_text":"-"},{"line":13,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":14,"long_text":"","short_text":"-"},{"line":15,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":16,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":17,"long_text":"","short_text":"-"},{"line":18,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":19,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":20,"long_text":"","short_text":"#####","background_color":"0xFC635E"},{"line":21,"long_text":"","short_text":"-"},{"line":22,"long_text":"","short_text":"-"},{"line":23,"long_text":"","short_text":"-"},{"line":24,"long_text":"","short_text":"-"},{"line":25,"long_text":"","short_text":"-"},{"line":26,"long_text":"","short_text":"-"},{"line":27,"long_text":"","short_text":"-"},{"line":28,"long_text":"","short_text":"-"},{"line":29,"long_text":"","short_text":"-"},{"line":30,"long_text":"","short_text":"-"},{"line":31,"long_text":"","short_text":"-"}],"spec/fixtures/fixturesTests/BranchesTests.m":[{"line":1,"long_text":"","short_text":"-"},{"line":2,"long_text":"","short_text":"-"},{"line":3,"long_text":"","short_text":"-"},{"line":4,"long_text":"","short_text":"-"},{"line":5,"long_text":"","short_text":"-"},{"line":6,"long_text":"","short_text":"-"},{"line":7,"long_text":"","short_text":"-"},{"line":8,"long_text":"","short_text":"-"},{"line":9,"long_text":"","short_text":"-"},{"line":10,"long_text":"","short_text":"-"},{"line":11,"long_text":"","short_text":"-"},{"line":12,"long_text":"","short_text":"-"},{"line":13,"long_text":"","short_text":"-"},{"line":14,"long_text":"","short_text":"-"},{"line":15,"long_text":"","short_text":"-"},{"line":16,"long_text":"","short_text":"-"},{"line":17,"long_text":"","short_text":"-"},{"line":18,"long_text":"","short_text":"-"},{"line":19,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":20,"long_text":"","short_text":"-"},{"line":21,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":22,"long_text":"","short_text":"-"},{"line":23,"long_text":"","short_text":"-"},{"line":24,"long_text":"","short_text":"-"},{"line":25,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":26,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":27,"long_text":"","short_text":"-"},{"line":28,"long_text":"","short_text":"-"},{"line":29,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":30,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":31,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":32,"long_text":"","short_text":"-"},{"line":33,"long_text":"","short_text":"-"},{"line":34,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":35,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":36,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":37,"long_text":"","short_text":"-"},{"line":38,"long_text":"","short_text":"-"}],"spec/fixtures/fixturesTests/fixturesTests.m":[{"line":1,"long_text":"","short_text":"-"},{"line":2,"long_text":"","short_text":"-"},{"line":3,"long_text":"","short_text":"-"},{"line":4,"long_text":"","short_text":"-"},{"line":5,"long_text":"","short_text":"-"},{"line":6,"long_text":"","short_text":"-"},{"line":7,"long_text":"","short_text":"-"},{"line":8,"long_text":"","short_text":"-"},{"line":9,"long_text":"","short_text":"-"},{"line":10,"long_text":"","short_text":"-"},{"line":11,"long_text":"","short_text":"-"},{"line":12,"long_text":"","short_text":"-"},{"line":13,"long_text":"","short_text":"-"},{"line":14,"long_text":"","short_text":"-"},{"line":15,"long_text":"","short_text":"-"},{"line":16,"long_text":"","short_text":"-"},{"line":17,"long_text":"","short_text":"-"},{"line":18,"long_text":"","short_text":"-"},{"line":19,"long_text":"","short_text":"-"},{"line":20,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":21,"long_text":"","short_text":"-"},{"line":22,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":23,"long_text":"","short_text":"-"},{"line":24,"long_text":"","short_text":"-"},{"line":25,"long_text":"","short_text":"-"},{"line":26,"long_text":"","short_text":"-"},{"line":27,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":28,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":29,"long_text":"","short_text":"-"},{"line":30,"long_text":"","short_text":"-"},{"line":31,"long_text":"","short_text":"-"},{"line":32,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":33,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":34,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":35,"long_text":"","short_text":"-"},{"line":36,"long_text":"","short_text":"-"}],"spec/fixtures/fixturesTests/peekaviewTests.m":[{"line":1,"long_text":"","short_text":"-"},{"line":2,"long_text":"","short_text":"-"},{"line":3,"long_text":"","short_text":"-"},{"line":4,"long_text":"","short_text":"-"},{"line":5,"long_text":"","short_text":"-"},{"line":6,"long_text":"","short_text":"-"},{"line":7,"long_text":"","short_text":"-"},{"line":8,"long_text":"","short_text":"-"},{"line":9,"long_text":"","short_text":"-"},{"line":10,"long_text":"","short_text":"-"},{"line":11,"long_text":"","short_text":"-"},{"line":12,"long_text":"","short_text":"-"},{"line":13,"long_text":"","short_text":"-"},{"line":14,"long_text":"","short_text":"-"},{"line":15,"long_text":"","short_text":"-"},{"line":16,"long_text":"","short_text":"-"},{"line":17,"long_text":"","short_text":"-"},{"line":18,"long_text":"","short_text":"-"},{"line":19,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":20,"long_text":"","short_text":"-"},{"line":21,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":22,"long_text":"","short_text":"-"},{"line":23,"long_text":"","short_text":"-"},{"line":24,"long_text":"","short_text":"-"},{"line":25,"long_text":"","short_text":"-"},{"line":26,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":27,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":28,"long_text":"","short_text":"-"},{"line":29,"long_text":"","short_text":"-"},{"line":30,"long_text":"","short_text":"-"},{"line":31,"long_text":"","short_text":"2","background_color":"0x35CC4B"},{"line":32,"long_text":"","short_text":"1","background_color":"0x35CC4B"},{"line":33,"long_text":"","short_text":"-"},{"line":34,"long_text":"","short_text":"-"}]}}
@@ -0,0 +1,21 @@
1
+ require 'cocoapods'
2
+ require File.join(File.dirname(__FILE__), '../../lib/cocoapods_plugin')
3
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
4
+
5
+ describe Slather do
6
+ describe 'CocoaPods Plugin' do
7
+ it 'should setup slather for coverage in the Pods project' do
8
+ mock_project = double(Xcodeproj::Project)
9
+ allow(Xcodeproj::Project).to receive(:open).and_return(mock_project)
10
+ expect(mock_project).to receive(:slather_setup_for_coverage)
11
+ expect(mock_project).to receive(:save)
12
+
13
+ # Execute the post_install hook via CocoaPods
14
+ sandbox_root = 'Pods'
15
+ sandbox = Pod::Sandbox.new(sandbox_root)
16
+ context = Pod::Installer::PostInstallHooksContext.generate(sandbox, [])
17
+ Pod::HooksManager.run(:post_install, context, {'slather' => nil})
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,337 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe Slather::CoverageFile do
4
+
5
+ let(:fixtures_project) do
6
+ Slather::Project.open(FIXTURES_PROJECT_PATH)
7
+ end
8
+
9
+ let(:coverage_file) do
10
+ fixtures_project.send(:coverage_files).detect { |cf| cf.source_file_pathname.basename.to_s == "fixtures.m" }
11
+ end
12
+
13
+ describe "#initialize" do
14
+ it "should convert the provided path string to a Pathname object, and set it as the gcno_file_pathname" do
15
+ expect(coverage_file.gcno_file_pathname).to be_exist
16
+ expect(coverage_file.gcno_file_pathname.basename.to_s).to eq("fixtures.gcno")
17
+ end
18
+ end
19
+
20
+ describe "#source_file_pathname" do
21
+ it "should look in the source_directory if it has been set on the project" do
22
+ coverage_file = Slather::CoverageFile.new(fixtures_project, "fixtures.m")
23
+ fixtures_project.source_directory = Pathname(File.join(File.dirname(__FILE__), '../fixtures/')).realpath.to_s
24
+ expect(coverage_file.source_file_pathname).to eq(fixtures_project["fixtures/fixtures.m"].real_path)
25
+ end
26
+
27
+ it "should look in the source_directory if it has been set on the project" do
28
+ coverage_file = Slather::CoverageFile.new(fixtures_project, "fixtures.m")
29
+ fixtures_project.source_directory = Pathname(File.join(File.dirname(__FILE__), '../fixtures/fixturesTests')).realpath.to_s
30
+ expect(coverage_file.source_file_pathname).to be_nil
31
+ end
32
+
33
+ it "should return nil if it couldn't find the coverage files's source implementation file in the project" do
34
+ whoami_file = Slather::CoverageFile.new(fixtures_project, "/some/path/whoami.gcno")
35
+ expect(whoami_file.source_file_pathname).to be_nil
36
+ end
37
+
38
+ ["cpp", "mm", "m"].each do |file_ext|
39
+ it "should work for #{file_ext} files" do
40
+ file_name = "fixtures_#{file_ext}.#{file_ext}"
41
+ coverage_file = fixtures_project.send(:coverage_files).detect { |cf| cf.source_file_pathname.basename.to_s == file_name }
42
+ expect(coverage_file.source_file_pathname).to eq(fixtures_project["fixtures/#{file_name}"].real_path)
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "#source_file" do
48
+ it "should return a file object for the source_file_pathname" do
49
+ file = coverage_file.source_file
50
+ expect(file).to be_a File
51
+ expect(Pathname(file.path)).to eq(coverage_file.source_file_pathname)
52
+ end
53
+ end
54
+
55
+ describe "#source_data" do
56
+ it "should return the contents of the source_file" do
57
+ expected = <<-OBJC
58
+ //
59
+ // fixtures.m
60
+ // fixtures
61
+ //
62
+ // Created by Mark Larsen on 6/24/14.
63
+ // Copyright (c) 2014 marklarr. All rights reserved.
64
+ //
65
+
66
+ #import "fixtures.h"
67
+
68
+ @implementation fixtures
69
+
70
+ - (void)testedMethod
71
+ {
72
+ NSLog(@"tested");
73
+ }
74
+
75
+ - (void)untestedMethod
76
+ {
77
+ NSLog(@"untested");
78
+ }
79
+
80
+ @end
81
+ OBJC
82
+ expect(coverage_file.source_data).to eq(expected)
83
+ end
84
+ end
85
+
86
+ describe "source_file_basename" do
87
+ it "returns the base name of the source file" do
88
+ expect(coverage_file.source_file_basename).to eq("fixtures")
89
+ end
90
+ end
91
+
92
+ describe "source_file_pathname_relative_to_repo_root" do
93
+ it "should return a pathname to the source_file, relative to the root of the repo" do
94
+ expect(coverage_file.source_file_pathname_relative_to_repo_root).to eq(Pathname("spec/fixtures/fixtures/fixtures.m"))
95
+ end
96
+ end
97
+
98
+ describe "#ignored" do
99
+ it "should return true if the source_file_pathname globs against anything in the project.ignore_list" do
100
+ coverage_file.project.ignore_list = ["*spec*", "*test*"]
101
+ expect(coverage_file).to be_ignored
102
+ end
103
+
104
+ it "should return false if the source_file_pathname does not glob against anything in the project.ignore_list" do
105
+ coverage_file.project.ignore_list = ["*test*", "*XCTest*"]
106
+ expect(coverage_file).not_to be_ignored
107
+ end
108
+ end
109
+
110
+ describe "gcov_data" do
111
+ it "should process the gcno file with gcov and return the contents of the file" do
112
+ expect(coverage_file.gcov_data).to include("1: 15: NSLog(@\"tested\");")
113
+ end
114
+ end
115
+
116
+ describe "line coverage" do
117
+
118
+ let(:line_coverage_file) do
119
+ fixtures_project.send(:coverage_files).detect { |cf| cf.source_file_pathname.basename.to_s == "fixtures.m" }
120
+ end
121
+
122
+ describe "#coverage_for_line" do
123
+ it "should return nil if the line is not relevant to coverage" do
124
+ expect(line_coverage_file.coverage_for_line(" -: 75: }")).to be_nil
125
+ end
126
+
127
+ it "should return the number of times the line was executed if the line is relevant to coverage" do
128
+ expect(line_coverage_file.coverage_for_line(" 1: 75: }")).to eq(1)
129
+ expect(line_coverage_file.coverage_for_line(" 15: 75: }")).to eq(15)
130
+ expect(line_coverage_file.coverage_for_line(" ####: 75: }")).to eq(0)
131
+ end
132
+ end
133
+
134
+ describe "num_lines_tested" do
135
+ it "should return the correct number of lines tested" do
136
+ expect(line_coverage_file.num_lines_tested).to eq(2)
137
+ end
138
+ end
139
+
140
+ describe "num_lines_testable" do
141
+ it "should return the correct number of lines that are testable" do
142
+ expect(line_coverage_file.num_lines_testable).to eq(4)
143
+ end
144
+ end
145
+
146
+ describe "percentage_lines_tested" do
147
+ it "should return the correct percentage of lines that are tested" do
148
+ expect(line_coverage_file.percentage_lines_tested).to eq(50)
149
+ end
150
+
151
+ it "should return 100 if no testable lines" do
152
+ line_coverage_file.stub(:num_lines_testable).and_return(0)
153
+ expect(line_coverage_file.percentage_lines_tested).to eq(100)
154
+ end
155
+ end
156
+ end
157
+
158
+ describe "branch coverage" do
159
+
160
+ let(:branch_coverage_file) do
161
+ fixtures_project.send(:coverage_files).detect { |cf| cf.source_file_pathname.basename.to_s == "Branches.m" }
162
+ end
163
+
164
+ describe "branch_coverage_data" do
165
+ it "should return a hash with keys representing the line number of a branch statement" do
166
+ expect(branch_coverage_file.branch_coverage_data.keys[0]).to eq(15)
167
+ expect(branch_coverage_file.branch_coverage_data.keys[1]).to eq(18)
168
+ expect(branch_coverage_file.branch_coverage_data.keys[2]).to eq(26)
169
+ expect(branch_coverage_file.branch_coverage_data.keys[3]).to eq(29)
170
+ end
171
+
172
+ it "should store an array for each line number which contains the hit count for each branch" do
173
+ data = branch_coverage_file.branch_coverage_data[15]
174
+ expect(data.length).to eq(2)
175
+ expect(data[0]).to eq(1)
176
+ expect(data[1]).to eq(1)
177
+
178
+ data = branch_coverage_file.branch_coverage_data[18]
179
+ expect(data.length).to eq(2)
180
+ expect(data[0]).to eq(0)
181
+ expect(data[1]).to eq(1)
182
+
183
+ data = branch_coverage_file.branch_coverage_data[26]
184
+ expect(data.length).to eq(2)
185
+ expect(data[0]).to eq(2)
186
+ expect(data[1]).to eq(0)
187
+
188
+ data = branch_coverage_file.branch_coverage_data[29]
189
+ expect(data.length).to eq(4)
190
+ expect(data[0]).to eq(0)
191
+ expect(data[1]).to eq(0)
192
+ expect(data[2]).to eq(0)
193
+ expect(data[3]).to eq(0)
194
+ end
195
+ end
196
+
197
+ describe "branch_coverage_data_for_statement_on_line" do
198
+ it "return the array with branch hit counts for statement at a given line number" do
199
+ data = branch_coverage_file.branch_coverage_data[15]
200
+ expect(data.length).to eq(2)
201
+ expect(data[0]).to eq(1)
202
+ expect(data[1]).to eq(1)
203
+
204
+ data = branch_coverage_file.branch_coverage_data[18]
205
+ expect(data.length).to eq(2)
206
+ expect(data[0]).to eq(0)
207
+ expect(data[1]).to eq(1)
208
+
209
+ data = branch_coverage_file.branch_coverage_data[26]
210
+ expect(data.length).to eq(2)
211
+ expect(data[0]).to eq(2)
212
+ expect(data[1]).to eq(0)
213
+
214
+ data = branch_coverage_file.branch_coverage_data[29]
215
+ expect(data.length).to eq(4)
216
+ expect(data[0]).to eq(0)
217
+ expect(data[1]).to eq(0)
218
+ expect(data[2]).to eq(0)
219
+ expect(data[3]).to eq(0)
220
+ end
221
+ end
222
+
223
+ describe "num_branch_hits_for_statement_on_line" do
224
+ it "returns the number of branches executed below the statement at a given line number" do
225
+ expect(branch_coverage_file.num_branch_hits_for_statement_on_line(15)).to eq(2)
226
+ expect(branch_coverage_file.num_branch_hits_for_statement_on_line(18)).to eq(1)
227
+ expect(branch_coverage_file.num_branch_hits_for_statement_on_line(26)).to eq(1)
228
+ expect(branch_coverage_file.num_branch_hits_for_statement_on_line(29)).to eq(0)
229
+ end
230
+ end
231
+
232
+ describe "rate_branch_coverage_for_statement_on_line" do
233
+ it "returns the ratio between number of executed and number of total branches at a given line number" do
234
+ expect(branch_coverage_file.rate_branch_coverage_for_statement_on_line(15)).to eq(1.0)
235
+ expect(branch_coverage_file.rate_branch_coverage_for_statement_on_line(18)).to eq(0.5)
236
+ expect(branch_coverage_file.rate_branch_coverage_for_statement_on_line(26)).to eq(0.5)
237
+ expect(branch_coverage_file.rate_branch_coverage_for_statement_on_line(29)).to eq(0.0)
238
+ end
239
+
240
+ it "return 0.0 for a line without branch data" do
241
+ expect(branch_coverage_file.rate_branch_coverage_for_statement_on_line(1)).to eq(0.0)
242
+ end
243
+ end
244
+
245
+ describe "percentage_branch_coverage_for_statement_on_line" do
246
+ it "returns the average hit percentage of all branches below the statement at a given line number" do
247
+ expect(branch_coverage_file.percentage_branch_coverage_for_statement_on_line(15)).to eq(100)
248
+ expect(branch_coverage_file.percentage_branch_coverage_for_statement_on_line(18)).to eq(50)
249
+ expect(branch_coverage_file.percentage_branch_coverage_for_statement_on_line(26)).to eq(50)
250
+ expect(branch_coverage_file.percentage_branch_coverage_for_statement_on_line(29)).to eq(0)
251
+ end
252
+ end
253
+
254
+ describe "num_branches_testable" do
255
+ it "returns the number of testable branches inside the class" do
256
+ expect(branch_coverage_file.num_branches_testable).to eq(10)
257
+ end
258
+ end
259
+
260
+ describe "num_branches_tested" do
261
+ it "returns the number of tested branches inside the class" do
262
+ expect(branch_coverage_file.num_branches_tested).to eq(4)
263
+ end
264
+ end
265
+
266
+ describe "rate_branches_tested" do
267
+ it "returns the ratio between tested and testable branches inside the class" do
268
+ expect(branch_coverage_file.rate_branches_tested).to eq(0.4)
269
+ end
270
+ end
271
+ end
272
+
273
+ describe "empty coverage data" do
274
+
275
+ let(:empty_file) do
276
+ fixtures_project.send(:coverage_files).detect { |cf| cf.source_file_pathname.basename.to_s == "Empty.m" }
277
+ end
278
+
279
+ describe "gcov_data" do
280
+ it "returns an empty string" do
281
+ gcov_data = empty_file.gcov_data
282
+ expect(gcov_data).to be_empty
283
+ end
284
+ end
285
+
286
+ describe "cleaned_gcov_data" do
287
+ it "returns an empty string" do
288
+ cleaned_gcov_data = empty_file.cleaned_gcov_data
289
+ expect(cleaned_gcov_data).to be_empty
290
+ end
291
+ end
292
+
293
+ describe "branch_coverage_data" do
294
+ it "returns an empty hash for branch_coverage_data of an empty file" do
295
+ data = empty_file.branch_coverage_data
296
+ expect(data).to be_empty
297
+ end
298
+ end
299
+
300
+ describe "num_branch_hits_for_statement_on_line" do
301
+ it "returns 0.0 when no data is available" do
302
+ expect(empty_file.num_branch_hits_for_statement_on_line(1)).to eq(0)
303
+ end
304
+ end
305
+
306
+ describe "rate_branch_coverage_for_statement_on_line" do
307
+ it "returns 0.0 when no data is available" do
308
+ expect(empty_file.rate_branch_coverage_for_statement_on_line(1)).to eq(0.0)
309
+ end
310
+ end
311
+
312
+ describe "percentage_branch_coverage_for_statement_on_line" do
313
+ it "returns 0 when no data is available" do
314
+ expect(empty_file.percentage_branch_coverage_for_statement_on_line(1)).to eq(0)
315
+ end
316
+ end
317
+
318
+ describe "num_branches_testable" do
319
+ it "returns 0 when no data is available" do
320
+ expect(empty_file.num_branches_testable).to eq(0)
321
+ end
322
+ end
323
+
324
+ describe "num_branches_tested" do
325
+ it "returns 0 when no data is available" do
326
+ expect(empty_file.num_branches_tested).to eq(0)
327
+ end
328
+ end
329
+
330
+ describe "rate_branches_tested" do
331
+ it "returns 0.0 when no data is available" do
332
+ expect(empty_file.rate_branches_tested).to eq(0.0)
333
+ end
334
+ end
335
+ end
336
+
337
+ end
@@ -0,0 +1,49 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+ require 'json'
3
+
4
+ describe Slather::CoverageService::CoberturaXmlOutput do
5
+
6
+ let(:fixtures_project) do
7
+ proj = Slather::Project.open(FIXTURES_PROJECT_PATH)
8
+ proj.extend(Slather::CoverageService::CoberturaXmlOutput)
9
+ end
10
+
11
+ describe '#coverage_file_class' do
12
+ it "should return CoverageFile" do
13
+ expect(fixtures_project.send(:coverage_file_class)).to eq(Slather::CoverageFile)
14
+ end
15
+ end
16
+
17
+ describe '#post' do
18
+ it "should create an XML report spanning all coverage files" do
19
+ fixtures_project.post
20
+
21
+ file = File.open(FIXTURES_XML_PATH)
22
+ fixture_xml_doc = Nokogiri::XML(file)
23
+ file.close
24
+
25
+ file = File.open('cobertura.xml')
26
+ current_xml_doc = Nokogiri::XML(file)
27
+ file.close
28
+
29
+ [current_xml_doc, fixture_xml_doc].each do |xml_doc|
30
+ xml_doc.root['timestamp'] = ''
31
+ xml_doc.root['version'] = ''
32
+ source_node = xml_doc.at_css "source"
33
+ source_node.content = ''
34
+ end
35
+
36
+ EquivalentXml.equivalent?(current_xml_doc, fixture_xml_doc).should be_truthy
37
+ end
38
+
39
+ it "should create an XML report in the given output directory" do
40
+ fixtures_project.output_directory = "./output"
41
+ fixtures_project.post
42
+
43
+ filepath = "#{fixtures_project.output_directory}/cobertura.xml"
44
+ expect(File.exists?(filepath)).to be_truthy
45
+
46
+ FileUtils.rm_rf(fixtures_project.output_directory)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,122 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe Slather::CoverageService::Coveralls do
4
+
5
+ let(:fixtures_project) do
6
+ proj = Slather::Project.open(FIXTURES_PROJECT_PATH)
7
+ proj.extend(Slather::CoverageService::Coveralls)
8
+ end
9
+
10
+ describe "#coverage_file_class" do
11
+ it "should return CoverallsCoverageFile" do
12
+ expect(fixtures_project.send(:coverage_file_class)).to eq(Slather::CoverallsCoverageFile)
13
+ end
14
+ end
15
+
16
+ describe "#travis_job_id" do
17
+ it "should return the TRAVIS_JOB_ID environment variable" do
18
+ actual_travis_job_id = ENV['TRAVIS_JOB_ID']
19
+ ENV['TRAVIS_JOB_ID'] = "9182"
20
+ expect(fixtures_project.send(:travis_job_id)).to eq("9182")
21
+ ENV['TRAVIS_JOB_ID'] = actual_travis_job_id
22
+ end
23
+ end
24
+
25
+ describe '#coveralls_coverage_data' do
26
+
27
+ context "coverage_service is :travis_ci" do
28
+ before(:each) { fixtures_project.ci_service = :travis_ci }
29
+
30
+ it "should return valid json for coveralls coverage data" do
31
+ fixtures_project.stub(:travis_job_id).and_return("9182")
32
+ expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql("{\"service_job_id\":\"9182\",\"service_name\":\"travis-ci\"}").excluding("source_files")
33
+ expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql(fixtures_project.send(:coverage_files).map(&:as_json).to_json).at_path("source_files")
34
+ end
35
+
36
+ it "should raise an error if there is no TRAVIS_JOB_ID" do
37
+ fixtures_project.stub(:travis_job_id).and_return(nil)
38
+ expect { fixtures_project.send(:coveralls_coverage_data) }.to raise_error(StandardError)
39
+ end
40
+ end
41
+
42
+ context "coverage_service is :travis_pro" do
43
+ before(:each) { fixtures_project.ci_service = :travis_pro }
44
+
45
+ it "should return valid json for coveralls coverage data" do
46
+ fixtures_project.stub(:travis_job_id).and_return("9182")
47
+ fixtures_project.stub(:coverage_access_token).and_return("abc123")
48
+ expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql("{\"service_job_id\":\"9182\",\"service_name\":\"travis-pro\",\"repo_token\":\"abc123\"}").excluding("source_files")
49
+ expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql(fixtures_project.send(:coverage_files).map(&:as_json).to_json).at_path("source_files")
50
+ end
51
+
52
+ it "should raise an error if there is no TRAVIS_JOB_ID" do
53
+ fixtures_project.stub(:travis_job_id).and_return(nil)
54
+ expect { fixtures_project.send(:coveralls_coverage_data) }.to raise_error(StandardError)
55
+ end
56
+ end
57
+
58
+ context "coverage_service is :circleci" do
59
+ before(:each) { fixtures_project.ci_service = :circleci }
60
+
61
+ it "should return valid json for coveralls coverage data" do
62
+ fixtures_project.stub(:circleci_job_id).and_return("9182")
63
+ fixtures_project.stub(:coverage_access_token).and_return("abc123")
64
+ fixtures_project.stub(:circleci_pull_request).and_return("1")
65
+ fixtures_project.stub(:circleci_build_url).and_return("https://circleci.com/gh/Bruce/Wayne/1")
66
+ fixtures_project.stub(:circleci_git_info).and_return({ :head => { :id => "ababa123", :author_name => "bwayne", :message => "hello" }, :branch => "master" })
67
+ expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql("{\"service_job_id\":\"9182\",\"service_name\":\"circleci\",\"repo_token\":\"abc123\",\"service_pull_request\":\"1\",\"service_build_url\":\"https://circleci.com/gh/Bruce/Wayne/1\",\"git\":{\"head\":{\"id\":\"ababa123\",\"author_name\":\"bwayne\",\"message\":\"hello\"},\"branch\":\"master\"}}").excluding("source_files")
68
+ expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql(fixtures_project.send(:coverage_files).map(&:as_json).to_json).at_path("source_files")
69
+ end
70
+
71
+ it "should raise an error if there is no CIRCLE_BUILD_NUM" do
72
+ fixtures_project.stub(:circleci_job_id).and_return(nil)
73
+ expect { fixtures_project.send(:coveralls_coverage_data) }.to raise_error(StandardError)
74
+ end
75
+ end
76
+
77
+ context "coverage_service is :jenkins" do
78
+ before(:each) { fixtures_project.ci_service = :jenkins }
79
+
80
+ it "should return valid json for coveralls coverage data" do
81
+ fixtures_project.stub(:jenkins_job_id).and_return("9182")
82
+ fixtures_project.stub(:coverage_access_token).and_return("abc123")
83
+ fixtures_project.stub(:jenkins_git_info).and_return({head: {id: "master", author_name: "author", message: "pull title" }, branch: "branch"})
84
+ fixtures_project.stub(:jenkins_branch_name).and_return('master')
85
+ expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql("{\"service_job_id\":\"9182\",\"service_name\":\"jenkins\",\"repo_token\":\"abc123\",\"git\":{\"head\":{\"id\":\"master\",\"author_name\":\"author\",\"message\":\"pull title\"},\"branch\":\"branch\"}}").excluding("source_files")
86
+ expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql(fixtures_project.send(:coverage_files).map(&:as_json).to_json).at_path("source_files")
87
+ end
88
+
89
+ it "should raise an error if there is no BUILD_ID" do
90
+ fixtures_project.stub(:jenkins_job_id).and_return(nil)
91
+ expect { fixtures_project.send(:coveralls_coverage_data) }.to raise_error(StandardError)
92
+ end
93
+ end
94
+
95
+ it "should raise an error if it does not recognize the ci_service" do
96
+ fixtures_project.ci_service = :jenkins_ci
97
+ expect { fixtures_project.send(:coveralls_coverage_data) }.to raise_error(StandardError)
98
+ end
99
+ end
100
+
101
+ describe '#post' do
102
+ it "should save the coveralls_coverage_data to a file and post it to coveralls" do
103
+ fixtures_project.stub(:travis_job_id).and_return("9182")
104
+ expect(fixtures_project).to receive(:`) do |cmd|
105
+ expect(cmd).to eq("curl -s --form json_file=@coveralls_json_file https://coveralls.io/api/v1/jobs")
106
+ expect(File.read('coveralls_json_file')).to be_json_eql(fixtures_project.send(:coveralls_coverage_data))
107
+ end.once
108
+ fixtures_project.post
109
+ end
110
+
111
+ it "should always remove the coveralls_json_file after it's done" do
112
+ fixtures_project.stub(:`)
113
+
114
+ fixtures_project.stub(:travis_job_id).and_return("9182")
115
+ fixtures_project.post
116
+ expect(File.exist?("coveralls_json_file")).to be_falsy
117
+ fixtures_project.stub(:travis_job_id).and_return(nil)
118
+ expect { fixtures_project.post }.to raise_error
119
+ expect(File.exist?("coveralls_json_file")).to be_falsy
120
+ end
121
+ end
122
+ end