coco 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTORS +9 -0
  3. data/Changelog.markdown +42 -0
  4. data/Gemfile.lock +36 -55
  5. data/LICENSE +7 -0
  6. data/README.markdown +124 -73
  7. data/Rakefile +10 -37
  8. data/VERSION +1 -1
  9. data/lib/coco.rb +9 -21
  10. data/lib/coco/configuration.rb +59 -20
  11. data/lib/coco/cover.rb +1 -0
  12. data/lib/coco/cover/coverage_result.rb +72 -16
  13. data/lib/coco/cover/coverage_stat.rb +20 -8
  14. data/lib/coco/cover/summary.rb +50 -0
  15. data/lib/coco/deprecated_message.rb +31 -0
  16. data/lib/coco/formatter.rb +2 -2
  17. data/lib/coco/formatter/colored_string.rb +1 -1
  18. data/lib/coco/formatter/console_formatter.rb +24 -19
  19. data/lib/coco/formatter/context.rb +10 -39
  20. data/lib/coco/formatter/html_formatter.rb +7 -13
  21. data/lib/coco/formatter/html_index_formatter.rb +20 -16
  22. data/lib/coco/formatter/index_context.rb +37 -0
  23. data/lib/coco/formatter/index_line.rb +21 -0
  24. data/lib/coco/formatter/template.rb +2 -3
  25. data/lib/coco/helpers.rb +88 -68
  26. data/lib/coco/lister/source_lister.rb +23 -26
  27. data/lib/coco/lister/uncovered_lister.rb +6 -9
  28. data/lib/coco/project.rb +65 -0
  29. data/lib/coco/theme.rb +15 -0
  30. data/lib/coco/writer/file_writer.rb +5 -5
  31. data/lib/coco/writer/html_directory.rb +16 -8
  32. data/lib/coco/writer/html_files_writer.rb +9 -6
  33. data/lib/coco/writer/html_index_writer.rb +6 -3
  34. data/template/css/dark.css +178 -0
  35. data/template/css/{coco.css → light.css} +22 -9
  36. data/template/file.erb +3 -3
  37. data/template/index.erb +35 -33
  38. data/template/js/coco.js +18 -0
  39. metadata +34 -58
  40. data/COPYING +0 -674
  41. data/lib/coco/formatter/formatter.rb +0 -23
  42. data/template/img/coconut16.png +0 -0
  43. data/template/img/licenses +0 -19
@@ -0,0 +1,31 @@
1
+ module Coco
2
+
3
+ # Group all messages for deprecated things in this module.
4
+ #
5
+ module DeprecatedMessage
6
+
7
+ def self.for_excludes
8
+ "Please change `excludes` to `exclude`.\n" \
9
+ 'Support for `excludes` configuration key will ' \
10
+ 'be removed in future Coco versions.'
11
+ end
12
+
13
+ def self.for_directories
14
+ "Please change `directories` to `include`.\n" \
15
+ 'Support for `directories` configuration key will ' \
16
+ 'be removed in future Coco versions.'
17
+ end
18
+
19
+ def self.for_threeshold
20
+ "Please change `threeshold` to `threshold`.\n" \
21
+ 'Support for the misspelt `threeshold` configuration key will ' \
22
+ 'be removed in future Coco versions.'
23
+ end
24
+
25
+ def self.for_legacy_config_file
26
+ "Please use `.coco.yml` instead of `.coco`.\n" \
27
+ 'Support for `.coco` will be removed in future versions.'
28
+ end
29
+
30
+ end
31
+ end
@@ -1,9 +1,9 @@
1
- require 'coco/formatter/formatter'
2
-
3
1
  require 'coco/formatter/console_formatter'
4
2
  require 'coco/formatter/context'
3
+ require 'coco/formatter/index_context'
5
4
 
6
5
  require 'coco/formatter/html_formatter'
7
6
  require 'coco/formatter/html_index_formatter'
8
7
  require 'coco/formatter/template'
9
8
  require 'coco/formatter/colored_string'
9
+ require 'coco/formatter/index_line'
@@ -7,7 +7,7 @@ module Coco
7
7
  # Public: Initialize a new ColoredString object.
8
8
  #
9
9
  # str - A String.
