Skip to content

Commit 638693e

Browse files
committed
Merge pull request #24 from neonichu/gutter-json
Added GutterJsonOutput as a coverage service.
2 parents 0a077b6 + 3f02ecd commit 638693e

File tree

7 files changed

+89
-0
lines changed

7 files changed

+89
-0
lines changed

bin/slather

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Clamp do
1515

1616
option ["--coveralls", "-c"], :flag, "Post coverage results to coveralls"
1717
option ["--simple-output", "-s"], :flag, "Output coverage results to the terminal"
18+
option ["--gutter-json", "-g"], :flag, "Output coverage results as Gutter JSON format"
1819

1920
option ["--build-directory", "-b"], "BUILD_DIRECTORY", "The directory where gcno files will be written to. Defaults to derived data."
2021
option ["--source-directory"], "SOURCE_DIRECTORY", "The directory where your source files are located."
@@ -72,6 +73,8 @@ Clamp do
7273
project.coverage_service = :coveralls
7374
elsif simple_output?
7475
project.coverage_service = :terminal
76+
elsif gutter_json?
77+
project.coverage_service = :gutter_json
7578
end
7679
end
7780

lib/slather.rb

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'slather/coverage_file'
44
require 'slather/coveralls_coverage_file'
55
require 'slather/coverage_service/coveralls'
6+
require 'slather/coverage_service/gutter_json_output'
67
require 'slather/coverage_service/simple_output'
78

89
module Slather
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module Slather
2+
module CoverageService
3+
module GutterJsonOutput
4+
5+
def coverage_file_class
6+
Slather::CoverageFile
7+
end
8+
private :coverage_file_class
9+
10+
def post
11+
output = { 'meta' => { 'timestamp' => DateTime.now.strftime('%Y-%m-%d %H:%M:%S.%6N') } }
12+
symbols = {}
13+
14+
coverage_files.each do |coverage_file|
15+
next unless coverage_file.gcov_data
16+
17+
filename = coverage_file.source_file_pathname.to_s
18+
filename = filename.sub(Pathname.pwd.to_s, '')[1..-1]
19+
20+
coverage_file.gcov_data.split("\n").each do |line|
21+
data = line.split(':')
22+
23+
line_number = data[1].to_i
24+
next unless line_number > 0
25+
26+
coverage = data[0].strip
27+
28+
symbol = { 'line' => line_number,
29+
'long_text' => '',
30+
'short_text' => coverage }
31+
32+
if coverage != '-'
33+
symbol['background_color'] = coverage.to_i > 0 ? '0x35CC4B' : '0xFC635E'
34+
end
35+
36+
if symbols.has_key?(filename)
37+
symbols[filename] << symbol
38+
else
39+
symbols[filename] = [ symbol ]
40+
end
41+
end
42+
end
43+
44+
output['symbols_by_file'] = symbols
45+
File.open('.gutter.json', 'w') { |file| file.write(output.to_json) }
46+
end
47+
48+
end
49+
end
50+
end

lib/slather/project.rb

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ def coverage_service=(service)
104104
extend(Slather::CoverageService::Coveralls)
105105
elsif service == :terminal
106106
extend(Slather::CoverageService::SimpleOutput)
107+
elsif service == :gutter_json
108+
extend(Slather::CoverageService::GutterJsonOutput)
107109
else
108110
raise ArgumentError, "`#{coverage_service}` is not a valid coverage service. Try `terminal` or `coveralls`"
109111
end

spec/fixtures/gutter.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"meta":{"timestamp":"2014-09-19 11:21:36.112110"},"symbols_by_file":{"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/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":"-"}]}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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 = JSON.parse(File.read(FIXTURES_JSON_PATH))
22+
fixture_json['meta']['timestamp'] = ''
23+
24+
current_json = JSON.parse(File.read('.gutter.json'))
25+
current_json['meta']['timestamp'] = ''
26+
27+
expect(current_json).to eq(fixture_json)
28+
File.unlink('.gutter.json')
29+
end
30+
end
31+
end

spec/spec_helper.rb

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
Coveralls.wear!
99

10+
FIXTURES_JSON_PATH = File.join(File.dirname(__FILE__), 'fixtures/gutter.json')
1011
FIXTURES_PROJECT_PATH = File.join(File.dirname(__FILE__), 'fixtures/fixtures.xcodeproj')
1112

1213
RSpec.configure do |config|

0 commit comments

Comments
 (0)