Class: FeatureMap::Private::TestCoverageFile

Inherits:
Object
  • Object
show all
Defined in:
lib/feature_map/private/test_coverage_file.rb

Overview

This class is responsible for compiling a set of file-level test coverage statistics into a test-coverage.yml file that captures test coverage statistics on a per-feature basis. This file can then be used as an input to a variety of engineering team utilities (e.g. PR/release announcements, documentation generation, etc).

Defined Under Namespace

Classes: FileContentError

Constant Summary collapse

COVERAGE_RATIO =
'coverage_ratio'
FEATURES_KEY =
'features'

Class Method Summary collapse

Class Method Details

.generate_content(coverage_stats) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/feature_map/private/test_coverage_file.rb', line 41

def self.generate_content(coverage_stats)
  feature_test_coverage = {}

  Private.feature_file_assignments.each do |feature_name, files|
    feature_test_coverage[feature_name] = { 'lines' => 0, 'hits' => 0, 'misses' => 0, 'coverage_ratio' => 0 }

    files.each_with_object(feature_test_coverage[feature_name]) do |file_path, coverage|
      next unless coverage_stats[file_path]

      coverage['lines'] = coverage['lines'] + (coverage_stats[file_path]['lines'] || 0)
      coverage['hits'] = coverage['hits'] + (coverage_stats[file_path]['hits'] || 0)
      coverage['misses'] = coverage['misses'] + (coverage_stats[file_path]['misses'] || 0)

      coverage
    end
    feature_test_coverage[feature_name][COVERAGE_RATIO] = if feature_test_coverage[feature_name]['lines'].zero?
                                                            0
                                                          else
                                                            ((feature_test_coverage[feature_name]['hits'].to_f / feature_test_coverage[feature_name]['lines']) * 100).round
                                                          end
  end

  { FEATURES_KEY => feature_test_coverage }
end

.header_commentObject



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/feature_map/private/test_coverage_file.rb', line 27

def self.header_comment
  <<~HEADER
    # STOP! - DO NOT EDIT THIS FILE MANUALLY
    # This file was automatically generated by "bin/featuremap test_coverage". The next time this file
    # is generated any changes will be lost. For more details:
    # https://github.com/Beyond-Finance/feature_map
    #
    # It is NOT recommended to commit this file into your source control. It will change or become
    # outdated frequently. Instead it should be regenerated when test coverage statistics are required.
    # This file should be ignored by your source control, allowing the local copy to be used for other
    # feature analysis operations (e.g. documentation generation, etc).
  HEADER
end

.load_features!Object



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/feature_map/private/test_coverage_file.rb', line 66

def self.load_features!
  test_coverage_content = YAML.load_file(path)

  return test_coverage_content[FEATURES_KEY] if test_coverage_content.is_a?(Hash) && test_coverage_content[FEATURES_KEY]

  raise FileContentError, "Unexpected content found in #{path}. Use `bin/featuremap test_coverage` to regenerate it and try again."
rescue Psych::SyntaxError => e
  raise FileContentError, "Invalid YAML content found at #{path}. Error: #{e.message} Use `bin/featuremap test_coverage` to generate it and try again."
rescue Errno::ENOENT
  raise FileContentError, "No feature test coverage file found at #{path}. Use `bin/featuremap test_coverage` to generate it and try again."
end

.pathObject



23
24
25
# File 'lib/feature_map/private/test_coverage_file.rb', line 23

def self.path
  Pathname.pwd.join('.feature_map/test-coverage.yml')
end

.write!(coverage_stats) ⇒ Object



17
18
19
20
21
# File 'lib/feature_map/private/test_coverage_file.rb', line 17

def self.write!(coverage_stats)
  FileUtils.mkdir_p(path.dirname) if !path.dirname.exist?

  path.write([header_comment, "\n", generate_content(coverage_stats).to_yaml].join)
end