1#!/usr/bin/env ruby 2# Copyright (c) 2021 Huawei Device Co., Ltd. 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# frozen_string_literal: true 16 17require 'optparse' 18require 'yaml' 19require 'ostruct' 20require_relative 'spec' 21require_relative 'templates/full_md' 22require_relative 'templates/orphaned_md' 23require_relative 'templates/uncovered_md' 24require_relative 'templates/report_md' 25 26def check_option(opts, key) 27 return unless opts[key].empty? 28 puts "Missing option: --#{key}" 29 puts opts 30 exit false 31end 32 33options = Hash.new { |h, k| h[k] = [] } 34 35OptionParser.new do |opts| 36 opts.banner = 'Usage: spectrac.rb [options]' 37 opts.on('-r', '--report FILE', 'Output the test coverage summary report in yaml') 38 opts.on('-d', '--testdir DIR', 'Directory with the test files (required)') 39 opts.on('-g', '--testglob GLOB', 'Glob(s) for finding test files in testdir (required, could be multiple)') do |g| 40 options[:testglob] << g 41 end 42 opts.on('-s', '--spec FILE', 'ISA spec file (required)') 43 opts.on('-n', '--non_testable FILE', 'Non testable assertions') 44 opts.on('-u', '--uncovered FILE', 'Output yaml document with ISA spec areas not covered by tests') 45 opts.on('-U', '--uncovered_md FILE', 'Output markdown document with ISA spec areas not covered by tests') 46 opts.on('-o', '--orphaned FILE', 'Output yaml file with the list of tests not relevant to the spec') 47 opts.on('-O', '--orphaned_md FILE', 'Output markdown file with the list of tests not relevant to the spec') 48 opts.on('-f', '--full FILE', 'Output spec file with additional coverage-specific fields in yaml') 49 opts.on('-F', '--full_md FILE', 'Output spec file with additional coverage-specific fields in markdown') 50 opts.on('-h', '--help', 'Prints this help') do 51 puts opts 52 exit 53 end 54end.parse!(into: options) 55 56check_option(options, :testglob) 57check_option(options, :testdir) 58check_option(options, :spec) 59 60unless File.directory? options[:testdir] 61 puts "Testdir dir #{options[:testdir]} does not exist!" 62 exit false 63end 64 65isa = YAML.load_file(options[:spec]) 66non_testable = options[:non_testable].empty? ? {} : YAML.load_file(options[:non_testable]) 67 68spec = Spec.new(isa, non_testable, options[:testdir]) 69options[:testglob].each { |g| 70 path = File.join(options[:testdir], g) 71 testfiles = Dir.glob(path) 72 unless 0 < testfiles.length 73 puts "No files found by #{path}" 74 exit false 75 end 76 testfiles.each { |tf| spec.add_testfile(tf) } 77} 78 79report = spec.compute_coverage 80ReportMd.new(report).generate 81 82File.write(options[:report], report.to_yaml) unless options[:report].empty? 83File.write(options[:orphaned], spec.orphaned.to_yaml) unless options[:orphaned].empty? 84File.write(options[:full], spec.spec.to_yaml) unless options[:full].empty? 85File.write(options[:uncovered], spec.uncovered.to_yaml) unless options[:uncovered].empty? 86 87FullMd.new(spec.spec).generate(options[:full_md]) unless options[:full_md].empty? 88OrphanedMd.new(spec.orphaned).generate(options[:orphaned_md]) unless options[:orphaned_md].empty? 89UncoveredMd.new(spec.uncovered).generate(options[:uncovered_md]) unless options[:uncovered_md].empty? 90