10
- def initialize(str="")
10
+ def initialize(str = '')
11
11
  super(str)
12
12
  end
13
13
 
@@ -1,24 +1,25 @@
1
1
  module Coco
2
2
 
3
3
  # I format coverages data for console output.
4
- class ConsoleFormatter < Formatter
4
+ #
5
+ class ConsoleFormatter
5
6
 
6
7
  # Public: Get a colored report, formatted for console output.
7
8
  #
8
- # single_line_report - Boolean
9
- #
10
9
  # Returns percent covered and associated filenames as a multilines
11
- # String
12
- def format(single_line_report = false)
13
- single_line_report ? single_line_message : @formatted_output.join("\n")
10
+ # or a single line String.
11
+ #
12
+ def format
13
+ @config[:single_line_report] ? single_line_message : multilines_message
14
14
  end
15
15
 
16
16
  # Get the link for the report's index file.
17
17
  #
18
18
  # Returns String.
19
+ #
19
20
  def link
20
21
  unless @formatted_output.empty?
21
- "See file://" +
22
+ 'See file://' +
22
23
  File.expand_path(File.join(Coco::HtmlDirectory.new.coverage_dir,
23
24
  'index.html'))
24
25
  end
@@ -26,11 +27,15 @@ module Coco
26
27
 
27
28
  # Public: Creates a new ConsoleFormatter.
28
29
  #
29
- # covered - See base class Formatter.
30
- # uncovered - See base class Formatter.
30
+ # uncovered - An Array list of uncovered files.
31
31
  # threshold - The Fixnum percentage threshold.
32
- def initialize(covered, uncovered, threshold)
33
- super(covered, uncovered)
32
+ # result - A CoverageResult.
33
+ # config - A Configuration.
34
+ #
35
+ def initialize(uncovered, threshold, result, config)
36
+ @uncovered = uncovered
37
+ @result = result
38
+
34
39
  @formatted_output = []
35
40
  compute_percentage
36
41
  add_percentage_to_uncovered
@@ -45,29 +50,29 @@ module Coco
45
50
  text.yellow
46
51
  end
47
52
  end
53
+ @summary = Summary.new(result, uncovered)
54
+ @config = config
48
55
  end
49
56
 
50
57
  private
51
58
 
52
59
  def compute_percentage
53
- @raw_coverages.each do |filename, coverage|
60
+ @result.not_covered_enough.each do |filename, coverage|
54
61
  percentage = CoverageStat.coverage_percent(coverage)
55
62
  @formatted_output << [percentage, filename]
56
63
  end
57
64
  end
58
65
 
59
66
  def add_percentage_to_uncovered
60
- @uncovered.each {|filename| @formatted_output << [0, filename] }
67
+ @uncovered.each { |filename| @formatted_output << [0, filename] }
61
68
  end
62
69
 
63
70
  def single_line_message
64
- if @uncovered.empty?
65
- ""
66
- else
67
- ColoredString.new("Some files are uncovered").yellow
68
- end
71
+ ColoredString.new(@summary.to_s).yellow
69
72
  end
70
73
 
74
+ def multilines_message
75
+ @formatted_output.join("\n") + "\n" + @summary.to_s + "\n"
76
+ end
71
77
  end
72
-
73
78
  end
@@ -1,6 +1,7 @@
1
1
  module Coco
2
2
 
3
3
  # Contextual information for ERB template, representing each covered files.
4
+ #
4
5
  class Context
5
6
 
6
7
  # Public: Initialize a Context for a covered file shown in the HTML
@@ -8,48 +9,18 @@ module Coco
8
9
  #
9
10
  # filename - A String name of the source file.
10
11
  # lines - An Array of lines.
11
- def initialize(filename, lines)
12
- @filename = filename
13
- @lines = lines
14
- end
15
-
16
- # Public: Get the object's binding.
17
12
  #
18
- # Returns Binding.
19
- def get_binding
20
- binding
21
- end
22
- end
23
-
24
- # Contextual information for ERB template, representing index.html.
25
- class IndexContext
13
+ def initialize(filename, lines)
14
+ @filename = filename
15
+ @lines = lines
16
+ end
26
17
 
