Class: Danger::DangerJacoco
- Inherits:
-
Plugin
- Object
- Plugin
- Danger::DangerJacoco
- Defined in:
- lib/jacoco/plugin.rb
Overview
Verify code coverage inside your projects This is done using the jacoco output Results are passed out as a table in markdown
Instance Attribute Summary collapse
-
#fail_no_coverage_data_found ⇒ Object
Returns the value of attribute fail_no_coverage_data_found.
-
#files_extension ⇒ Object
Returns the value of attribute files_extension.
-
#minimum_class_coverage_map ⇒ Object
Returns the value of attribute minimum_class_coverage_map.
-
#minimum_class_coverage_percentage ⇒ Object
Returns the value of attribute minimum_class_coverage_percentage.
-
#minimum_package_coverage_map ⇒ Object
Returns the value of attribute minimum_package_coverage_map.
-
#minimum_project_coverage_percentage ⇒ Object
rubocop:disable Metrics/ClassLength.
Instance Method Summary collapse
-
#classes(delimiter) ⇒ Object
Select modified and added files in this PR.
-
#coverage_status(coverage, minimum_percentage) ⇒ Object
it returns an emoji for coverage status.
-
#package_coverage(class_name) ⇒ Object
it returns the most suitable coverage by package name to class or nil.
-
#parse(path) ⇒ Object
Parses the xml output of jacoco to Ruby model classes This is slow since it’s basically DOM parsing.
-
#report(path, report_url = '', delimiter = %r{\/java\/|\/kotlin\/}, fail_no_coverage_data_found: true) ⇒ Object
This is a fast report based on SAX parser.
-
#report_class(jacoco_class) ⇒ Object
It returns a specific class code coverage and an emoji status as well.
-
#setup ⇒ Object
Initialize the plugin with configured parameters or defaults.
-
#total_coverage(report_path) ⇒ Object
It returns total of project code coverage and an emoji status as well.
Instance Attribute Details
#fail_no_coverage_data_found ⇒ Object
Returns the value of attribute fail_no_coverage_data_found.
28 29 30 |
# File 'lib/jacoco/plugin.rb', line 28 def fail_no_coverage_data_found @fail_no_coverage_data_found end |
#files_extension ⇒ Object
Returns the value of attribute files_extension.
25 26 27 |
# File 'lib/jacoco/plugin.rb', line 25 def files_extension @files_extension end |
#minimum_class_coverage_map ⇒ Object
Returns the value of attribute minimum_class_coverage_map.
27 28 29 |
# File 'lib/jacoco/plugin.rb', line 27 def minimum_class_coverage_map @minimum_class_coverage_map end |
#minimum_class_coverage_percentage ⇒ Object
Returns the value of attribute minimum_class_coverage_percentage.
24 25 26 |
# File 'lib/jacoco/plugin.rb', line 24 def minimum_class_coverage_percentage @minimum_class_coverage_percentage end |
#minimum_package_coverage_map ⇒ Object
Returns the value of attribute minimum_package_coverage_map.
26 27 28 |
# File 'lib/jacoco/plugin.rb', line 26 def minimum_package_coverage_map @minimum_package_coverage_map end |
#minimum_project_coverage_percentage ⇒ Object
rubocop:disable Metrics/ClassLength
23 24 25 |
# File 'lib/jacoco/plugin.rb', line 23 def minimum_project_coverage_percentage @minimum_project_coverage_percentage end |
Instance Method Details
#classes(delimiter) ⇒ Object
Select modified and added files in this PR
86 87 88 89 90 91 |
# File 'lib/jacoco/plugin.rb', line 86 def classes(delimiter) git = @dangerfile.git affected_files = git.modified_files + git.added_files affected_files.select { |file| files_extension.reduce(false) { |state, el| state || file.end_with?(el) } } .map { |file| file.split('.').first.split(delimiter)[1] } end |
#coverage_status(coverage, minimum_percentage) ⇒ Object
it returns an emoji for coverage status
134 135 136 137 138 139 |
# File 'lib/jacoco/plugin.rb', line 134 def coverage_status(coverage, minimum_percentage) if coverage < (minimum_percentage / 2) then ':skull:' elsif coverage < minimum_percentage then ':warning:' else ':white_check_mark:' end end |
#package_coverage(class_name) ⇒ Object
it returns the most suitable coverage by package name to class or nil
120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/jacoco/plugin.rb', line 120 def package_coverage(class_name) path = class_name package_parts = class_name.split('/') package_parts.reverse_each do |item| size = item.size path = path[0...-size] coverage = minimum_package_coverage_map[path] path = path[0...-1] unless path.empty? return coverage unless coverage.nil? end nil end |
#parse(path) ⇒ Object
Parses the xml output of jacoco to Ruby model classes This is slow since it’s basically DOM parsing
44 45 46 |
# File 'lib/jacoco/plugin.rb', line 44 def parse(path) Jacoco::DOMParser.read_path(path) end |
#report(path, report_url = '', delimiter = %r{\/java\/|\/kotlin\/}, fail_no_coverage_data_found: true) ⇒ Object
This is a fast report based on SAX parser
changed files. We need to get the class from this path to check the Jacoco report,
e.g. src/java/com/example/SomeJavaClass.java -> com/example/SomeJavaClass e.g. src/kotlin/com/example/SomeKotlinClass.kt -> com/example/SomeKotlinClass
The default value supposes that you’re using gradle structure, that is your path to source files is something like
Java => blah/blah/java/slashed_package/Source.java Kotlin => blah/blah/kotlin/slashed_package/Source.kt
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/jacoco/plugin.rb', line 65 def report(path, report_url = '', delimiter = %r{\/java\/|\/kotlin\/}, fail_no_coverage_data_found: true) @fail_no_coverage_data_found = fail_no_coverage_data_found setup classes = classes(delimiter) parser = Jacoco::SAXParser.new(classes) Nokogiri::XML::SAX::Parser.new(parser).parse(File.open(path)) total_covered = total_coverage(path) report_markdown = "### JaCoCO Code Coverage #{total_covered[:covered]}% #{total_covered[:status]}\n" report_markdown += "| Class | Covered | Meta | Status |\n" report_markdown += "|:---|:---:|:---:|:---:|\n" class_coverage_above_minimum = markdown_class(parser, report_markdown, report_url) markdown(report_markdown) report_fails(class_coverage_above_minimum, total_covered) end |
#report_class(jacoco_class) ⇒ Object
It returns a specific class code coverage and an emoji status as well
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/jacoco/plugin.rb', line 94 def report_class(jacoco_class) report_result = { covered: 'No coverage data found : -', status: ':black_joker:', required_coverage_percentage: 'No coverage data found : -' } counter = coverage_counter(jacoco_class) unless counter.nil? coverage = (counter.covered.fdiv(counter.covered + counter.missed) * 100).floor required_coverage = minimum_class_coverage_map[jacoco_class.name] required_coverage = package_coverage(jacoco_class.name) if required_coverage.nil? required_coverage = minimum_class_coverage_percentage if required_coverage.nil? status = coverage_status(coverage, required_coverage) report_result = { covered: coverage, status: status, required_coverage_percentage: required_coverage } end report_result end |
#setup ⇒ Object
Initialize the plugin with configured parameters or defaults
31 32 33 34 35 36 37 |
# File 'lib/jacoco/plugin.rb', line 31 def setup @minimum_project_coverage_percentage = 0 unless minimum_project_coverage_percentage @minimum_class_coverage_percentage = 0 unless minimum_class_coverage_percentage @minimum_package_coverage_map = {} unless minimum_package_coverage_map @minimum_class_coverage_map = {} unless minimum_class_coverage_map @files_extension = ['.kt', '.java'] unless files_extension end |
#total_coverage(report_path) ⇒ Object
It returns total of project code coverage and an emoji status as well
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/jacoco/plugin.rb', line 142 def total_coverage(report_path) jacoco_report = Nokogiri::XML(File.open(report_path)) report = jacoco_report.xpath('report/counter').select { |item| item['type'] == 'INSTRUCTION' } missed_instructions = report.first['missed'].to_f covered_instructions = report.first['covered'].to_f total_instructions = missed_instructions + covered_instructions covered_percentage = (covered_instructions * 100 / total_instructions).round(2) coverage_status = coverage_status(covered_percentage, minimum_project_coverage_percentage) { covered: covered_percentage, status: coverage_status } end |