r19cov 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/COPYING ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2009 orepuri
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/ChangeLog ADDED
@@ -0,0 +1,3 @@
1
+ === 0.1 (2009-12-21)
2
+
3
+ * first release
data/README.rdoc ADDED
@@ -0,0 +1,15 @@
1
+ = R19Cov: Coverage Tool for Ruby 1.9
2
+
3
+ R19Cov is a simple coverage tool for Ruby 1.9.
4
+
5
+ * R19Cov supports only C0 Coverage.
6
+ * R19Cov works only with Ruby 1.9 because uses coverage library embedded in Ruby 1.9.
7
+
8
+ = Install
9
+
10
+ gem sources -a http://gemcutter.org/
11
+ gem install r19cov
12
+
13
+ = Usage
14
+
15
+ r19cov <ruby script>
data/Rakefile ADDED
@@ -0,0 +1,73 @@
1
+ # Rake file for R19Cov. -*-ruby-*-
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ require 'rake/gempackagetask'
5
+ require File.join(File.dirname(__FILE__), 'lib', 'r19cov')
6
+
7
+ spec = Gem::Specification.new do |s|
8
+ s.name = 'r19cov'
9
+ s.version = R19Cov::VERSION
10
+ s.description = 'Coverage Tool for Ruby 1.9'
11
+ s.date = Date.today
12
+ s.authors = ['orepuri']
13
+ s.email = 'orepuri@gmail.com'
14
+ s.homepage = 'http://github.com/orepuri'
15
+ s.require_paths = ['lib']
16
+ s.rubygems_version = Gem::VERSION
17
+ s.summary = <<-SUMMARY
18
+ R19Cov is a Coverage Tool for Ruby 1.9. It uses `coverage` library embeded in Ruby 1.9.
19
+ R19Cov analyzes source code coverage and report in HTML format.
20
+ SUMMARY
21
+ s.rubyforge_project = 'r19cov'
22
+ s.files = %w(COPYING ChangeLog README.rdoc Rakefile) + Dir["{lib,bin,spec}/**/*"]
23
+ s.bindir = 'bin'
24
+ s.executables << 'r19cov'
25
+ s.required_ruby_version = ">= 1.9"
26
+
27
+ s.add_development_dependency 'rspec', '1.2.9'
28
+ end
29
+
30
+
31
+ task :package
32
+ Rake::GemPackageTask.new(spec) do |p|
33
+ p.gem_spec = spec
34
+ end
35
+
36
+ begin
37
+ require 'spec/rake/spectask'
38
+
39
+ spec_opts = lambda do
40
+ lib_dir = File.join(File.dirname(__FILE__), 'lib')
41
+ ENV['RUBYLIB'] ? (ENV['RUBYLIB'] += ":#{lib_dir}") : (ENV['RUBYLIB'] = lib_dir)
42
+ File.read('spec/spec.opts').split("\n")
43
+ end
44
+
45
+ desc 'Run specs'
46
+ Spec::Rake::SpecTask.new('spec') do |t|
47
+ t.spec_files = Dir['spec/**/*_spec.rb']
48
+ t.spec_opts = spec_opts.call
49
+ end
50
+
51
+ namespace :spec do
52
+ desc 'Run specs with r19cov'
53
+ R19Cov::Rake::SpecTask.new do |t|
54
+ t.spec_files = Dir['spec/**/*_spec.rb']
55
+ t.spec_opts = spec_opts.call
56
+ t.spec_script = "spec"
57
+ t.rcov_opts = ['-x ruby-1.9.1,gems,spec']
58
+ t.rcov_dir = 'coverage'
59
+ end
60
+ end
61
+ rescue LoadError => e
62
+ STDERR.puts e
63
+ STDERR.puts "gem install rspec if needs to run specs"
64
+ end
65
+
66
+ desc 'clean unneccessary files'
67
+ task :clean do
68
+ (Dir['**/*~'] + Dir['**/*#']).each do |file|
69
+ cmd = "rm #{file}"
70
+ puts cmd
71
+ system cmd
72
+ end
73
+ end
data/bin/r19cov ADDED
@@ -0,0 +1,8 @@
1
+ #! /usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ lib_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $:.unshift lib_dir unless $:.include?(lib_dir)
6
+
7
+ require 'r19cov'
8
+ R19Cov::CLI.execute
data/lib/r19cov.rb ADDED
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ if RUBY_VERSION !~ /1\.9/
4
+ STDERR.puts 'R19Cov runs only Ruby 1.9'
5
+ exit(1)
6
+ end
7
+
8
+ $:.unshift File.dirname(__FILE__)
9
+
10
+ require 'coverage'
11
+
12
+ ::Coverage.start
13
+
14
+ module R19Cov
15
+ autoload :VERSION, 'r19cov/version'
16
+ autoload :Analyzer, 'r19cov/analyzer'
17
+ autoload :Coverage, 'r19cov/coverage'
18
+ autoload :OptionParser, 'r19cov/option_parser'
19
+ autoload :Options, 'r19cov/options'
20
+ autoload :ReportFactory, 'r19cov/report_factory'
21
+ autoload :CLI, 'r19cov/cli'
22
+
23
+ class Coverage
24
+ autoload :Summary, 'r19cov/coverage/summary'
25
+ end
26
+
27
+ module Report
28
+ autoload :HTML, 'r19cov/report/html'
29
+ class HTML
30
+ autoload :Page, 'r19cov/report/html/page'
31
+ autoload :DetailPage, 'r19cov/report/html/detail_page'
32
+ autoload :IndexPage, 'r19cov/report/html/index_page'
33
+ end
34
+ end
35
+
36
+ module Rake
37
+ autoload :SpecTask, 'r19cov/rake/spec_task'
38
+ end
39
+ end
@@ -0,0 +1,88 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module R19Cov
4
+ class Analyzer
5
+ def initialize(args)
6
+ parser = R19Cov::OptionParser.new
7
+ @options = parser.parse(args)
8
+ @report = R19Cov::ReportFactory.create(options)
9
+ end
10
+
11
+ attr_reader :options, :coverages
12
+
13
+ def analyze
14
+ @coverages = []
15
+ @@loaded_files ||= []
16
+ target_files = []
17
+
18
+ targets.each do |target|
19
+ target = Pathname.new(target).cleanpath.to_s
20
+ if File.directory?(target)
21
+ Dir["#{target}/**/*.rb"].each do |file|
22
+ target_files << file if File.file?(file) && !target_files.include?(file)
23
+ end
24
+ else
25
+ target_files << target unless target_files.include?(target)
26
+ end
27
+ end
28
+ target_files.each do |target_file|
29
+ if to_be_loaded?(target_file)
30
+ begin
31
+ load target_file
32
+ rescue Exception
33
+ # rescue exception in library and do nothing
34
+ end
35
+ @@loaded_files << target_file
36
+ end
37
+ end
38
+
39
+ add_result
40
+ @@result.each do |file, cov|
41
+ next if to_be_excluded?(file)
42
+ cov = @@result[File.expand_path(file)]
43
+ if cov
44
+ coverage = R19Cov::Coverage.new(file, cov)
45
+ @coverages << coverage
46
+ end
47
+ end
48
+ end
49
+
50
+ def add_result
51
+ @@result ||= {}
52
+ ::Coverage.result.each do |file, coverage|
53
+ coverage.each_with_index do |c, idx|
54
+ @@result[file] ||= []
55
+ if @@result[file][idx].nil?
56
+ @@result[file][idx] = c
57
+ else
58
+ @@result[file][idx] += c
59
+ end
60
+ end
61
+ end
62
+ ::Coverage.start
63
+ end
64
+
65
+ def to_be_loaded?(file)
66
+ !@@loaded_files.include?(file) && File.exist?(file)
67
+ end
68
+
69
+ def to_be_excluded?(file)
70
+ options.exclude.each do |e|
71
+ return true if file =~ /#{e}/
72
+ end
73
+ return false
74
+ end
75
+
76
+ def output_dir
77
+ options.output_dir
78
+ end
79
+
80
+ def output
81
+ @report.output(coverages)
82
+ end
83
+
84
+ def targets
85
+ options.targets
86
+ end
87
+ end
88
+ end
data/lib/r19cov/cli.rb ADDED
@@ -0,0 +1,9 @@
1
+ module R19Cov
2
+ class CLI
3
+ def self.execute(args = ARGV)
4
+ analyzer = Analyzer.new(args)
5
+ analyzer.analyze
6
+ analyzer.output
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module R19Cov
4
+ class Coverage
5
+ def initialize(source_file, result)
6
+ @filename = source_file
7
+ @result = result
8
+ load_source_file(source_file)
9
+ end
10
+
11
+ attr_accessor :filename, :lines, :result
12
+
13
+ def load_source_file(source_file)
14
+ @lines = File.read(source_file).split("\n")
15
+ end
16
+
17
+ def total_lines
18
+ lines.size
19
+ end
20
+
21
+ def lines_of_code
22
+ result.select{ |c| !c.nil? }.size
23
+ end
24
+
25
+ def total_coverage
26
+ total_lines > 0 ? (total_lines.to_f - uncovered.to_f) / total_lines.to_f : 0.0
27
+ end
28
+
29
+ def code_coverage
30
+ lines_of_code > 0 ? covered.to_f / lines_of_code.to_f : 0.0
31
+ end
32
+
33
+ def uncovered
34
+ result.select{ |c| c == 0 }.size
35
+ end
36
+
37
+ def covered
38
+ result.select{ |c| !c.nil? && c > 0 }.size
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module R19Cov
4
+ class Coverage
5
+ class Summary
6
+ def initialize(coverages)
7
+ @coverages = coverages
8
+ end
9
+
10
+ attr_reader :coverages, :code_coverage
11
+
12
+ def filename
13
+ 'index'
14
+ end
15
+
16
+ def total_lines
17
+ coverages.inject(0){ |t, c| t += c.total_lines }
18
+ end
19
+
20
+ def lines_of_code
21
+ coverages.inject(0){ |t, c| t += c.lines_of_code }
22
+ end
23
+
24
+ def total_coverage
25
+ total_lines > 0 ? (total_lines.to_f - uncovered.to_f) / total_lines.to_f : 0.0
26
+ end
27
+
28
+ def code_coverage
29
+ lines_of_code > 0 ? covered.to_f / lines_of_code.to_f : 0.0
30
+ end
31
+
32
+ def covered
33
+ coverages.inject(0){ |t, c| t += c.covered }
34
+ end
35
+
36
+ def uncovered
37
+ coverages.inject(0){ |t, c| t += c.uncovered }
38
+ end
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'optparse'
4
+
5
+ module R19Cov
6
+ class OptionParser
7
+ def initialize(out = STDOUT, err = STDERR)
8
+ @out = out
9
+ @err = err
10
+ end
11
+
12
+ attr_reader :options
13
+
14
+ def parse(args)
15
+ @options = Options.new
16
+ if (idx = args.index('--'))
17
+ extra_args = args[idx + 1 .. -1]
18
+ args = args[0, idx].dup
19
+ else
20
+ extra_args = []
21
+ args = args.dup
22
+ end
23
+ @options.raw_options = args.dup
24
+ args = ['--help'] if args.empty?
25
+ ::OptionParser.new { |opt|
26
+ opt.banner = "Usage: r19cov [options] (FILE|DIRECTORY)+ [-- --extra-options]"
27
+ opt.on('-h', '--help', 'Show help messages') { @out.puts opt }
28
+ opt.on('-o', '--output [OUTPUT_DIR]', 'Specifies output directory of coverage report') {
29
+ |v| @options.output_dir = v
30
+ }
31
+ opt.on('-x', '--exclude [PATTERNS]', 'Don\'t generate info for files matching a pattern',
32
+ '(comma-separated regexp list)') { |v| @options.exclude = v.split(/,/) }
33
+ opt.on('-v', '--version', 'Show version') { @out.puts "r19cov #{R19Cov::VERSION}" }
34
+ opt.parse!(args)
35
+ }
36
+ @options.targets = args
37
+ @options.raw_options -= @options.targets
38
+ ARGV.replace extra_args
39
+ @options
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'pathname'
4
+
5
+ module R19Cov
6
+ class Options
7
+ def initialize
8
+ @exclude = []
9
+ @output_dir = default_output_dir
10
+ @report = default_report
11
+ end
12
+
13
+ attr_accessor :targets, :raw_options, :exclude, :output_dir, :report
14
+
15
+ private
16
+ def default_output_dir
17
+ Pathname.new(File.join(Dir.pwd, 'coverage')).cleanpath.to_s
18
+ end
19
+
20
+ def default_report
21
+ :html
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,66 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # Define a task library for running spec with R19Cov
4
+
5
+ require 'spec/rake/spectask'
6
+
7
+ module R19Cov
8
+ module Rake
9
+
10
+ # A Rake task that runs coverage.
11
+ #
12
+ # Example:
13
+ #
14
+ # R19Cov::Rake::Task.new do |t|
15
+ # end
16
+ #
17
+ # This will create a task that can be run with:
18
+ #
19
+ # rake r19cov
20
+ #
21
+ class SpecTask < ::Spec::Rake::SpecTask
22
+ def initialize(name = :r19cov)
23
+ super
24
+ end
25
+ attr_accessor :spec_script
26
+
27
+ def define # :nodoc:
28
+ rcov = true
29
+ lib_path = libs.join(File::PATH_SEPARATOR)
30
+ task name do
31
+ RakeFileUtils.verbose(verbose) do
32
+ unless spec_file_list.empty?
33
+ # ruby [ruby_opts] -Ilib -S r19cov [r19cov_opts] bin/spec -- examples [spec_opts]
34
+ cmd_parts = [ruby_cmd || RUBY]
35
+ cmd_parts += ruby_opts
36
+ cmd_parts << %[-I"#{lib_path}"]
37
+ cmd_parts << "-S r19cov"
38
+ cmd_parts << "-w" if warning
39
+ cmd_parts << rcov_option_list if rcov
40
+ cmd_parts << %[-o "#{rcov_dir}"] if rcov
41
+ cmd_parts << %["#{spec_script}"]
42
+ cmd_parts << "--"
43
+ cmd_parts += spec_file_list.collect { |fn| %["#{fn}"] }
44
+ cmd_parts << spec_option_list
45
+ if out
46
+ cmd_parts << %[> "#{out}"]
47
+ STDERR.puts "The Spec::Rake::SpecTask#out attribute is DEPRECATED and will be removed in a future version. Use --format FORMAT:WHERE instead."
48
+ end
49
+ cmd = cmd_parts.join(" ")
50
+ puts cmd if verbose
51
+ unless system(cmd)
52
+ STDERR.puts failure_message if failure_message
53
+ raise("Command #{cmd} failed") if fail_on_error
54
+ end
55
+ end
56
+ end
57
+ end
58
+ self
59
+ end
60
+
61
+ def rcov_option_list # :nodoc:
62
+ ENV['RCOV_OPTS'] || rcov_opts.join(" ") || ""
63
+ end
64
+ end
65
+ end
66
+ end