• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env ruby
2# Copyright (c) 2021-2022 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# frozen_string_literal: true
15
16# Huawei Technologies Co.,Ltd.
17require 'optparse'
18require 'yaml'
19require 'json'
20require 'ostruct'
21
22Dir[File.join(__dir__, '..', 'lib', '*.rb')].each { |file| require file } # rubocop:disable Lint/NonDeterministicRequireOrder
23
24def check_file(file)
25  raise OptionParser::InvalidOption, "File #{file} not found" unless File.exist? File.expand_path(file)
26end
27
28def check_files(arr)
29  raise OptionParser::InvalidOption, 'No ISA spec files found' if arr.length.zero?
30
31  arr.each do |f|
32    check_file(f)
33  end
34end
35
36def check_dir(dir)
37  raise OptionParser::InvalidOption, "Directory #{dir} not found." unless File.directory? File.expand_path(dir)
38end
39
40options = OpenStruct.new
41optparser = OptionParser.new do |opts|
42  opts.banner = 'Usage: spectrac.rb [options]'
43  opts.on('-r', '--report [FILE]', 'Output the test coverage summary report in yaml')
44  opts.on('-d', '--testdir DIR', 'Directory with the test files (required)')
45  opts.on('-g', '--testglob GLOB', 'Glob for finding test files in testdir (required)')
46  opts.on('-s', '--spec FILE1,FILE2,FILE3', Array, 'ISA spec file(s) (at least one required)')
47  opts.on('-n', '--non_testable [FILE]', 'Non testable assertions')
48  opts.on('-u', '--uncovered [FILE]', 'Output yaml document with ISA spec areas not covered by tests')
49  opts.on('-U', '--uncovered_md [FILE]', 'Output markdown document with ISA spec areas not covered by tests')
50  opts.on('-o', '--orphaned [FILE]', 'Output yaml file with the list of tests not relevant to the spec')
51  opts.on('-O', '--orphaned_md [FILE]', 'Output markdown file with the list of tests not relevant to the spec')
52  opts.on('-f', '--full [FILE]', 'Output spec file with additional coverage-specific fields in yaml')
53  opts.on('-F', '--full_md [FILE]', 'Output spec file with additional coverage-specific fields in markdown')
54  opts.on('-h', '--help', 'Prints this help') do
55    puts opts
56    exit
57  end
58end
59
60begin
61  optparser.parse!(into: options)
62
63  # check that required arguments aren't missing
64  missing = %i[spec testdir testglob].select { |param| options[param].nil? }
65  raise OptionParser::MissingArgument, missing.join(', ') unless missing.empty?
66
67  # check that specified paths are valid
68  check_files(options.spec)
69  check_dir(options.testdir)
70  check_file(options.non_testable) if options.non_testable
71rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
72  puts e
73  puts optparser
74  exit false
75end
76
77spec = options.spec.map { |f| YAML.load_file(File.expand_path(f)) }
78
79fullspec = Spec.new(spec)
80fullspec.load_non_testable(YAML.load_file(File.expand_path(options.non_testable))) if options.non_testable
81fullspec.load_tests(options.testdir, options.testglob)
82
83summary = Summary.new(fullspec)
84summary.compute
85
86File.write(options.report, summary.report.to_yaml) if options.report
87File.write(options.uncovered, summary.uncovered.to_yaml) if options.uncovered
88File.write(options.full, fullspec.data.to_yaml) if options.full
89File.write(options.orphaned, fullspec.orphaned.to_yaml) if options.orphaned
90
91ReportMd.new(summary.report).generate
92UncoveredMd.new(summary.uncovered).generate(options.uncovered_md) if options.uncovered_md
93FullMd.new(fullspec.data).generate(options.full_md) if options.full_md
94OrphanedMd.new(fullspec.orphaned).generate(options.orphaned_md) if options.orphaned_md
95