27
- # Public: Initialize an IndexContext for the index file in the HTML
28
- # report.
29
- #
30
- # title - The String title for the report.
31
- # covered - Array of subarrays. Each subarray is:
32
- # [
33
- # Fixnum coverage percentage,
34
- # String formatted filename (HTML ready),
35
- # String real filename
36
- # ]
37
- # FIXME Need a class to handle subarrays.
38
- # uncovered - Array of String filenames. The filenames are already
39
- # formatted, ready to be display in an HTML file.
40
- #
41
- def initialize(title, covered, uncovered)
42
- @title = title
43
- @covered = covered
44
- @uncovered = uncovered
45
- end
46
-
47
18
  # Public: Get the object's binding.
48
19
  #
49
20
  # Returns Binding.
50
- def get_binding
51
- binding
52
- end
53
- end
54
-
21
+ #
22
+ def variables
23
+ binding
24
+ end
25
+ end
55
26
  end
@@ -3,12 +3,12 @@ require 'erb'
3
3
 
4
4
  module Coco
5
5
 
6
- # I format coverages information into html files.
7
- # @todo document and change name to HtmlFilesFormatter
8
- class HtmlFormatter < Formatter
6
+ # I format coverage's data into html files.
7
+ #
8
+ class HtmlFormatter
9
9
 
10
10
  def initialize(raw_coverages)
11
- super(raw_coverages, [])
11
+ @raw_coverages = raw_coverages
12
12
  @formatted_output_files = {}
13
13
  @context = nil
14
14
  @template = Template.open(File.join(Coco::ROOT, 'template/file.erb'))
@@ -25,17 +25,11 @@ module Coco
25
25
 
26
26
  def build_html(filename, coverage)
27
27
  lines = []
28
- source(filename).each_with_index do |line, index|
29
- lines << [index+1, CGI.escapeHTML(line.chomp), coverage[index]]
28
+ File.readlines(filename).each_with_index do |line, index|
29
+ lines << [index + 1, CGI.escapeHTML(line.chomp), coverage[index]]
30
30
  end
31
31
  @context = Context.new(Helpers.name_for_html(filename), lines)
32
- @formatted_output_files[filename] = @template.result(@context.get_binding)
32
+ @formatted_output_files[filename] = @template.result(@context.variables)
33
33
  end
34
-
35
- def source(filename)
36
- File.readlines(filename)
37
- end
38
-
39
34
  end
40
-
41
35
  end
@@ -3,10 +3,18 @@ require 'erb'
3
3
  module Coco
4
4
 
5
5
  # I format the index.html
6
- class HtmlIndexFormatter < Formatter
7
-
8
- def initialize(raw_coverages, uncovered)
9
- super
6
+ #
7
+ class HtmlIndexFormatter
8
+
9
+ # uncovered - An Array list of uncovered files.
10
+ # result - CoverageResult.
11
+ # threshold - Fixnum.
12
+ #
13
+ def initialize(uncovered, result, threshold = 100)
14
+ @uncovered = uncovered
15
+ @result = result
16
+ @threshold = threshold
17
+ @summary = Summary.new(result, uncovered)
10
18
  @context = nil
11
19
  @template = Template.open(File.join(Coco::ROOT, 'template/index.erb'))
12
20
  @lines = []
@@ -14,26 +22,22 @@ module Coco
14
22
  end
15
23
 
16
24
  def format
17
- @context = IndexContext.new(
18
- Helpers.index_title,
19
- @lines,
20
- @uncovered.map {|filename| Helpers.name_for_html(filename) })
21
- @template.result(@context.get_binding)
25
+ @context = IndexContext.new(Helpers.index_title, @lines, uncovered_files,
26
+ @summary, @threshold)
27
+ @template.result(@context.variables)
22
28
  end
23
29
 
24
30
  private
25
31
 
26
32
  def build_lines_for_context
27
- @raw_coverages.each do |filename, coverage|
28
- @lines << [
29
- CoverageStat.coverage_percent(coverage),
30
- Helpers.name_for_html(filename),
31
- Helpers.rb2html(filename)
32
- ]
33
+ @result.coverable_files.to_a.each do |filename, coverage|
34
+ @lines << IndexLine.build(filename, coverage)
33
35
  end
