From 80ba4ab18c8d62b2e0d7fffecb3f80c7df6dad32 Mon Sep 17 00:00:00 2001 From: Miguel Savignano Date: Sun, 3 Nov 2019 01:10:02 +0100 Subject: [PATCH] execute node bin --- bin/lcov-parse.js | 129 +++++++++++++++++++++++ lib/coverage_report.rb | 66 +++++++----- spec/coverage_report_spec.rb | 15 +++ spec/fixtures/example.lcov | 193 +++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 1 + 5 files changed, 377 insertions(+), 27 deletions(-) create mode 100644 bin/lcov-parse.js create mode 100644 spec/coverage_report_spec.rb create mode 100644 spec/fixtures/example.lcov diff --git a/bin/lcov-parse.js b/bin/lcov-parse.js new file mode 100644 index 0000000..80d0e52 --- /dev/null +++ b/bin/lcov-parse.js @@ -0,0 +1,129 @@ +/* +Copyright (c) 2012, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://yuilibrary.com/license/ +*/ + +var fs = require('fs'), + path = require('path'); + +/* istanbul ignore next */ +var exists = fs.exists || path.exists; + +var walkFile = function (str, cb) { + var data = [], item; + + ['end_of_record'].concat(str.split('\n')).forEach(function (line) { + line = line.trim(); + var allparts = line.split(':'), + parts = [allparts.shift(), allparts.join(':')], + lines, fn; + + switch (parts[0].toUpperCase()) { + case 'TN': + item.title = parts[1].trim(); + break; + case 'SF': + item.file = parts.slice(1).join(':').trim(); + break; + case 'FNF': + item.functions.found = Number(parts[1].trim()); + break; + case 'FNH': + item.functions.hit = Number(parts[1].trim()); + break; + case 'LF': + item.lines.found = Number(parts[1].trim()); + break; + case 'LH': + item.lines.hit = Number(parts[1].trim()); + break; + case 'DA': + lines = parts[1].split(','); + item.lines.details.push({ + line: Number(lines[0]), + hit: Number(lines[1]) + }); + break; + case 'FN': + fn = parts[1].split(','); + item.functions.details.push({ + name: fn[1], + line: Number(fn[0]) + }); + break; + case 'FNDA': + fn = parts[1].split(','); + item.functions.details.some(function (i, k) { + if (i.name === fn[1] && i.hit === undefined) { + item.functions.details[k].hit = Number(fn[0]); + return true; + } + }); + break; + case 'BRDA': + fn = parts[1].split(','); + item.branches.details.push({ + line: Number(fn[0]), + block: Number(fn[1]), + branch: Number(fn[2]), + taken: ((fn[3] === '-') ? 0 : Number(fn[3])) + }); + break; + case 'BRF': + item.branches.found = Number(parts[1]); + break; + case 'BRH': + item.branches.hit = Number(parts[1]); + break; + } + + if (line.indexOf('end_of_record') > -1) { + data.push(item); + item = { + lines: { + found: 0, + hit: 0, + details: [] + }, + functions: { + hit: 0, + found: 0, + details: [] + }, + branches: { + hit: 0, + found: 0, + details: [] + } + }; + } + }); + + data.shift(); + + if (data.length) { + cb(null, data); + } else { + cb('Failed to parse string'); + } +}; + +var parse = function (file, cb) { + exists(file, function (x) { + if (!x) { + return walkFile(file, cb); + } + fs.readFile(file, 'utf8', function (err, str) { + walkFile(str, cb); + }); + }); + +}; + +var path = process.argv[2] +parse(path, function (err, data) { + console.log(JSON.stringify(data, null, 2)) +}); + +// console.log(process.argv[2]) diff --git a/lib/coverage_report.rb b/lib/coverage_report.rb index 7646611..07623ed 100644 --- a/lib/coverage_report.rb +++ b/lib/coverage_report.rb @@ -1,33 +1,45 @@ # frozen_string_literal: true class CoverageReport - def self.generate(type, report_path, data) - if type == 'simplecov' - simplecov(report_path, data) - elsif type == 'jest' - jest(report_path, data) - else - raise 'InvalidCoverageReportType' + class << self + def generate(type, report_path, data) + if type == 'simplecov' + simplecov(report_path, data) + elsif type == 'jest' + jest(report_path, data) + else + raise 'InvalidCoverageReportType' + end + end + + def simplecov(report_path, data) + report = read_json(report_path) + minumum_percent = data[:min] + covered_percent = report.dig('result', 'covered_percent') + { 'lines' => { 'covered_percent' => covered_percent, 'minumum_percent' => minumum_percent } } + end + + def lcov(report_path, data) + lcov_result = execute_lcov_parse(report_path) + minumum_percent = data[:min] + { 'lines' => { 'covered_percent' => lcov_covered_percent(lcov_result), 'minumum_percent' => minumum_percent } } + end + + private + + def lcov_covered_percent(lcov_result) + lines = lcov_result.map { |r| r['lines']['details'] }.flatten + total_lines = lines.count&.to_f + covered_lines = lines.select { |r| r['hit'] == 1 }.count&.to_f + (covered_lines / total_lines) * 100 + end + + def execute_lcov_parse(report_path) + `node bin/lcov-parse.js #{report_path}` + end + + def read_json(path) + JSON.parse(File.read(path)) end end - - def self.simplecov(report_path, data) - report = read_json(report_path) - minumum_percent = data[:min] - covered_percent = report.dig('result', 'covered_percent') - { 'lines' => { 'covered_percent' => covered_percent, 'minumum_percent' => minumum_percent } } - end - - def self.jest(report_path, data) - report = read_json(report_path) - minumum_percent = data[:min] - covered_percent = report.dig('result', 'covered_percent') - { 'lines' => { 'covered_percent' => covered_percent, 'minumum_percent' => minumum_percent } } - end - - private - - def read_json(path) - JSON.parse(File.read(path)) - end end diff --git a/spec/coverage_report_spec.rb b/spec/coverage_report_spec.rb new file mode 100644 index 0000000..3bb1cbf --- /dev/null +++ b/spec/coverage_report_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require './spec/spec_helper' + +describe CoverageReport do + # it '.simplecov' do + # result = adapter.conslusion(report) + # expect(result).to eq('success') + # end + + it '.lcov' do + result = CoverageReport.lcov('./spec/fixtures/example.lcov', { min: 80 }) + expect(result['lines']['covered_percent']).to eq('sas') + end +end diff --git a/spec/fixtures/example.lcov b/spec/fixtures/example.lcov new file mode 100644 index 0000000..f2f795a --- /dev/null +++ b/spec/fixtures/example.lcov @@ -0,0 +1,193 @@ +SF:./app/controllers/application_controller.rb +DA:1,1 +DA:2,1 +end_of_record +SF:./app/controllers/posts_controller.rb +DA:1,1 +DA:2,1 +DA:6,1 +DA:7,1 +DA:12,1 +DA:16,1 +DA:17,1 +DA:21,1 +DA:26,1 +DA:27,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:34,0 +DA:35,0 +DA:42,1 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:48,0 +DA:49,0 +DA:56,1 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:64,1 +DA:66,1 +DA:67,0 +DA:71,1 +DA:72,0 +end_of_record +SF:./app/helpers/application_helper.rb +DA:1,1 +end_of_record +SF:./app/helpers/posts_helper.rb +DA:1,1 +end_of_record +SF:./app/models/application_record.rb +DA:1,1 +DA:2,1 +end_of_record +SF:./app/models/post.rb +DA:1,1 +end_of_record +SF:./config/application.rb +DA:1,1 +DA:3,1 +DA:7,1 +DA:9,1 +DA:10,1 +DA:12,1 +end_of_record +SF:./config/boot.rb +DA:1,1 +DA:3,1 +DA:4,1 +end_of_record +SF:./config/environment.rb +DA:2,1 +DA:5,1 +end_of_record +SF:./config/environments/test.rb +DA:1,1 +DA:8,1 +DA:13,1 +DA:16,1 +DA:17,1 +DA:22,1 +DA:23,1 +DA:26,1 +DA:29,1 +DA:32,1 +DA:34,1 +DA:39,1 +DA:42,1 +end_of_record +SF:./config/initializers/application_controller_renderer.rb + +end_of_record +SF:./config/initializers/assets.rb +DA:4,1 +DA:9,1 +end_of_record +SF:./config/initializers/backtrace_silencers.rb + +end_of_record +SF:./config/initializers/content_security_policy.rb + +end_of_record +SF:./config/initializers/cookies_serializer.rb +DA:5,1 +end_of_record +SF:./config/initializers/filter_parameter_logging.rb +DA:4,1 +end_of_record +SF:./config/initializers/inflections.rb + +end_of_record +SF:./config/initializers/mime_types.rb + +end_of_record +SF:./config/initializers/wrap_parameters.rb +DA:7,1 +DA:8,2 +end_of_record +SF:./config/routes.rb +DA:1,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +end_of_record +SF:./spec/helpers/posts_helper_spec.rb +DA:1,1 +DA:13,1 +DA:14,1 +end_of_record +SF:./spec/models/post_spec.rb +DA:1,1 +DA:3,1 +DA:4,1 +end_of_record +SF:./spec/requests/posts_spec.rb +DA:1,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:7,1 +end_of_record +SF:./spec/routing/posts_routing_spec.rb +DA:1,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:9,1 +DA:10,1 +DA:13,1 +DA:14,1 +DA:17,1 +DA:18,1 +DA:22,1 +DA:23,1 +DA:26,1 +DA:27,1 +DA:30,1 +DA:31,1 +DA:34,1 +DA:35,1 +end_of_record +SF:./spec/views/posts/edit.html.erb_spec.rb +DA:1,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:8,1 +DA:9,1 +DA:11,1 +end_of_record +SF:./spec/views/posts/index.html.erb_spec.rb +DA:1,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:11,1 +DA:12,1 +end_of_record +SF:./spec/views/posts/new.html.erb_spec.rb +DA:1,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:8,1 +DA:9,1 +DA:11,1 +end_of_record +SF:./spec/views/posts/show.html.erb_spec.rb +DA:1,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:8,1 +DA:9,1 +end_of_record diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d37a172..be4f8ff 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,3 +6,4 @@ require 'pry' require './lib/report_adapter' require './lib/github_check_run_service' require './lib/github_client' +require './lib/coverage_report'