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.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +45 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +132 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +206 -0
- data/Rakefile +1 -0
- data/assets/highlight.pack.js +1 -0
- data/assets/list.min.js +1 -0
- data/assets/slather.css +316 -0
- data/bin/slather +117 -0
- data/docs/logo.jpg +0 -0
- data/lib/cocoapods_plugin.rb +10 -0
- data/lib/slather.rb +20 -0
- data/lib/slather/coverage_file.rb +195 -0
- data/lib/slather/coverage_service/cobertura_xml_output.rb +183 -0
- data/lib/slather/coverage_service/coveralls.rb +186 -0
- data/lib/slather/coverage_service/gutter_json_output.rb +50 -0
- data/lib/slather/coverage_service/hardcover.rb +61 -0
- data/lib/slather/coverage_service/html_output.rb +244 -0
- data/lib/slather/coverage_service/simple_output.rb +31 -0
- data/lib/slather/coveralls_coverage_file.rb +13 -0
- data/lib/slather/project.rb +132 -0
- data/lib/slather/version.rb +3 -0
- data/slather.gemspec +32 -0
- data/spec/fixtures/fixtures.xcodeproj/project.pbxproj +496 -0
- data/spec/fixtures/fixtures.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/spec/fixtures/fixtures.xcodeproj/xcshareddata/xcschemes/fixtures.xcscheme +69 -0
- data/spec/fixtures/fixtures/Supporting Files/fixtures-Prefix.pch +9 -0
- data/spec/fixtures/fixtures/fixtures.h +16 -0
- data/spec/fixtures/fixtures/fixtures.m +23 -0
- data/spec/fixtures/fixtures/fixtures_cpp.cpp +9 -0
- data/spec/fixtures/fixtures/fixtures_cpp.h +6 -0
- data/spec/fixtures/fixtures/fixtures_m.h +5 -0
- data/spec/fixtures/fixtures/fixtures_m.m +5 -0
- data/spec/fixtures/fixtures/fixtures_mm.h +5 -0
- data/spec/fixtures/fixtures/fixtures_mm.mm +5 -0
- data/spec/fixtures/fixtures/more_files/Branches.h +15 -0
- data/spec/fixtures/fixtures/more_files/Branches.m +45 -0
- data/spec/fixtures/fixtures/more_files/Empty.h +13 -0
- data/spec/fixtures/fixtures/more_files/Empty.m +13 -0
- data/spec/fixtures/fixtures/more_files/peekaview.h +13 -0
- data/spec/fixtures/fixtures/more_files/peekaview.m +31 -0
- data/spec/fixtures/fixturesTests/BranchesTests.m +38 -0
- data/spec/fixtures/fixturesTests/Supporting Files/en.lproj/InfoPlist.strings +2 -0
- data/spec/fixtures/fixturesTests/Supporting Files/fixturesTests-Info.plist +22 -0
- data/spec/fixtures/fixturesTests/fixturesTests.m +36 -0
- data/spec/fixtures/fixturesTests/peekaviewTests.m +34 -0
- data/spec/fixtures/fixtures_html/Branches.m.html +261 -0
- data/spec/fixtures/fixtures_html/BranchesTests.m.html +228 -0
- data/spec/fixtures/fixtures_html/Empty.m.html +30 -0
- data/spec/fixtures/fixtures_html/fixtures.m.html +151 -0
- data/spec/fixtures/fixtures_html/fixturesTests.m.html +216 -0
- data/spec/fixtures/fixtures_html/fixtures_cpp.cpp.html +30 -0
- data/spec/fixtures/fixtures_html/fixtures_m.m.html +30 -0
- data/spec/fixtures/fixtures_html/fixtures_mm.mm.html +30 -0
- data/spec/fixtures/fixtures_html/index.html +134 -0
- data/spec/fixtures/fixtures_html/peekaview.m.html +190 -0
- data/spec/fixtures/fixtures_html/peekaviewTests.m.html +206 -0
- data/spec/fixtures/gutter.json +1 -0
- data/spec/slather/cocoapods_plugin_spec.rb +21 -0
- data/spec/slather/coverage_file_spec.rb +337 -0
- data/spec/slather/coverage_service/cobertura_xml_spec.rb +49 -0
- data/spec/slather/coverage_service/coveralls_spec.rb +122 -0
- data/spec/slather/coverage_service/gutter_json_spec.rb +28 -0
- data/spec/slather/coverage_service/hardcover_spec.rb +87 -0
- data/spec/slather/coverage_service/html_output_spec.rb +179 -0
- data/spec/slather/coverage_service/simple_output_spec.rb +35 -0
- data/spec/slather/fixtures.gcno +0 -0
- data/spec/slather/project_spec.rb +288 -0
- data/spec/spec_helper.rb +27 -0
- metadata +319 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
describe Slather::CoverageService::GutterJsonOutput do
|
|
5
|
+
|
|
6
|
+
let(:fixtures_project) do
|
|
7
|
+
proj = Slather::Project.open(FIXTURES_PROJECT_PATH)
|
|
8
|
+
proj.extend(Slather::CoverageService::GutterJsonOutput)
|
|
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 print out the coverage for each file, and then total coverage" do
|
|
19
|
+
fixtures_project.post
|
|
20
|
+
|
|
21
|
+
fixture_json = File.read(FIXTURES_JSON_PATH)
|
|
22
|
+
current_json = File.read('.gutter.json')
|
|
23
|
+
|
|
24
|
+
expect(current_json).to be_json_eql(fixture_json)
|
|
25
|
+
File.unlink('.gutter.json')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
|
2
|
+
|
|
3
|
+
describe Slather::CoverageService::Hardcover do
|
|
4
|
+
|
|
5
|
+
let(:fixtures_project) do
|
|
6
|
+
proj = Slather::Project.open(FIXTURES_PROJECT_PATH)
|
|
7
|
+
proj.extend(Slather::CoverageService::Hardcover)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
let(:fixture_yaml) do
|
|
11
|
+
yaml_text = <<-EOF
|
|
12
|
+
hardcover_repo_token: "27dd855e706b22126ec6daaaf7bb40b5"
|
|
13
|
+
hardcover_base_url: "http://api.hardcover.io"
|
|
14
|
+
EOF
|
|
15
|
+
yaml = YAML.load(yaml_text)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#coverage_file_class" do
|
|
19
|
+
it "should return CoverallsCoverageFile" do
|
|
20
|
+
expect(fixtures_project.send(:coverage_file_class)).to eq(Slather::CoverallsCoverageFile)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "#job_id" do
|
|
25
|
+
it "should return the Jenkins JOB_NAME and BUILD_NUMBER environment variables" do
|
|
26
|
+
ENV['BUILD_NUMBER'] = "9182"
|
|
27
|
+
ENV['JOB_NAME'] = "slather-master"
|
|
28
|
+
expect(fixtures_project.send(:jenkins_job_id)).to eq("slather-master/9182")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe '#hardcover_coverage_data' do
|
|
33
|
+
|
|
34
|
+
context "coverage_service is :jenkins_ci" do
|
|
35
|
+
before(:each) do
|
|
36
|
+
fixtures_project.ci_service = :jenkins_ci
|
|
37
|
+
Slather::Project.stub(:yml).and_return(fixture_yaml)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should return a valid json" do
|
|
41
|
+
json = JSON(fixtures_project.send(:hardcover_coverage_data))
|
|
42
|
+
expect(json["service_job_id"]).to eq("slather-master/9182")
|
|
43
|
+
expect(json["service_name"]).to eq("jenkins-ci")
|
|
44
|
+
expect(json["repo_token"]).to eq("27dd855e706b22126ec6daaaf7bb40b5")
|
|
45
|
+
expect(json["source_files"]).to_not be_empty
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should raise an error if there is no BUILD_NUMBER or JOB_NAME" do
|
|
49
|
+
fixtures_project.stub(:jenkins_job_id).and_return(nil)
|
|
50
|
+
expect { fixtures_project.send(:hardcover_coverage_data) }.to raise_error(StandardError)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should raise an error if it does not recognize the ci_service" do
|
|
55
|
+
fixtures_project.ci_service = :non_existing_ci
|
|
56
|
+
expect { fixtures_project.send(:hardcover_coverage_data) }.to raise_error(StandardError)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe '#post' do
|
|
61
|
+
before(:each) do
|
|
62
|
+
Slather::Project.stub(:yml).and_return(fixture_yaml)
|
|
63
|
+
fixtures_project.ci_service = :jenkins_ci
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should save the hardcover_coverage_data to a file and post it to hardcover" do
|
|
67
|
+
fixtures_project.stub(:jenkins_job_id).and_return("slather-master/9182")
|
|
68
|
+
fixtures_project.stub(:coverage_service_url).and_return("http://api.hardcover.io")
|
|
69
|
+
expect(fixtures_project).to receive(:`) do |cmd|
|
|
70
|
+
expect(cmd).to eq("curl --form json_file=@hardcover_json_file http://api.hardcover.io/v1/jobs")
|
|
71
|
+
end.once
|
|
72
|
+
fixtures_project.post
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should always remove the hardcover_json_file after it's done" do
|
|
76
|
+
fixtures_project.stub(:`)
|
|
77
|
+
|
|
78
|
+
fixtures_project.stub(:jenkins_job_id).and_return("slather-master/9182")
|
|
79
|
+
fixtures_project.stub(:coverage_service_url).and_return("http://api.hardcover.io")
|
|
80
|
+
fixtures_project.post
|
|
81
|
+
expect(File.exist?("hardcover_json_file")).to be_falsy
|
|
82
|
+
fixtures_project.stub(:jenkins_job_id).and_return(nil)
|
|
83
|
+
expect { fixtures_project.post }.to raise_error
|
|
84
|
+
expect(File.exist?("hardcover_json_file")).to be_falsy
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
|
2
|
+
require 'nokogiri'
|
|
3
|
+
|
|
4
|
+
describe Slather::CoverageService::HtmlOutput do
|
|
5
|
+
|
|
6
|
+
OUTPUT_DIR_PATH = "html"
|
|
7
|
+
|
|
8
|
+
let(:fixture_html_files) do
|
|
9
|
+
["index",
|
|
10
|
+
"fixtures.m",
|
|
11
|
+
"peekaview.m",
|
|
12
|
+
"fixtures_cpp.cpp",
|
|
13
|
+
"fixtures_mm.mm",
|
|
14
|
+
"fixtures_m.m",
|
|
15
|
+
"Branches.m",
|
|
16
|
+
"Empty.m",
|
|
17
|
+
"fixturesTests.m",
|
|
18
|
+
"peekaviewTests.m",
|
|
19
|
+
"BranchesTests.m"].map { |file| "#{file}.html"}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
let(:fixtures_project) do
|
|
23
|
+
proj = Slather::Project.open(FIXTURES_PROJECT_PATH)
|
|
24
|
+
proj.extend(Slather::CoverageService::HtmlOutput)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#coverage_file_class' do
|
|
28
|
+
it "should return CoverageFile" do
|
|
29
|
+
expect(fixtures_project.send(:coverage_file_class)).to eq(Slather::CoverageFile)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '#post' do
|
|
34
|
+
before(:each) {
|
|
35
|
+
fixtures_project.stub(:print_path_coverage)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
after(:each) {
|
|
39
|
+
FileUtils.rm_rf(OUTPUT_DIR_PATH) if Dir.exist?(OUTPUT_DIR_PATH)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def extract_header_title(doc)
|
|
43
|
+
doc.at_css('title').text
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should create all coverage as static html files" do
|
|
47
|
+
fixtures_project.post
|
|
48
|
+
|
|
49
|
+
fixture_html_files.map { |filename|
|
|
50
|
+
File.join(OUTPUT_DIR_PATH, filename)
|
|
51
|
+
}.each { |filepath|
|
|
52
|
+
expect(File.exist?(filepath)).to be_truthy
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should print out the path of the html folder by default" do
|
|
57
|
+
fixtures_project.post
|
|
58
|
+
|
|
59
|
+
expect(fixtures_project).to have_received(:print_path_coverage).with("html/index.html")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should open the index.html automatically if --show is flagged" do
|
|
63
|
+
fixtures_project.stub(:open_coverage)
|
|
64
|
+
|
|
65
|
+
fixtures_project.show_html = true
|
|
66
|
+
fixtures_project.post
|
|
67
|
+
|
|
68
|
+
expect(fixtures_project).to have_received(:open_coverage).with("html/index.html")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should create index html with correct coverage information" do
|
|
72
|
+
def extract_title(doc)
|
|
73
|
+
doc.at_css('#reports > h2').text
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def extract_coverage_text(doc)
|
|
77
|
+
doc.at_css('#total_coverage').text
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def extract_coverage_class(doc)
|
|
81
|
+
doc.at_css('#total_coverage').attribute("class").to_s
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def extract_cov_header(doc)
|
|
85
|
+
doc.css("table.coverage_list > thead > tr > th").map { |header|
|
|
86
|
+
[header.text, header.attribute("data-sort")].join(", ")
|
|
87
|
+
}.join("; ")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def extract_cov_index(doc)
|
|
91
|
+
coverages = doc.css("table.coverage_list > tbody > tr").map { |tr|
|
|
92
|
+
tr.css("td").map { |td|
|
|
93
|
+
if td.attribute("class")
|
|
94
|
+
td.attribute("class").to_s.split.join(", ") + ", #{td.text}"
|
|
95
|
+
elsif span = td.at_css("span")
|
|
96
|
+
span.attribute("class").to_s.split.join(", ") + ", #{td.text}"
|
|
97
|
+
else
|
|
98
|
+
td.text
|
|
99
|
+
end
|
|
100
|
+
}.join("; ")
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
list = doc.css("table.coverage_list > tbody").attribute("class")
|
|
104
|
+
coverages.append(list.to_s)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
fixtures_project.post
|
|
108
|
+
|
|
109
|
+
file = File.open(File.join(FIXTURES_HTML_FOLDER_PATH, "index.html"))
|
|
110
|
+
fixture_doc = Nokogiri::HTML(file)
|
|
111
|
+
file.close
|
|
112
|
+
|
|
113
|
+
file = File.open(File.join(OUTPUT_DIR_PATH, "index.html"))
|
|
114
|
+
current_doc = Nokogiri::HTML(file)
|
|
115
|
+
file.close
|
|
116
|
+
|
|
117
|
+
expect(extract_header_title(current_doc)).to eq(extract_header_title(fixture_doc))
|
|
118
|
+
expect(extract_title(current_doc)).to eq(extract_title(fixture_doc))
|
|
119
|
+
expect(extract_coverage_text(current_doc)).to eq(extract_coverage_text(fixture_doc))
|
|
120
|
+
expect(extract_coverage_class(current_doc)).to eq(extract_coverage_class(fixture_doc))
|
|
121
|
+
expect(extract_cov_header(current_doc)).to eq(extract_cov_header(fixture_doc))
|
|
122
|
+
expect(extract_cov_index(current_doc)).to eq(extract_cov_index(fixture_doc))
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "should create html coverage for each file with correct coverage" do
|
|
126
|
+
def extract_title(doc)
|
|
127
|
+
doc.css('#coverage > h2 > span').map{ |x| x.text.strip }.join(", ")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def extract_subtitle(doc)
|
|
131
|
+
(sub = doc.at_css('h4.cov_subtitle')) ? sub.text : ""
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def extract_filepath(doc)
|
|
135
|
+
(path = doc.at_css('h4.cov_filepath'))? path.text : ""
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def extract_cov_data(doc)
|
|
139
|
+
doc.css("table.source_code > tr").map { |tr|
|
|
140
|
+
([tr.attribute("class")] + tr.css('td').map(&:text)).join(",")
|
|
141
|
+
}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
fixtures_project.post
|
|
145
|
+
|
|
146
|
+
fixture_html_files.each { |filename|
|
|
147
|
+
file = File.open(File.join(FIXTURES_HTML_FOLDER_PATH, filename))
|
|
148
|
+
fixture_doc = Nokogiri::HTML(file)
|
|
149
|
+
file.close
|
|
150
|
+
|
|
151
|
+
file = File.open(File.join(OUTPUT_DIR_PATH, filename))
|
|
152
|
+
current_doc = Nokogiri::HTML(file)
|
|
153
|
+
file.close
|
|
154
|
+
|
|
155
|
+
expect(extract_title(fixture_doc)).to eq(extract_title(current_doc))
|
|
156
|
+
expect(extract_subtitle(fixture_doc)).to eq(extract_subtitle(current_doc))
|
|
157
|
+
expect(extract_filepath(fixture_doc)).to eq(extract_filepath(current_doc))
|
|
158
|
+
expect(extract_cov_data(fixture_doc)).to eq(extract_cov_data(current_doc))
|
|
159
|
+
}
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "should create an HTML report directory in the given output directory" do
|
|
163
|
+
fixtures_project.output_directory = "./output"
|
|
164
|
+
fixtures_project.post
|
|
165
|
+
|
|
166
|
+
expect(Dir.exist?(fixtures_project.output_directory)).to be_truthy
|
|
167
|
+
|
|
168
|
+
FileUtils.rm_rf(fixtures_project.output_directory) if Dir.exist?(fixtures_project.output_directory)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "should create the default directory (html) if output directory is faulty" do
|
|
172
|
+
fixtures_project.output_directory = " "
|
|
173
|
+
fixtures_project.post
|
|
174
|
+
|
|
175
|
+
expect(Dir.exist?(OUTPUT_DIR_PATH)).to be_truthy
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
end
|
|
179
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
|
2
|
+
|
|
3
|
+
describe Slather::CoverageService::SimpleOutput do
|
|
4
|
+
|
|
5
|
+
let(:fixtures_project) do
|
|
6
|
+
proj = Slather::Project.open(FIXTURES_PROJECT_PATH)
|
|
7
|
+
proj.extend(Slather::CoverageService::SimpleOutput)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe '#coverage_file_class' do
|
|
11
|
+
it "should return CoverageFile" do
|
|
12
|
+
expect(fixtures_project.send(:coverage_file_class)).to eq(Slather::CoverageFile)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#post' do
|
|
17
|
+
it "should print out the coverage for each file, and then total coverage" do
|
|
18
|
+
["spec/fixtures/fixtures/fixtures.m: 2 of 4 lines (50.00%)",
|
|
19
|
+
"spec/fixtures/fixtures/more_files/peekaview.m: 0 of 6 lines (0.00%)",
|
|
20
|
+
"spec/fixtures/fixtures/fixtures_cpp.cpp: 0 of 0 lines (100.00%)",
|
|
21
|
+
"spec/fixtures/fixtures/fixtures_mm.mm: 0 of 0 lines (100.00%)",
|
|
22
|
+
"spec/fixtures/fixtures/fixtures_m.m: 0 of 0 lines (100.00%)",
|
|
23
|
+
"spec/fixtures/fixtures/more_files/Branches.m: 10 of 20 lines (50.00%)",
|
|
24
|
+
"spec/fixtures/fixtures/more_files/Empty.m: 0 of 0 lines (100.00%)",
|
|
25
|
+
"spec/fixtures/fixturesTests/fixturesTests.m: 7 of 7 lines (100.00%)",
|
|
26
|
+
"spec/fixtures/fixturesTests/peekaviewTests.m: 6 of 6 lines (100.00%)",
|
|
27
|
+
"spec/fixtures/fixturesTests/BranchesTests.m: 10 of 10 lines (100.00%)",
|
|
28
|
+
"Test Coverage: 66.04%"].each do |line|
|
|
29
|
+
expect(fixtures_project).to receive(:puts).with(line)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
fixtures_project.post
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
Binary file
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
|
2
|
+
|
|
3
|
+
describe Slather::Project do
|
|
4
|
+
|
|
5
|
+
let(:fixtures_project) do
|
|
6
|
+
Slather::Project.any_instance.stub(:configure_from_yml)
|
|
7
|
+
Slather::Project.open(FIXTURES_PROJECT_PATH)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "::open" do
|
|
11
|
+
it "should return a project instance that has been configured from yml" do
|
|
12
|
+
expect_any_instance_of(Slather::Project).to receive(:configure_from_yml)
|
|
13
|
+
expect(fixtures_project).not_to be_nil
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#derived_data_dir" do
|
|
18
|
+
it "should return the system's derived data directory" do
|
|
19
|
+
expect(fixtures_project.send(:derived_data_dir)).to eq(File.expand_path('~') + "/Library/Developer/Xcode/DerivedData/")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "#build_directory" do
|
|
24
|
+
it "should return the build_directory property, if it has been explicitly set" do
|
|
25
|
+
build_directory_mock = double(String)
|
|
26
|
+
fixtures_project.build_directory = build_directory_mock
|
|
27
|
+
expect(fixtures_project.build_directory).to eq(build_directory_mock)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should return the derived_data_dir if no build_directory has been set" do
|
|
31
|
+
derived_data_dir_mock = double(String)
|
|
32
|
+
fixtures_project.stub(:derived_data_dir).and_return(derived_data_dir_mock)
|
|
33
|
+
expect(fixtures_project.build_directory).to eq(derived_data_dir_mock)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe "::yml" do
|
|
38
|
+
before(:each) { Slather::Project.instance_variable_set("@yml", nil) }
|
|
39
|
+
|
|
40
|
+
context ".slather.yml file exists" do
|
|
41
|
+
before(:all) { File.open(".slather.yml", "w") { |f| f.write("two: 2") } }
|
|
42
|
+
after(:all) { File.delete(".slather.yml") }
|
|
43
|
+
|
|
44
|
+
it "should load and return .slather.yml, if it exists" do
|
|
45
|
+
expect(Slather::Project.yml).to eq({"two" => 2})
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context ".slather.yml file doesn't exist" do
|
|
50
|
+
it "should return an empy hash" do
|
|
51
|
+
expect(Slather::Project.yml).to eq({})
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "#coverage_files" do
|
|
57
|
+
class SpecCoverageFile < Slather::CoverageFile
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
before(:each) do
|
|
61
|
+
Dir.stub(:[]).and_call_original
|
|
62
|
+
Dir.stub(:[]).with("#{fixtures_project.build_directory}/**/*.gcno").and_return(["/some/path/fixtures.gcno",
|
|
63
|
+
"/some/path/peekaview.gcno",
|
|
64
|
+
"/some/path/fixturesTests.gcno",
|
|
65
|
+
"/some/path/peekaviewTests.gcno",
|
|
66
|
+
"/some/path/NotInProject.gcno",
|
|
67
|
+
"/some/path/NSRange.gcno"])
|
|
68
|
+
fixtures_project.stub(:coverage_file_class).and_return(SpecCoverageFile)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should return coverage file objects of type coverage_file_class for unignored project files" do
|
|
72
|
+
fixtures_project.ignore_list = ["*fixturesTests*"]
|
|
73
|
+
fixtures_project.stub(:dedupe) { |coverage_files| coverage_files }
|
|
74
|
+
coverage_files = fixtures_project.send(:coverage_files)
|
|
75
|
+
coverage_files.each { |cf| expect(cf.kind_of?(SpecCoverageFile)).to be_truthy }
|
|
76
|
+
expect(coverage_files.map { |cf| cf.source_file_pathname.basename.to_s }).to eq(["fixtures.m", "peekaview.m"])
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should raise an exception if no unignored project coverage file files were found" do
|
|
80
|
+
fixtures_project.ignore_list = ["*fixturesTests*", "*fixtures*"]
|
|
81
|
+
expect {fixtures_project.send(:coverage_files)}.to raise_error(StandardError)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "#dedupe" do
|
|
86
|
+
it "should return a deduplicated list of coverage files, favoring the file with higher coverage" do
|
|
87
|
+
coverage_file_1 = double(Slather::CoverageFile)
|
|
88
|
+
coverage_file_1.stub(:source_file_pathname).and_return("some/path/class1.m")
|
|
89
|
+
coverage_file_1.stub(:percentage_lines_tested).and_return(100)
|
|
90
|
+
|
|
91
|
+
coverage_file_2 = double(Slather::CoverageFile)
|
|
92
|
+
coverage_file_2.stub(:source_file_pathname).and_return("some/path/class2.m")
|
|
93
|
+
coverage_file_2.stub(:percentage_lines_tested).and_return(100)
|
|
94
|
+
|
|
95
|
+
coverage_file_2b = double(Slather::CoverageFile)
|
|
96
|
+
coverage_file_2b.stub(:source_file_pathname).and_return("some/path/class2.m")
|
|
97
|
+
coverage_file_2b.stub(:percentage_lines_tested).and_return(0)
|
|
98
|
+
|
|
99
|
+
coverage_files = [coverage_file_1, coverage_file_2, coverage_file_2b]
|
|
100
|
+
deduped_coverage_files = fixtures_project.send(:dedupe, coverage_files)
|
|
101
|
+
expect(deduped_coverage_files.size).to eq(2)
|
|
102
|
+
expect(deduped_coverage_files).to include(coverage_file_1)
|
|
103
|
+
expect(deduped_coverage_files).to include(coverage_file_2)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "#configure_from_yml" do
|
|
108
|
+
it "should configure all properties from the yml" do
|
|
109
|
+
unstubbed_project = Slather::Project.open(FIXTURES_PROJECT_PATH)
|
|
110
|
+
expect(unstubbed_project).to receive(:configure_build_directory_from_yml)
|
|
111
|
+
expect(unstubbed_project).to receive(:configure_source_directory_from_yml)
|
|
112
|
+
expect(unstubbed_project).to receive(:configure_ignore_list_from_yml)
|
|
113
|
+
expect(unstubbed_project).to receive(:configure_ci_service_from_yml)
|
|
114
|
+
expect(unstubbed_project).to receive(:configure_coverage_service_from_yml)
|
|
115
|
+
unstubbed_project.configure_from_yml
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "#configure_ignore_list_from_yml" do
|
|
120
|
+
it "should set the ignore_list if it has been provided in the yml and has not already been set" do
|
|
121
|
+
Slather::Project.stub(:yml).and_return({"ignore" => ["test", "ing"] })
|
|
122
|
+
fixtures_project.configure_ignore_list_from_yml
|
|
123
|
+
expect(fixtures_project.ignore_list).to eq(["test", "ing"])
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "should force the ignore_list into an array" do
|
|
127
|
+
Slather::Project.stub(:yml).and_return({"ignore" => "test" })
|
|
128
|
+
fixtures_project.configure_ignore_list_from_yml
|
|
129
|
+
expect(fixtures_project.ignore_list).to eq(["test"])
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "should not set the ignore_list if it has already been set" do
|
|
133
|
+
Slather::Project.stub(:yml).and_return({"ignore" => ["test", "ing"] })
|
|
134
|
+
fixtures_project.ignore_list = ["already", "set"]
|
|
135
|
+
fixtures_project.configure_ignore_list_from_yml
|
|
136
|
+
expect(fixtures_project.ignore_list).to eq(["already", "set"])
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "should default the ignore_list to an empty array if nothing is provided in the yml" do
|
|
140
|
+
Slather::Project.stub(:yml).and_return({})
|
|
141
|
+
fixtures_project.configure_ignore_list_from_yml
|
|
142
|
+
expect(fixtures_project.ignore_list).to eq([])
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
describe "#configure_build_directory_from_yml" do
|
|
147
|
+
it "should set the build_directory if it has been provided in the yml and has not already been set" do
|
|
148
|
+
Slather::Project.stub(:yml).and_return({"build_directory" => "/some/path"})
|
|
149
|
+
fixtures_project.configure_build_directory_from_yml
|
|
150
|
+
expect(fixtures_project.build_directory).to eq("/some/path")
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should not set the build_directory if it has already been set" do
|
|
154
|
+
Slather::Project.stub(:yml).and_return({"build_directory" => "/some/path"})
|
|
155
|
+
fixtures_project.build_directory = "/already/set"
|
|
156
|
+
fixtures_project.configure_build_directory_from_yml
|
|
157
|
+
expect(fixtures_project.build_directory).to eq("/already/set")
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it "should default the build_directory to derived data if nothing is provided in the yml" do
|
|
161
|
+
Slather::Project.stub(:yml).and_return({})
|
|
162
|
+
fixtures_project.configure_build_directory_from_yml
|
|
163
|
+
expect(fixtures_project.build_directory).to eq(fixtures_project.send(:derived_data_dir))
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
describe "#configure_source_directory_from_yml" do
|
|
168
|
+
it "should set the source_directory if it has been provided in the yml and has not already been set" do
|
|
169
|
+
Slather::Project.stub(:yml).and_return({"source_directory" => "/some/path"})
|
|
170
|
+
fixtures_project.configure_source_directory_from_yml
|
|
171
|
+
expect(fixtures_project.source_directory).to eq("/some/path")
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "should not set the source_directory if it has already been set" do
|
|
175
|
+
Slather::Project.stub(:yml).and_return({"source_directory" => "/some/path"})
|
|
176
|
+
fixtures_project.source_directory = "/already/set"
|
|
177
|
+
fixtures_project.configure_source_directory_from_yml
|
|
178
|
+
expect(fixtures_project.source_directory).to eq("/already/set")
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe "#configure_output_directory_from_yml" do
|
|
183
|
+
it "should set the output_directory if it has been provided in the yml and has not already been set" do
|
|
184
|
+
Slather::Project.stub(:yml).and_return({"output_directory" => "/some/path"})
|
|
185
|
+
fixtures_project.configure_output_directory_from_yml
|
|
186
|
+
expect(fixtures_project.output_directory).to eq("/some/path")
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "should not set the output_directory if it has already been set" do
|
|
190
|
+
Slather::Project.stub(:yml).and_return({"output_directory" => "/some/path"})
|
|
191
|
+
fixtures_project.output_directory = "/already/set"
|
|
192
|
+
fixtures_project.configure_output_directory_from_yml
|
|
193
|
+
expect(fixtures_project.output_directory).to eq("/already/set")
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
describe "#configure_ci_service_from_yml" do
|
|
198
|
+
it "should set the ci_service if it has been provided in the yml and has not already been set" do
|
|
199
|
+
Slather::Project.stub(:yml).and_return({"ci_service" => "some_service"})
|
|
200
|
+
fixtures_project.configure_ci_service_from_yml
|
|
201
|
+
expect(fixtures_project.ci_service).to eq(:some_service)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "should not set the ci_service if it has already been set" do
|
|
205
|
+
Slather::Project.stub(:yml).and_return({"ci_service" => "some service"})
|
|
206
|
+
fixtures_project.ci_service = "already_set"
|
|
207
|
+
fixtures_project.configure_ci_service_from_yml
|
|
208
|
+
expect(fixtures_project.ci_service).to eq(:already_set)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "should default the ci_service to :travis_ci if nothing is provided in the yml" do
|
|
212
|
+
Slather::Project.stub(:yml).and_return({})
|
|
213
|
+
fixtures_project.configure_ci_service_from_yml
|
|
214
|
+
expect(fixtures_project.ci_service).to eq(:travis_ci)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
describe "#ci_service=" do
|
|
219
|
+
it "should set the ci_service as a symbol" do
|
|
220
|
+
fixtures_project.ci_service = "foobar"
|
|
221
|
+
expect(fixtures_project.ci_service).to eq(:foobar)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
describe "#configure_coverage_service_from_yml" do
|
|
226
|
+
it "should set the coverage_service if it has been provided by the yml" do
|
|
227
|
+
Slather::Project.stub(:yml).and_return({"coverage_service" => "some_service"})
|
|
228
|
+
expect(fixtures_project).to receive(:coverage_service=).with("some_service")
|
|
229
|
+
fixtures_project.configure_coverage_service_from_yml
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it "should default the coverage_service to :terminal if nothing is provided in the yml" do
|
|
233
|
+
Slather::Project.stub(:yml).and_return({})
|
|
234
|
+
expect(fixtures_project).to receive(:coverage_service=).with(:terminal)
|
|
235
|
+
fixtures_project.configure_coverage_service_from_yml
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "should not set the coverage_service if it has already been set" do
|
|
239
|
+
Slather::Project.stub(:yml).and_return({"coverage_service" => "some_service" })
|
|
240
|
+
fixtures_project.stub(:coverage_service).and_return("already set")
|
|
241
|
+
expect(fixtures_project).to_not receive(:coverage_service=)
|
|
242
|
+
fixtures_project.configure_coverage_service_from_yml
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
describe "#configure_coverage_access_token" do
|
|
247
|
+
it "should set the coverage_access_token if it has been provided by the yml" do
|
|
248
|
+
Slather::Project.stub(:yml).and_return({"coverage_access_token" => "abc123"})
|
|
249
|
+
expect(fixtures_project).to receive(:coverage_access_token=).with("abc123")
|
|
250
|
+
fixtures_project.configure_coverage_access_token_from_yml
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it "should set the coverage_access_token if it is in the ENV" do
|
|
254
|
+
stub_const('ENV', ENV.to_hash.merge('COVERAGE_ACCESS_TOKEN' => 'asdf456'))
|
|
255
|
+
expect(fixtures_project).to receive(:coverage_access_token=).with("asdf456")
|
|
256
|
+
fixtures_project.configure_coverage_access_token_from_yml
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
describe "#coverage_service=" do
|
|
262
|
+
it "should extend Slather::CoverageService::Coveralls and set coverage_service = :coveralls if given coveralls" do
|
|
263
|
+
expect(fixtures_project).to receive(:extend).with(Slather::CoverageService::Coveralls)
|
|
264
|
+
fixtures_project.coverage_service = "coveralls"
|
|
265
|
+
expect(fixtures_project.coverage_service).to eq(:coveralls)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it "should extend Slather::CoverageService::SimpleOutput and set coverage_service = :terminal if given terminal" do
|
|
269
|
+
expect(fixtures_project).to receive(:extend).with(Slather::CoverageService::SimpleOutput)
|
|
270
|
+
fixtures_project.coverage_service = "terminal"
|
|
271
|
+
expect(fixtures_project.coverage_service).to eq(:terminal)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it "should raise an exception if it does not recognize the coverage service" do
|
|
275
|
+
expect { fixtures_project.coverage_service = "xcode bots, lol" }.to raise_error(StandardError)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
describe "#slather_setup_for_coverage" do
|
|
280
|
+
it "should enable the correct flags to generate test coverage on all of the build_configurations build settings" do
|
|
281
|
+
fixtures_project.slather_setup_for_coverage
|
|
282
|
+
fixtures_project.build_configurations.each do |build_configuration|
|
|
283
|
+
expect(build_configuration.build_settings["GCC_INSTRUMENT_PROGRAM_FLOW_ARCS"]).to eq("YES")
|
|
284
|
+
expect(build_configuration.build_settings["GCC_GENERATE_TEST_COVERAGE_FILES"]).to eq("YES")
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|