34
36
  @lines.sort!
35
37
  end
36
38
 
39
+ def uncovered_files
40
+ @uncovered.map { |filename| Helpers.name_for_html(filename) }
41
+ end
37
42
  end
38
-
39
43
  end
@@ -0,0 +1,37 @@
1
+ module Coco
2
+
3
+ # Contextual information for ERB template, representing index.html.
4
+ #
5
+ class IndexContext
6
+
7
+ # Public: Initialize an IndexContext for the index file in the HTML
8
+ # report.
9
+ #
10
+ # title - The String title for the report.
11
+ # all - Array of subarrays. Each subarray is:
12
+ # [
13
+ # Fixnum coverage percentage,
14
+ # String formatted filename (HTML ready),
15
+ # String real filename
16
+ # ]
17
+ # uncovered - Array of String filenames. The filenames are already
18
+ # formatted, ready to be display in an HTML file.
19
+ # summary - A Summary object.
20
+ # threshold - Fixnum.
21
+ #
22
+ def initialize(title, all, uncovered, summary, threshold)
23
+ @title = title
24
+ @covered, @greens = all.partition { |file| file.first < threshold }
25
+ @uncovered = uncovered
26
+ @summary = summary
27
+ end
28
+
29
+ # Public: Get the object's binding.
30
+ #
31
+ # Returns Binding.
32
+ #
33
+ def variables
34
+ binding
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ module Coco
2
+
3
+ # Assembles data required to represent a line on the index HTML
4
+ # report.
5
+ #
6
+ module IndexLine
7
+
8
+ # filename - The absolute String filename.
9
+ # coverage - An Array of hit.
10
+ #
11
+ # Returns an Array.
12
+ #
13
+ def self.build(filename, coverage)
14
+ [
15
+ CoverageStat.coverage_percent(coverage),
16
+ Helpers.name_for_html(filename),
17
+ Helpers.rb2html(filename),
18
+ ]
19
+ end
20
+ end
21
+ end
@@ -1,7 +1,7 @@
1
1
  require 'erb'
2
2
 
3
3
  module Coco
4
-
4
+
5
5
  # From me, you can obtain ERB templates.
6
6
  class Template
7
7
  # filename - An String ERB template.
@@ -9,8 +9,7 @@ module Coco
9
9
  # Returns ERB.
10
10
  def self.open(filename)
11
11
  io = IO.readlines(filename, nil)
12
- ERB.new(io[0], nil, '><')
12
+ ERB.new(io[0], nil, '><')
13
13
  end
14
14
  end
15
-
16
15
  end
@@ -2,81 +2,101 @@ module Coco
2
2
 
3
3
  # Public: Collection of application's helpers methods.
4
4
  #
5
- # TODO The app is full of `Dir.pwd`. This is the root project
6
- # directory and must be in Configuration class (or Coco module ?).
7
5
  module Helpers
8
- class << self
9
6
 
