Class: KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector

Inherits:
Object
  • Object
show all
Defined in:
lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb

Instance Method Summary collapse

Instance Method Details

#generate_json_report(rspec_args) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb', line 6

def generate_json_report(rspec_args)
  raise "The internal KNAPSACK_PRO_RSPEC_OPTIONS environment variable is unset. Ensure it is not overridden accidentally. Otherwise, please report this as a bug: #{KnapsackPro::Urls::SUPPORT}" if rspec_args.nil?

  require 'rspec/core'

  cli_format =
    if Gem::Version.new(::RSpec::Core::Version::STRING) < Gem::Version.new('3.6.0')
      require_relative '../formatters/rspec_json_formatter'
      ['--format', KnapsackPro::Formatters::RSpecJsonFormatter.to_s]
    else
      ['--format', 'json']
    end

  ensure_report_dir_exists
  remove_old_json_report

  test_file_entities = slow_test_files

  if test_file_entities.empty?
    no_examples_json = { examples: [] }.to_json
    File.write(report_path, no_examples_json)
    return
  end

  args = (rspec_args || '').split
  cli_args_without_formatters = KnapsackPro::Adapters::RSpecAdapter.remove_formatters(args)

  # Apply a --format option which overrides formatters from the RSpec custom option files like `.rspec`.
  cli_args = cli_args_without_formatters + cli_format + [
    '--dry-run',
    '--no-color',
    '--out', report_path,
    '--default-path', test_dir,
  ] + KnapsackPro::TestFilePresenter.paths(test_file_entities)
  options = ::RSpec::Core::ConfigurationOptions.new(cli_args)
  exit_code = ::RSpec::Core::Runner.new(options).run($stderr, $stdout)
  if exit_code != 0
    debug_cmd = ([
      'bundle exec rspec',
    ] + cli_args).join(' ')

    KnapsackPro.logger.error('-'*10 + ' START of actionable error message ' + '-'*50)
    KnapsackPro.logger.error('RSpec (with a dry-run option) had a problem generating the report with test examples for the slow test files. Here is what you can do:')

    KnapsackPro.logger.error("a) Please look for an error message from RSpec in the output above or below. If you don't see anything, that is fine. Sometimes RSpec does not produce any errors in the output.")

    KnapsackPro.logger.error("b) Check if RSpec generated the report file #{report_path}. If the report exists, it may contain an error message. Here is a preview of the report file:")
    KnapsackPro.logger.error(report_content || 'N/A')

    KnapsackPro.logger.error('c) To reproduce the error manually, please run the following RSpec command. This way, you can find out what is causing the error. Please ensure you run the command in the same environment where the error occurred. For instance, if the error happens on the CI server, you should run the command in the CI environment:')
    KnapsackPro.logger.error(debug_cmd)

    KnapsackPro.logger.error('-'*10 + ' END of actionable error message ' + '-'*50)

    raise 'There was a problem while generating test examples for the slow test files. Please read the actionable error message above.'
  end
end

#slow_test_filesObject



75
76
77
78
79
80
81
82
83
# File 'lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb', line 75

def slow_test_files
  if KnapsackPro::Config::Env.slow_test_file_pattern
    KnapsackPro::TestFileFinder.slow_test_files_by_pattern(adapter_class)
  else
    # read slow test files from JSON file on disk that was generated
    # by lib/knapsack_pro/base_allocator_builder.rb
    KnapsackPro::SlowTestFileDeterminer.read_from_json_report
  end
end

#test_file_example_pathsObject



64
65
66
67
68
69
70
71
72
73
# File 'lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb', line 64

def test_file_example_paths
  raise "No report found at #{report_path}" unless File.exist?(report_path)

  json_report = File.read(report_path)
  hash_report = JSON.parse(json_report)
  hash_report
    .fetch('examples')
    .map { |e| e.fetch('id') }
    .map { |path_with_example_id| test_file_hash_for(path_with_example_id) }
end