minitest-cc 0.1.0.beta

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9b4e3b7affdd0bac184df62e862738f07e4fd11b5d688a73fa6215dd9d7ec287
4
+ data.tar.gz: 99fd07e500ec5fb9ad6e3b7887c1189046ff83bbcb4785af1630d7952bc48c9c
5
+ SHA512:
6
+ metadata.gz: aec3e0e03446768f11a22f0abebf255d1e05d2a134e8e2a627d2afae726852a2eb0fa74715ab6a5457c6b9e555d9a98b08777e783bee92a1874517f1a67dd4fd
7
+ data.tar.gz: 695f37256eef625dddf8a97d51aa32294c4c7352a07ef2c1855aee4a07409f024dfa380ecad493e81688bbbde2071ea76962f1edf9300e20dd325833996be1f6
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Minitest
4
+ module Cc
5
+ # model for a file
6
+ class FileArray < Array
7
+ ##
8
+ # Calculate the lines average of the self array
9
+ # @return [Integer] percent of lines executed
10
+ def lines_average
11
+ lines = reduce(0) { |sum, v| sum + v.lines.to_i }
12
+ lines_executed = reduce(0) { |sum, v| sum + v.lines_executed.to_i }
13
+ lines_executed * 100 / lines
14
+ rescue ZeroDivisionError
15
+ 0
16
+ end
17
+
18
+ ##
19
+ # Calculate the branches average of the self array
20
+ # @return [Integer] percent of branches executed
21
+ def branches_average
22
+ branches = reduce(0) { |sum, v| sum + v.branches.to_i }
23
+ branches_executed = reduce(0) { |sum, v| sum + v.branches_executed.to_i }
24
+ branches_executed * 100 / branches
25
+ rescue ZeroDivisionError
26
+ 0
27
+ end
28
+
29
+ ##
30
+ # Calculate the methods average of the self array
31
+ # @return [Integer] percent of methods executed
32
+ def methods_average
33
+ methods = reduce(0) { |sum, v| sum + v.methods.to_i }
34
+ methods_executed = reduce(0) { |sum, v| sum + v.methods_executed.to_i }
35
+ methods_executed * 100 / methods
36
+ rescue ZeroDivisionError
37
+ 0
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Minitest
4
+ module Cc
5
+ # model for a file
6
+ class FileCoverage
7
+ # @return [String] the name of the file with extension
8
+ attr_accessor :name
9
+ # @return [String] the absolute path to the file
10
+ attr_accessor :path
11
+ # @return [String] the relative path to the file
12
+ attr_accessor :relative_path
13
+ # @return [Boolean] if this was tested or not.
14
+ # this indicate if the file was tracked by coverage or not
15
+ attr_accessor :tested
16
+ # @return [Integer] total lines of the file
17
+ attr_accessor :lines
18
+ # @return [Integer] total lines executed of the file
19
+ attr_accessor :lines_executed
20
+ # @return [Integer] total branches of the file
21
+ attr_accessor :branches
22
+ # @return [Integer] total branches executed of the file
23
+ attr_accessor :branches_executed
24
+ # @return [Integer] total methods of the file
25
+ attr_accessor :methods
26
+ # @return [Integer] total methods executed of the file
27
+ attr_accessor :methods_executed
28
+
29
+ ##
30
+ # Initialize an instance of FileCoverage
31
+ # @param path [String] full path to the file
32
+ # @param relative_path [String] relative path to the file
33
+ # @param result [Hash] object with the result of the coverage for the file
34
+ def initialize(path, relative_path, result = nil)
35
+ @path = path
36
+ @relative_path = relative_path
37
+ @name = File.basename(path)
38
+ @tested = !result.nil?
39
+ from_result(result) unless result.nil?
40
+ end
41
+
42
+ ##
43
+ # Set the results of the coverage into the object variables
44
+ # @param result [Hash] object with the result of the coverage
45
+ def from_result(result)
46
+ @lines, @lines_executed = count_lines(result) unless result[:lines].nil?
47
+ @branches, @branches_executed = count_branches(result) unless result[:branches].nil?
48
+ @methods, @methods_executed = count_methods(result) unless result[:methods].nil?
49
+ end
50
+
51
+ ##
52
+ # count total lines and executed lines
53
+ # @param result [Hash] object with the result of the coverage
54
+ # @return [Array] Array with two values: First: the total lines. Second: the lines executed
55
+ def count_lines(result)
56
+ [result[:lines].count { |n| n.is_a? Integer }, result[:lines].count { |n| n.is_a?(Integer) && n != 0 }]
57
+ end
58
+
59
+ ##
60
+ # count total branches and executed branches
61
+ # @param result [Hash] object with the result of the coverage
62
+ # @return [Array] Array with two values: First: the total branches. Second: the branches executed
63
+ def count_branches(result)
64
+ [
65
+ result[:branches].values.reduce(0) { |sum, v| sum + v.size },
66
+ result[:branches].values.reduce(0) { |sum, v| sum + v.values.reject(&:zero?).count }
67
+ ]
68
+ end
69
+
70
+ ##
71
+ # count total methods and executed methods
72
+ # @param result [Hash] object with the result of the coverage
73
+ # @return [Array] Array with two values: First: the total methods. Second: the methods executed
74
+ def count_methods(result)
75
+ [result[:methods].length, result[:methods].values.reject(&:zero?).count]
76
+ end
77
+
78
+ ##
79
+ # Transform the object to a readable string
80
+ # @return [String] contains the information ready to print
81
+ def to_s
82
+ if tested
83
+ str = "#{relative_path}: \n lines: #{lines_executed}/#{lines} #{lines_percent}%"
84
+ str += "\tbranches: #{branches_executed}/#{branches} #{branches_percent}%" if branches
85
+ str += "\tmethods: #{methods_executed}/#{methods} #{methods_percent}%" if methods
86
+ str
87
+ else
88
+ "#{relative_path} : Not executed during the tests."
89
+ end
90
+ end
91
+
92
+ ##
93
+ # Calculate the percent of coverage lines
94
+ # @return [Integer] percent of coverage. executed lines / total lines
95
+ def lines_percent
96
+ lines_executed * 100 / lines
97
+ rescue ZeroDivisionError
98
+ 0
99
+ end
100
+
101
+ ##
102
+ # Calculate the percent of coverage branches
103
+ # @return [Integer] percent of coverage. executed branches / total branches
104
+ def branches_percent
105
+ branches_executed * 100 / branches
106
+ rescue ZeroDivisionError
107
+ 0
108
+ end
109
+
110
+ ##
111
+ # Calculate the percent of coverage methods
112
+ # @return [Integer] percent of coverage. executed methods / total methods
113
+ def methods_percent
114
+ methods_executed * 100 / methods
115
+ rescue ZeroDivisionError
116
+ 0
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest'
4
+
5
+ module Minitest
6
+ module Cc
7
+ # Reporter class extend of Minitest Reporter
8
+ # this get 5 important methods from the parent
9
+ # but we use only 2
10
+ class Reporter < Minitest::AbstractReporter
11
+ ##
12
+ # Executed in the beginin of the minitest run
13
+ def start
14
+ Cc.start_coverage
15
+ end
16
+
17
+ ##
18
+ # Executed in the final of the minitest run
19
+ def report
20
+ Cc.summary
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Minitest
4
+ module Cc
5
+ # plugin version
6
+ VERSION = '0.1.0.beta'
7
+ end
8
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'cc/version'
4
+ require_relative 'cc/reporter'
5
+ require_relative 'cc/file_coverage'
6
+ require_relative 'cc/file_array'
7
+
8
+ module Minitest
9
+ # Main module of the plugin
10
+ # @author Andres
11
+ module Cc
12
+ @results = []
13
+ @files = FileArray.new
14
+
15
+ def self.cattr_accessor(name) # :nodoc:
16
+ (class << self; self; end).attr_accessor name
17
+ end
18
+
19
+ # @return [Symbol] mode of the summary. Could be :resume or :per_file
20
+ cattr_accessor :cc_mode
21
+ self.cc_mode = :resume
22
+
23
+ # @return [Array] pattern to find files that must be cover by the tests
24
+ cattr_accessor :tracked_files
25
+ self.tracked_files = [
26
+ './app/**/*.rb',
27
+ './lib/**/*.rb'
28
+ ]
29
+
30
+ # @return [Array] mode of the coverage, this array could contain:
31
+ # :lines, :branches, :methods
32
+ cattr_accessor :coverage_mode
33
+ self.coverage_mode = %i[
34
+ lines
35
+ branches
36
+ methods
37
+ ]
38
+
39
+ class << self
40
+ ##
41
+ # Start the coverage process
42
+ # @see https://runebook.dev/en/docs/ruby/coverage Coverage blog post explaining the use
43
+ # @see https://ruby-doc.org/stdlib-2.7.6/libdoc/coverage/rdoc/Coverage.html Documentation of the module
44
+ def start_coverage
45
+ Coverage.start(coverage_mode.collect { |m| [m, true] }.to_h)
46
+ end
47
+
48
+ ##
49
+ # Print the results after the runs
50
+ def summary
51
+ @results = Coverage.peek_result
52
+ list_files
53
+ puts "\n\n# Coverage:\n\n"
54
+ @files.each { |f| puts f.to_s } if cc_mode == :per_file
55
+ puts resume if cc_mode == :resume
56
+ puts
57
+ end
58
+
59
+ ##
60
+ # This method populate the FileArray variable with results
61
+ def list_files
62
+ Dir.glob(tracked_files.each { |f| File.expand_path(f) }).each do |d|
63
+ full_path = File.expand_path(d)
64
+ @files << FileCoverage.new(full_path, d, result_for_file(full_path))
65
+ end
66
+ end
67
+
68
+ ##
69
+ # Find the result for a file with the full path
70
+ # if the file was not tracked by Coverage this will return nil
71
+ # @param file_path [String] Absolute path to the file
72
+ # @return [Hash, nil] Object with all the results for the selected file or nil
73
+ def result_for_file(file_path)
74
+ return if @results.empty?
75
+
76
+ @results[file_path]
77
+ end
78
+
79
+ ##
80
+ # compose the string with resume of averages
81
+ # @return [String] String with averages
82
+ def resume
83
+ "lines: #{@files.lines_average}% branches: #{@files.branches_average}% methods: #{@files.methods_average}%"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'coverage'
4
+ require 'minitest'
5
+ require 'minitest/cc'
6
+
7
+ # Minitest module
8
+ module Minitest
9
+ # Init method called from minitest
10
+ # it start the plugin
11
+ def self.plugin_cc_init(_options)
12
+ # insert ower reporter to minitest reporters
13
+ reporter << Minitest::Cc::Reporter.new
14
+ rescue StandardError
15
+ puts 'The coverage plugin cannot be initialized.'
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minitest-cc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.beta
5
+ platform: ruby
6
+ authors:
7
+ - a-chacon
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-06-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'Plugin for minitest, provide a minimal information of code coverage
14
+ to your test output. '
15
+ email:
16
+ - andres.ch@protonmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/minitest/cc.rb
22
+ - lib/minitest/cc/file_array.rb
23
+ - lib/minitest/cc/file_coverage.rb
24
+ - lib/minitest/cc/reporter.rb
25
+ - lib/minitest/cc/version.rb
26
+ - lib/minitest/cc_plugin.rb
27
+ homepage: https://github.com/a-chacon/minitest-cc
28
+ licenses:
29
+ - GPL-3.0
30
+ metadata:
31
+ bug_tracker_uri: https://github.com/a-chacon/minitest-cc/issues
32
+ changelog_uri: https://github.com/a-chacon/minitest-cc
33
+ documentation_uri: https://www.rubydoc.info/gems/minitest-cc
34
+ homepage_uri: https://github.com/a-chacon/minitest-cc
35
+ source_code_uri: https://github.com/a-chacon/minitest-cc
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 2.5.3
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">"
48
+ - !ruby/object:Gem::Version
49
+ version: 1.3.1
50
+ requirements: []
51
+ rubygems_version: 3.2.22
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Minitest plugin, add code coverage metrics.
55
+ test_files: []