10
- # Public: Get a String (ruby) source filename ready to be
11
- # displayed in the index file.
12
- #
13
- # name - String full path filename (normaly full path but, who
14
- # knows? may be relative path).
15
- #
16
- # Examples
17
- #
18
- # name = '/home/user/my_project/lib/source.rb'
19
- # Helpers.name_for_html(name)
20
- # #=> 'lib/<b>source.rb</b>'
21
- #
22
- # Returns the formatted String.
23
- def name_for_html(name)
24
- name = File.expand_path(name)
25
- name = name.sub(Dir.pwd, '')
26
- name = name.sub(/^\//, '')
27
- base = File.basename(name)
28
- name.sub(base, "<b>#{base}</b>")
29
- end
7
+ # Public: Get a String (ruby) source filename ready to be
8
+ # displayed in the index file.
9
+ #
10
+ # name - String full path filename (normaly full path but, who
11
+ # knows? may be relative path).
12
+ #
13
+ # Examples
14
+ #
15
+ # name = '/home/user/my_project/lib/source.rb'
16
+ # Helpers.name_for_html(name)
17
+ # #=> 'lib/<b>source.rb</b>'
18
+ #
19
+ # Returns the formatted String.
20
+ #
21
+ def self.name_for_html(name)
22
+ name = File.expand_path(name)
23
+ name = name.sub(Dir.pwd, '')
24
+ name = name.sub(%r{^/}, '')
25
+ base = File.basename(name)
26
+ name.sub(base, "<b>#{base}</b>")
27
+ end
30
28
 
31
- # Public: Get html filename (from a ruby filename) suitable for
32
- # the coverage directory.
33
- #
34
- # name - String full path filename.
35
- #
36
- # Examples
37
- #
38
- # ruby = '/home/user/my_project/lib/source.rb'
39
- # html = Helpers.rb2html(ruby)
40
- # #=> '_lib_source.rb.html'
41
- #
42
- # Returns String HTML filename.
43
- def rb2html(name)
44
- name = name.sub(Dir.pwd, '')
45
- name = name.sub(/^\//, '')
46
- name = name.tr('/\\', '_')
47
- name + '.html'
48
- end
29
+ # Public: Get html filename (from a ruby filename) suitable for
30
+ # the coverage directory.
31
+ #
32
+ # name - String full path filename.
33
+ #
34
+ # Examples
35
+ #
36
+ # ruby = '/home/user/my_project/lib/source.rb'
37
+ # html = Helpers.rb2html(ruby)
38
+ # #=> '_lib_source.rb.html'
39
+ #
40
+ # Returns String HTML filename.
41
+ #
42
+ def self.rb2html(name)
43
+ name = name.sub(Dir.pwd, '')
44
+ name = name.sub(%r{^/}, '')
45
+ name = name.tr('/\\', '_')
46
+ name + '.html'
47
+ end
49
48
 
50
- # Public: Get page title for the index.html file.
51
- #
52
- # Returns String.
53
- def index_title
54
- project_name = File.basename(Dir.pwd)
55
- version = File.read(File.join(Coco::ROOT, 'VERSION')).strip
56
- "#{project_name} - Code coverage (coco #{version})"
57
- end
49
+ # Public: Get page title for the index.html file.
50
+ #
51
+ # Returns String.
52
+ #
53
+ def self.index_title
54
+ project_name = File.basename(Dir.pwd)
55
+ version = File.read(File.join(Coco::ROOT, 'VERSION')).strip
56
+ "#{project_name} - Code coverage (coco #{version})"
57
+ end
58
58
 
59
- # Public: Expands a bulk of filenames into full path filenames.
60
- #
61
- # files - List of filenames as an Array of String.
62
- #
63
- # Returns an Array of String.
64
- def expand(files)
65
- files.map {|file| File.expand_path(file) }
66
- end
59
+ # Public: Expands a bulk of filenames into full path filenames.
60
+ #
61
+ # files - List of filenames as an Array of String.
62
+ #
63
+ # Returns an Array of String.
64
+ #
65
+ def self.expand(files)
66
+ files.map { |file| File.expand_path(file) }
67
+ end
67
68
 
68
- # Public: Get all ruby files from a directory, including
69
- # sub-directories.
70
- #
71
- # directory - String directory to look into.
72
- #
73
- # Returns an Array of String.
74
- def rb_files_from(directory)
75
- rb_files = File.join(directory, "**", "*.rb")
76
- Dir.glob(rb_files)
77
- end
69
+ # Public: Get all ruby files from a directory, including
70
+ # sub-directories.
71
+ #
72
+ # directory - String directory to look into.
73
+ #
74
+ # Returns an Array of String.
75
+ #
76
+ def self.rb_files_from(directory)
77
+ rb_files = File.join(directory, '**', '*.rb')
78
+ Dir.glob(rb_files)
78
79
  end
79
80
 
81
+ # Public: Get the CSS class given a percentage. To use in the
82
+ # index file.
83
+ #
84
+ # percentage - A Fixnum.
85
+ #
86
+ # Examples
87
+ #
88
+ # Helpers.level_class(100)
89
+ # #=> 'green'
90
+ #
91
+ # Returns the String CSS class name.
92
+ #
93
+ def self.level_class(percentage)
94
+ case percentage
95
+ when 100 then 'green'
96
+ when 80..99 then 'yellow'
97
+ else
98
+ 'red'
99
+ end
100
+ end
80
101
  end
81
-
82
102
  end