• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14# frozen_string_literal: true
15
16#
17# Huawei Technologies Co.,Ltd.
18class Summary
19  def initialize(spec)
20    @spec = spec
21
22    # Tests
23    @total = 0
24    @accepted = []
25    @orphaned = []
26
27    # Assertions
28    @testable = 0
29    @non_testable = 0
30    @covered = 0
31    @not_covered = 0
32
33    # Coverage
34    @coverage_by_groups = []
35    @coverage_metric = 0
36
37    @uncovered_assertions = []
38  end
39
40  def report
41    {
42      'tests' => {
43        'total' => @total,
44        'counted_for_coverage' => @accepted.length,
45        'orphaned' => @orphaned.length
46      },
47      'assertions' => {
48        'testable' => @testable,
49        'non_testable' => @non_testable,
50        'covered' => @covered,
51        'not_covered' => @not_covered
52      },
53      'coverage_by_groups' => @coverage_by_groups,
54      'coverage_metric' => @testable.zero? ? 0 : (@covered.to_f / @testable).round(2)
55    }
56  end
57
58  def uncovered
59    { 'groups' => @uncovered_assertions }
60  end
61
62  def compute
63    @spec.data['groups'].each do |g|
64      compute_for_group(g)
65    end
66
67    @accepted = @accepted.uniq
68    @orphaned = @spec.orphaned.map { |f| f['file'] }.uniq
69    @total = (@accepted + @orphaned).uniq.length
70  end
71
72  private
73
74  def compute_for_group(group)
75    testable_count = 0
76    non_testable_count = 0
77    covered_count = 0
78    not_covered_count = 0
79    uncovered_for_group = { 'title' => group['title'] } # object stores uncovered assertions for the group
80
81    %w[instructions description_tests exceptions_tests verification_tests].each do |k|
82      not_covered_assertions = []
83
84      group[k]&.each do |assertion|
85        if assertion['non_testable']
86          non_testable_count += 1
87        else
88          testable_count += 1
89          if assertion['tests'].length.positive?
90            covered_count += 1
91            @accepted += assertion['tests']
92          else
93            not_covered_count += 1
94            not_covered_assertions << assertion
95          end
96        end
97      end
98
99      send(k, not_covered_assertions, uncovered_for_group) if not_covered_assertions.length.positive?
100    end
101
102    # collect uncovered assertions
103    @uncovered_assertions << uncovered_for_group if not_covered_count.positive?
104
105    # update coverage metric for the group
106    group_metric = testable_count.positive? ? (covered_count.to_f / testable_count).round(2) : 'Not testable'
107    group['coverage_metric'] = group_metric
108    @coverage_by_groups << { 'title' => group['title'], 'coverage_metric' => group_metric }
109
110    # update counters
111    @testable += testable_count
112    @non_testable += non_testable_count
113    @covered += covered_count
114    @not_covered += not_covered_count
115  end
116
117  # The following methods make not covered assertions look like in ISA
118  # by formatting and removing extra fields added by us.
119  def instructions(not_covered_assertions, uncovered_for_group)
120    uncovered_for_group['instructions'] = not_covered_assertions.map { |a| except(a, %w[tests non_testable]) }
121  end
122
123  def description_tests(not_covered_assertions, uncovered_for_group)
124    uncovered_for_group['description'] = not_covered_assertions.map do |a|
125      a['assertion']
126    end.join('. ').gsub(/\n/, ' ').rstrip
127  end
128
129  def exceptions_tests(not_covered_assertions, uncovered_for_group)
130    uncovered_for_group['exceptions'] = not_covered_assertions.map { |a| a['exception'] }
131  end
132
133  def verification_tests(not_covered_assertions, uncovered_for_group)
134    uncovered_for_group['verification'] = not_covered_assertions.map { |a| a['verification'] }
135  end
136
137  # delete specified keys from hash
138  def except(hash, keys)
139    hash.dup.tap do |x|
140      keys.each { |key| x.delete(key) }
141    end
142  end
143end
144