diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..aaabdf7 --- /dev/null +++ b/Gemfile @@ -0,0 +1,13 @@ +source 'https://rubygems.org' + +gemspec + +group :development do + gem "mocha", :require => false + # Use local copy of simplecov in development when checked out or fetch from git + if File.directory?(File.dirname(__FILE__) + '/../simplecov') + gem 'simplecov', :path => File.dirname(__FILE__) + '/../simplecov' + else + gem 'simplecov', :git => 'https://github.com/colszowka/simplecov' + end +end diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e9e9153 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2012 Vicent Llongo Silla + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 1f8b81b..97d0f66 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,52 @@ simplecov-json ============== -JSON formatter for the ruby 1.9+ coverage gem SimpleCov \ No newline at end of file +JSON formatter for the ruby 1.9+ coverage gem SimpleCov + +Usage +----- + +1. Add simplecov-json to your `Gemfile` and `bundle install`: + + gem 'simplecov-json', :require => false, :group => :test + +2. Require simplecov-json and set it up as SimpleCov's formatter: + + require 'simplecov-json' + SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter + +Result +------ + +Generated JSON can be found in coverage/coverage.json + +The format you can expect is: + + { + "timestamp": 1348489587, + "command_name": "RSpec", + "files": [ + { + "filename": "/home/user/rails/environment.rb", + "coverage": [ + null, + 1, + null, + null, + 1 + ] + }, + ... + ], + "groups": {}, + "metrics": { + "covered_percent": 81.70731707317073, + "covered_strength": 0.8170731707317073, + "covered_lines": 67, + "total_lines": 82 + } + } + +## Copyright + +Copyright (c) 2012 Vicent Llongo. See LICENSE for details. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..a86f1fb --- /dev/null +++ b/Rakefile @@ -0,0 +1,12 @@ +require 'bundler' +Bundler::GemHelper.install_tasks + +require 'rake/testtask' +Rake::TestTask.new(:test) do |test| + test.libs << 'lib' << 'test' + test.pattern = 'test/**/test_*.rb' + test.verbose = true +end + +task :default => :test + diff --git a/lib/simplecov-json.rb b/lib/simplecov-json.rb new file mode 100644 index 0000000..874be89 --- /dev/null +++ b/lib/simplecov-json.rb @@ -0,0 +1,49 @@ +require 'simplecov' +require 'json' + +class SimpleCov::Formatter::JSONFormatter + def format(result) + puts result.inspect + data = {} + data[:timestamp] = result.created_at.to_i + data[:command_name] = result.command_name + data[:files] = [] + result.original_result.each do |filename,coverage| + next unless result.filenames.include? filename + data[:files] << { + filename: filename, + coverage: coverage, + } + end + data[:groups] = result.groups + data[:metrics] = { + covered_percent: result.covered_percent, + covered_strength: result.covered_strength, + covered_lines: result.covered_lines, + total_lines: result.total_lines, + } + File.open(File.join(output_path, output_filename), "w+") do |file| + file.puts data.to_json + end + puts output_message(result) + data.to_json + end + + def output_filename + 'coverage.json' + end + + def output_filepath + File.join(output_path, output_filename) + end + + def output_message(result) + "Coverage report generated for #{result.command_name} to #{output_filepath}. #{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered." + end + + private + + def output_path + SimpleCov.coverage_path + end +end diff --git a/simplecov-json.gemspec b/simplecov-json.gemspec new file mode 100644 index 0000000..b779fb6 --- /dev/null +++ b/simplecov-json.gemspec @@ -0,0 +1,21 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) + +Gem::Specification.new do |s| + s.name = "simplecov-json" + s.version = '0.1.1' + s.platform = Gem::Platform::RUBY + s.authors = ["Vicent Llongo"] + s.email = ["villosil@gmail.com"] + s.homepage = "https://github.com/vicentllongo/simplecov-json" + s.summary = %Q{JSON formatter for SimpleCov code coverage tool for ruby 1.9+} + s.description = %Q{JSON formatter for SimpleCov code coverage tool for ruby 1.9+} + + s.rubyforge_project = "simplecov-json" + s.files = ['lib/simplecov-json.rb'] + s.test_files = ['test/helper', 'test/test_simplecov_json.rb'] + s.require_paths = ["lib"] + + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) +end diff --git a/test/helper.rb b/test/helper.rb new file mode 100644 index 0000000..df6ee5f --- /dev/null +++ b/test/helper.rb @@ -0,0 +1,10 @@ +require 'rubygems' +require 'bundler/setup' +require 'simplecov' +require 'simplecov-json' + +require 'test/unit' +require 'mocha' + +class Test::Unit::TestCase +end diff --git a/test/test_simplecov_json.rb b/test/test_simplecov_json.rb new file mode 100644 index 0000000..c39b77d --- /dev/null +++ b/test/test_simplecov_json.rb @@ -0,0 +1,46 @@ +require 'helper' + +class TestSimpleCovHtml < Test::Unit::TestCase + def test_format + formatter = SimpleCov::Formatter::JSONFormatter.new + result = mock() + created_at = DateTime.now.to_s + + result.expects(:created_at).returns(created_at) + result.expects(:command_name).returns('RSpec') + result.expects(:original_result).returns({ + '/lib/foo.rb' => [1, nil, 0, 0, nil, 1, nil], + '/lib/bar.rb' => [nil, 1, nil, 1, 1, 1, 0, 0, nil, 1, nil], + '/test/test.rb' => [nil, 1, 1, 1, 1] + }) + result.expects(:filenames).returns(['/lib/foo.rb', '/lib/bar.rb']) + result.expects(:filenames).returns(['/lib/foo.rb', '/lib/bar.rb']) + result.expects(:filenames).returns(['/lib/foo.rb', '/lib/bar.rb']) + result.expects(:groups).returns(['controllers', 'models']) + result.expects(:covered_percent).returns(73.33) + result.expects(:covered_strength).returns(0.87) + result.expects(:covered_lines).returns(11) + result.expects(:total_lines).returns(15) + + result.expects(:command_name).returns('RSpec') + result.expects(:covered_lines).returns(11) + result.expects(:total_lines).returns(15) + result.expects(:covered_percent).returns(73.33) + + assert_equal(formatter.format(result), { + 'timestamp' => created_at.to_i, + 'command_name' => 'RSpec', + 'files' => [ + {'filename' => '/lib/foo.rb', 'coverage' => [1, nil, 0, 0, nil, 1, nil]}, + {'filename' => '/lib/bar.rb', 'coverage' => [nil, 1, nil, 1, 1, 1, 0, 0, nil, 1, nil]}, + ], + 'groups' =>['controllers', 'models'], + 'metrics' => { + 'covered_percent' => 73.33, + 'covered_strength' => 0.87, + 'covered_lines' => 11, + 'total_lines' => 15, + } + }.to_json) + end +end