Improve the architecture of RspecFlaky classes by introducing a new RspecFlaky::Report class
Signed-off-by: Rémy Coutable <remy@rymai.me>
This commit is contained in:
parent
9bb97abf04
commit
b11e887582
10 changed files with 258 additions and 198 deletions
|
@ -1,9 +1,7 @@
|
|||
require 'json'
|
||||
|
||||
module RspecFlaky
|
||||
class Config
|
||||
def self.generate_report?
|
||||
ENV['FLAKY_RSPEC_GENERATE_REPORT'] == 'true'
|
||||
!!(ENV['FLAKY_RSPEC_GENERATE_REPORT'] =~ /1|true/)
|
||||
end
|
||||
|
||||
def self.suite_flaky_examples_report_path
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
require 'json'
|
||||
|
||||
module RspecFlaky
|
||||
class ExamplesPruner
|
||||
# - flaky_examples: contains flaky examples
|
||||
attr_reader :flaky_examples
|
||||
|
||||
def initialize(collection)
|
||||
unless collection.is_a?(RspecFlaky::FlakyExamplesCollection)
|
||||
raise ArgumentError, "`collection` must be a RspecFlaky::FlakyExamplesCollection, #{collection.class} given!"
|
||||
end
|
||||
|
||||
@flaky_examples = collection
|
||||
end
|
||||
|
||||
def prune_examples_older_than(date)
|
||||
updated_hash = flaky_examples.dup
|
||||
.delete_if do |uid, hash|
|
||||
hash[:last_flaky_at] && Time.parse(hash[:last_flaky_at]).to_i < date.to_i
|
||||
end
|
||||
|
||||
RspecFlaky::FlakyExamplesCollection.new(updated_hash)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,13 +1,9 @@
|
|||
require 'json'
|
||||
require 'active_support/hash_with_indifferent_access'
|
||||
|
||||
require_relative 'flaky_example'
|
||||
|
||||
module RspecFlaky
|
||||
class FlakyExamplesCollection < SimpleDelegator
|
||||
def self.from_json(json)
|
||||
new(JSON.parse(json))
|
||||
end
|
||||
|
||||
def initialize(collection = {})
|
||||
unless collection.is_a?(Hash)
|
||||
raise ArgumentError, "`collection` must be a Hash, #{collection.class} given!"
|
||||
|
@ -24,7 +20,7 @@ module RspecFlaky
|
|||
super(Hash[collection_of_flaky_examples])
|
||||
end
|
||||
|
||||
def to_report
|
||||
def to_h
|
||||
Hash[map { |uid, example| [uid, example.to_h] }].deep_symbolize_keys
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
require 'json'
|
||||
|
||||
require_relative 'config'
|
||||
require_relative 'example'
|
||||
require_relative 'flaky_example'
|
||||
require_relative 'flaky_examples_collection'
|
||||
require_relative 'report'
|
||||
|
||||
module RspecFlaky
|
||||
class Listener
|
||||
# - suite_flaky_examples: contains all the currently tracked flacky example
|
||||
|
@ -9,7 +15,7 @@ module RspecFlaky
|
|||
attr_reader :suite_flaky_examples, :flaky_examples
|
||||
|
||||
def initialize(suite_flaky_examples_json = nil)
|
||||
@flaky_examples = FlakyExamplesCollection.new
|
||||
@flaky_examples = RspecFlaky::FlakyExamplesCollection.new
|
||||
@suite_flaky_examples = init_suite_flaky_examples(suite_flaky_examples_json)
|
||||
end
|
||||
|
||||
|
@ -18,47 +24,36 @@ module RspecFlaky
|
|||
|
||||
return unless current_example.attempts > 1
|
||||
|
||||
flaky_example = suite_flaky_examples.fetch(current_example.uid) { FlakyExample.new(current_example) }
|
||||
flaky_example = suite_flaky_examples.fetch(current_example.uid) { RspecFlaky::FlakyExample.new(current_example) }
|
||||
flaky_example.update_flakiness!(last_attempts_count: current_example.attempts)
|
||||
|
||||
flaky_examples[current_example.uid] = flaky_example
|
||||
end
|
||||
|
||||
def dump_summary(_)
|
||||
write_report_file(flaky_examples, RspecFlaky::Config.flaky_examples_report_path)
|
||||
RspecFlaky::Report.new(flaky_examples).write(RspecFlaky::Config.flaky_examples_report_path)
|
||||
# write_report_file(flaky_examples, RspecFlaky::Config.flaky_examples_report_path)
|
||||
|
||||
new_flaky_examples = flaky_examples - suite_flaky_examples
|
||||
if new_flaky_examples.any?
|
||||
Rails.logger.warn "\nNew flaky examples detected:\n"
|
||||
Rails.logger.warn JSON.pretty_generate(new_flaky_examples.to_report)
|
||||
Rails.logger.warn JSON.pretty_generate(new_flaky_examples.to_h)
|
||||
|
||||
write_report_file(new_flaky_examples, RspecFlaky::Config.new_flaky_examples_report_path)
|
||||
RspecFlaky::Report.new(new_flaky_examples).write(RspecFlaky::Config.new_flaky_examples_report_path)
|
||||
# write_report_file(new_flaky_examples, RspecFlaky::Config.new_flaky_examples_report_path)
|
||||
end
|
||||
end
|
||||
|
||||
def to_report(examples)
|
||||
Hash[examples.map { |k, ex| [k, ex.to_h] }]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_suite_flaky_examples(suite_flaky_examples_json = nil)
|
||||
unless suite_flaky_examples_json
|
||||
if suite_flaky_examples_json
|
||||
RspecFlaky::Report.load_json(suite_flaky_examples_json).flaky_examples
|
||||
else
|
||||
return {} unless File.exist?(RspecFlaky::Config.suite_flaky_examples_report_path)
|
||||
|
||||
suite_flaky_examples_json = File.read(RspecFlaky::Config.suite_flaky_examples_report_path)
|
||||
RspecFlaky::Report.load(RspecFlaky::Config.suite_flaky_examples_report_path).flaky_examples
|
||||
end
|
||||
|
||||
FlakyExamplesCollection.from_json(suite_flaky_examples_json)
|
||||
end
|
||||
|
||||
def write_report_file(examples_collection, file_path)
|
||||
return unless RspecFlaky::Config.generate_report?
|
||||
|
||||
report_path_dir = File.dirname(file_path)
|
||||
FileUtils.mkdir_p(report_path_dir) unless Dir.exist?(report_path_dir)
|
||||
|
||||
File.write(file_path, JSON.pretty_generate(examples_collection.to_report))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
54
lib/rspec_flaky/report.rb
Normal file
54
lib/rspec_flaky/report.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
require 'json'
|
||||
require 'time'
|
||||
|
||||
require_relative 'config'
|
||||
require_relative 'flaky_examples_collection'
|
||||
|
||||
module RspecFlaky
|
||||
# This class is responsible for loading/saving JSON reports, and pruning
|
||||
# outdated examples.
|
||||
class Report < SimpleDelegator
|
||||
OUTDATED_DAYS_THRESHOLD = 90
|
||||
|
||||
attr_reader :flaky_examples
|
||||
|
||||
def self.load(file_path)
|
||||
load_json(File.read(file_path))
|
||||
end
|
||||
|
||||
def self.load_json(json)
|
||||
new(RspecFlaky::FlakyExamplesCollection.new(JSON.parse(json)))
|
||||
end
|
||||
|
||||
def initialize(flaky_examples)
|
||||
unless flaky_examples.is_a?(RspecFlaky::FlakyExamplesCollection)
|
||||
raise ArgumentError, "`flaky_examples` must be a RspecFlaky::FlakyExamplesCollection, #{flaky_examples.class} given!"
|
||||
end
|
||||
|
||||
@flaky_examples = flaky_examples
|
||||
super(flaky_examples)
|
||||
end
|
||||
|
||||
def write(file_path)
|
||||
unless RspecFlaky::Config.generate_report?
|
||||
puts "! Generating reports is disabled. To enable it, please set the `FLAKY_RSPEC_GENERATE_REPORT=1` !" # rubocop:disable Rails/Output
|
||||
return
|
||||
end
|
||||
|
||||
report_path_dir = File.dirname(file_path)
|
||||
FileUtils.mkdir_p(report_path_dir) unless Dir.exist?(report_path_dir)
|
||||
|
||||
File.write(file_path, JSON.pretty_generate(flaky_examples.to_h))
|
||||
end
|
||||
|
||||
def prune_outdated(days: OUTDATED_DAYS_THRESHOLD)
|
||||
outdated_date_threshold = Time.now - (3600 * 24 * days)
|
||||
updated_hash = flaky_examples.dup
|
||||
.delete_if do |uid, hash|
|
||||
hash[:last_flaky_at] && Time.parse(hash[:last_flaky_at]).to_i < outdated_date_threshold.to_i
|
||||
end
|
||||
|
||||
self.class.new(RspecFlaky::FlakyExamplesCollection.new(updated_hash))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,23 +16,25 @@ describe RspecFlaky::Config, :aggregate_failures do
|
|||
end
|
||||
end
|
||||
|
||||
context "when ENV['FLAKY_RSPEC_GENERATE_REPORT'] is set to 'false'" do
|
||||
before do
|
||||
stub_env('FLAKY_RSPEC_GENERATE_REPORT', 'false')
|
||||
context "when ENV['FLAKY_RSPEC_GENERATE_REPORT'] is set" do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:env_value, :result) do
|
||||
'1' | true
|
||||
'true' | true
|
||||
'foo' | false
|
||||
'0' | false
|
||||
'false' | false
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(described_class).not_to be_generate_report
|
||||
end
|
||||
end
|
||||
with_them do
|
||||
before do
|
||||
stub_env('FLAKY_RSPEC_GENERATE_REPORT', env_value)
|
||||
end
|
||||
|
||||
context "when ENV['FLAKY_RSPEC_GENERATE_REPORT'] is set to 'true'" do
|
||||
before do
|
||||
stub_env('FLAKY_RSPEC_GENERATE_REPORT', 'true')
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
expect(described_class).to be_generate_report
|
||||
it 'returns false' do
|
||||
expect(described_class.generate_report?).to be(result)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe RspecFlaky::ExamplesPruner, :aggregate_failures do
|
||||
let(:collection_hash) do
|
||||
{
|
||||
a: { example_id: 'spec/foo/bar_spec.rb:2' },
|
||||
b: { example_id: 'spec/foo/baz_spec.rb:3', first_flaky_at: Time.utc(2000, 1, 1).to_s, last_flaky_at: Time.utc(2000, 2, 1).to_s }
|
||||
}
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'accepts a collection' do
|
||||
expect { described_class.new(RspecFlaky::FlakyExamplesCollection.new(collection_hash)) }.not_to raise_error
|
||||
end
|
||||
|
||||
it 'does not accept anything else' do
|
||||
expect { described_class.new([1, 2, 3]) }.to raise_error(ArgumentError, "`collection` must be a RspecFlaky::FlakyExamplesCollection, Array given!")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#prune_examples_older_than' do
|
||||
it 'returns a new collection without the examples older than 3 months' do
|
||||
collection = RspecFlaky::FlakyExamplesCollection.new(collection_hash)
|
||||
|
||||
new_report = collection.to_report.dup.tap { |r| r.delete(:b) }
|
||||
new_collection = described_class.new(collection).prune_examples_older_than(3.months.ago)
|
||||
|
||||
expect(new_collection).to be_a(RspecFlaky::FlakyExamplesCollection)
|
||||
expect(new_collection.to_report).to eq(new_report)
|
||||
expect(collection).to have_key(:b)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -24,14 +24,6 @@ describe RspecFlaky::FlakyExamplesCollection, :aggregate_failures do
|
|||
}
|
||||
end
|
||||
|
||||
describe '.from_json' do
|
||||
it 'accepts a JSON' do
|
||||
collection = described_class.from_json(JSON.pretty_generate(collection_hash))
|
||||
|
||||
expect(collection.to_report).to eq(described_class.new(collection_hash).to_report)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'accepts no argument' do
|
||||
expect { described_class.new }.not_to raise_error
|
||||
|
@ -46,11 +38,11 @@ describe RspecFlaky::FlakyExamplesCollection, :aggregate_failures do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#to_report' do
|
||||
describe '#to_h' do
|
||||
it 'calls #to_h on the values' do
|
||||
collection = described_class.new(collection_hash)
|
||||
|
||||
expect(collection.to_report).to eq(collection_report)
|
||||
expect(collection.to_h).to eq(collection_report)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -61,7 +53,7 @@ describe RspecFlaky::FlakyExamplesCollection, :aggregate_failures do
|
|||
a: { example_id: 'spec/foo/bar_spec.rb:2' },
|
||||
c: { example_id: 'spec/bar/baz_spec.rb:4' })
|
||||
|
||||
expect((collection2 - collection1).to_report).to eq(
|
||||
expect((collection2 - collection1).to_h).to eq(
|
||||
c: {
|
||||
example_id: 'spec/bar/baz_spec.rb:4',
|
||||
first_flaky_at: nil,
|
||||
|
|
|
@ -4,7 +4,7 @@ describe RspecFlaky::Listener, :aggregate_failures do
|
|||
let(:already_flaky_example_uid) { '6e869794f4cfd2badd93eb68719371d1' }
|
||||
let(:suite_flaky_example_report) do
|
||||
{
|
||||
already_flaky_example_uid => {
|
||||
"#{already_flaky_example_uid}": {
|
||||
example_id: 'spec/foo/bar_spec.rb:2',
|
||||
file: 'spec/foo/bar_spec.rb',
|
||||
line: 2,
|
||||
|
@ -55,8 +55,7 @@ describe RspecFlaky::Listener, :aggregate_failures do
|
|||
it 'returns a valid Listener instance' do
|
||||
listener = described_class.new
|
||||
|
||||
expect(listener.to_report(listener.suite_flaky_examples))
|
||||
.to eq(expected_suite_flaky_examples)
|
||||
expect(listener.suite_flaky_examples.to_h).to eq(expected_suite_flaky_examples)
|
||||
expect(listener.flaky_examples).to eq({})
|
||||
end
|
||||
end
|
||||
|
@ -65,25 +64,35 @@ describe RspecFlaky::Listener, :aggregate_failures do
|
|||
it_behaves_like 'a valid Listener instance'
|
||||
end
|
||||
|
||||
context 'when a report file exists and set by SUITE_FLAKY_RSPEC_REPORT_PATH' do
|
||||
let(:report_file) do
|
||||
Tempfile.new(%w[rspec_flaky_report .json]).tap do |f|
|
||||
f.write(JSON.pretty_generate(suite_flaky_example_report))
|
||||
f.rewind
|
||||
context 'when SUITE_FLAKY_RSPEC_REPORT_PATH is set' do
|
||||
let(:report_file_path) { 'foo/report.json' }
|
||||
|
||||
before do
|
||||
stub_env('SUITE_FLAKY_RSPEC_REPORT_PATH', report_file_path)
|
||||
end
|
||||
|
||||
context 'and report file exists' do
|
||||
before do
|
||||
expect(File).to receive(:exist?).with(report_file_path).and_return(true)
|
||||
end
|
||||
|
||||
it 'delegates the load to RspecFlaky::Report' do
|
||||
report = RspecFlaky::Report.new(RspecFlaky::FlakyExamplesCollection.new(suite_flaky_example_report))
|
||||
|
||||
expect(RspecFlaky::Report).to receive(:load).with(report_file_path).and_return(report)
|
||||
expect(described_class.new.suite_flaky_examples.to_h).to eq(report.flaky_examples.to_h)
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
stub_env('SUITE_FLAKY_RSPEC_REPORT_PATH', report_file.path)
|
||||
end
|
||||
context 'and report file does not exist' do
|
||||
before do
|
||||
expect(File).to receive(:exist?).with(report_file_path).and_return(false)
|
||||
end
|
||||
|
||||
after do
|
||||
report_file.close
|
||||
report_file.unlink
|
||||
end
|
||||
|
||||
it_behaves_like 'a valid Listener instance' do
|
||||
let(:expected_suite_flaky_examples) { suite_flaky_example_report }
|
||||
it 'return an empty hash' do
|
||||
expect(RspecFlaky::Report).not_to receive(:load)
|
||||
expect(described_class.new.suite_flaky_examples.to_h).to eq({})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -186,74 +195,21 @@ describe RspecFlaky::Listener, :aggregate_failures do
|
|||
let(:notification_already_flaky_rspec_example) { double(example: already_flaky_rspec_example) }
|
||||
|
||||
context 'when a report file path is set by FLAKY_RSPEC_REPORT_PATH' do
|
||||
let(:report_file_path) { Rails.root.join('tmp', 'rspec_flaky_report.json') }
|
||||
let(:new_report_file_path) { Rails.root.join('tmp', 'rspec_flaky_new_report.json') }
|
||||
it 'delegates the writes to RspecFlaky::Report' do
|
||||
listener.example_passed(notification_new_flaky_rspec_example)
|
||||
listener.example_passed(notification_already_flaky_rspec_example)
|
||||
|
||||
before do
|
||||
stub_env('FLAKY_RSPEC_REPORT_PATH', report_file_path)
|
||||
stub_env('NEW_FLAKY_RSPEC_REPORT_PATH', new_report_file_path)
|
||||
FileUtils.rm(report_file_path) if File.exist?(report_file_path)
|
||||
FileUtils.rm(new_report_file_path) if File.exist?(new_report_file_path)
|
||||
report1 = double
|
||||
report2 = double
|
||||
|
||||
expect(RspecFlaky::Report).to receive(:new).with(listener.flaky_examples).and_return(report1)
|
||||
expect(report1).to receive(:write).with(RspecFlaky::Config.flaky_examples_report_path)
|
||||
|
||||
expect(RspecFlaky::Report).to receive(:new).with(listener.flaky_examples - listener.suite_flaky_examples).and_return(report2)
|
||||
expect(report2).to receive(:write).with(RspecFlaky::Config.new_flaky_examples_report_path)
|
||||
|
||||
listener.dump_summary(nil)
|
||||
end
|
||||
|
||||
after do
|
||||
FileUtils.rm(report_file_path) if File.exist?(report_file_path)
|
||||
FileUtils.rm(new_report_file_path) if File.exist?(new_report_file_path)
|
||||
end
|
||||
|
||||
context 'when FLAKY_RSPEC_GENERATE_REPORT == "false"' do
|
||||
before do
|
||||
stub_env('FLAKY_RSPEC_GENERATE_REPORT', 'false')
|
||||
end
|
||||
|
||||
it 'does not write any report file' do
|
||||
listener.example_passed(notification_new_flaky_rspec_example)
|
||||
|
||||
listener.dump_summary(nil)
|
||||
|
||||
expect(File.exist?(report_file_path)).to be(false)
|
||||
expect(File.exist?(new_report_file_path)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when FLAKY_RSPEC_GENERATE_REPORT == "true"' do
|
||||
before do
|
||||
stub_env('FLAKY_RSPEC_GENERATE_REPORT', 'true')
|
||||
end
|
||||
|
||||
around do |example|
|
||||
Timecop.freeze { example.run }
|
||||
end
|
||||
|
||||
it 'writes the report files' do
|
||||
listener.example_passed(notification_new_flaky_rspec_example)
|
||||
listener.example_passed(notification_already_flaky_rspec_example)
|
||||
|
||||
listener.dump_summary(nil)
|
||||
|
||||
expect(File.exist?(report_file_path)).to be(true)
|
||||
expect(File.exist?(new_report_file_path)).to be(true)
|
||||
|
||||
expect(File.read(report_file_path))
|
||||
.to eq(JSON.pretty_generate(listener.to_report(listener.flaky_examples)))
|
||||
|
||||
new_example = RspecFlaky::Example.new(notification_new_flaky_rspec_example)
|
||||
new_flaky_example = RspecFlaky::FlakyExample.new(new_example)
|
||||
new_flaky_example.update_flakiness!
|
||||
|
||||
expect(File.read(new_report_file_path))
|
||||
.to eq(JSON.pretty_generate(listener.to_report(new_example.uid => new_flaky_example)))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_report' do
|
||||
let(:listener) { described_class.new(suite_flaky_example_report.to_json) }
|
||||
|
||||
it 'transforms the internal hash to a JSON-ready hash' do
|
||||
expect(listener.to_report(already_flaky_example_uid => already_flaky_example))
|
||||
.to match(hash_including(suite_flaky_example_report))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
125
spec/lib/rspec_flaky/report_spec.rb
Normal file
125
spec/lib/rspec_flaky/report_spec.rb
Normal file
|
@ -0,0 +1,125 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe RspecFlaky::Report, :aggregate_failures do
|
||||
let(:a_hundred_days) { 3600 * 24 * 100 }
|
||||
let(:collection_hash) do
|
||||
{
|
||||
a: { example_id: 'spec/foo/bar_spec.rb:2' },
|
||||
b: { example_id: 'spec/foo/baz_spec.rb:3', first_flaky_at: (Time.now - a_hundred_days).to_s, last_flaky_at: (Time.now - a_hundred_days).to_s }
|
||||
}
|
||||
end
|
||||
let(:suite_flaky_example_report) do
|
||||
{
|
||||
'6e869794f4cfd2badd93eb68719371d1': {
|
||||
example_id: 'spec/foo/bar_spec.rb:2',
|
||||
file: 'spec/foo/bar_spec.rb',
|
||||
line: 2,
|
||||
description: 'hello world',
|
||||
first_flaky_at: 1234,
|
||||
last_flaky_at: 4321,
|
||||
last_attempts_count: 3,
|
||||
flaky_reports: 1,
|
||||
last_flaky_job: nil
|
||||
}
|
||||
}
|
||||
end
|
||||
let(:flaky_examples) { RspecFlaky::FlakyExamplesCollection.new(collection_hash) }
|
||||
let(:report) { described_class.new(flaky_examples) }
|
||||
|
||||
describe '.load' do
|
||||
let!(:report_file) do
|
||||
Tempfile.new(%w[rspec_flaky_report .json]).tap do |f|
|
||||
f.write(JSON.pretty_generate(suite_flaky_example_report))
|
||||
f.rewind
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
report_file.close
|
||||
report_file.unlink
|
||||
end
|
||||
|
||||
it 'loads the report file' do
|
||||
expect(described_class.load(report_file.path).flaky_examples.to_h).to eq(suite_flaky_example_report)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.load_json' do
|
||||
let(:report_json) do
|
||||
JSON.pretty_generate(suite_flaky_example_report)
|
||||
end
|
||||
|
||||
it 'loads the report file' do
|
||||
expect(described_class.load_json(report_json).flaky_examples.to_h).to eq(suite_flaky_example_report)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'accepts a RspecFlaky::FlakyExamplesCollection' do
|
||||
expect { report }.not_to raise_error
|
||||
end
|
||||
|
||||
it 'does not accept anything else' do
|
||||
expect { described_class.new([1, 2, 3]) }.to raise_error(ArgumentError, "`flaky_examples` must be a RspecFlaky::FlakyExamplesCollection, Array given!")
|
||||
end
|
||||
end
|
||||
|
||||
it 'delegates to #flaky_examples using SimpleDelegator' do
|
||||
expect(report.__getobj__).to eq(flaky_examples)
|
||||
end
|
||||
|
||||
describe '#write' do
|
||||
let(:report_file_path) { Rails.root.join('tmp', 'rspec_flaky_report.json') }
|
||||
|
||||
before do
|
||||
FileUtils.rm(report_file_path) if File.exist?(report_file_path)
|
||||
end
|
||||
|
||||
after do
|
||||
FileUtils.rm(report_file_path) if File.exist?(report_file_path)
|
||||
end
|
||||
|
||||
context 'when RspecFlaky::Config.generate_report? is false' do
|
||||
before do
|
||||
allow(RspecFlaky::Config).to receive(:generate_report?).and_return(false)
|
||||
end
|
||||
|
||||
it 'does not write any report file' do
|
||||
report.write(report_file_path)
|
||||
|
||||
expect(File.exist?(report_file_path)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when RspecFlaky::Config.generate_report? is true' do
|
||||
before do
|
||||
allow(RspecFlaky::Config).to receive(:generate_report?).and_return(true)
|
||||
end
|
||||
|
||||
it 'delegates the writes to RspecFlaky::Report' do
|
||||
report.write(report_file_path)
|
||||
|
||||
expect(File.exist?(report_file_path)).to be(true)
|
||||
expect(File.read(report_file_path))
|
||||
.to eq(JSON.pretty_generate(report.flaky_examples.to_h))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#prune_outdated' do
|
||||
it 'returns a new collection without the examples older than 90 days by default' do
|
||||
new_report = flaky_examples.to_h.dup.tap { |r| r.delete(:b) }
|
||||
new_flaky_examples = report.prune_outdated
|
||||
|
||||
expect(new_flaky_examples).to be_a(described_class)
|
||||
expect(new_flaky_examples.to_h).to eq(new_report)
|
||||
expect(flaky_examples).to have_key(:b)
|
||||
end
|
||||
|
||||
it 'accepts a given number of days' do
|
||||
new_flaky_examples = report.prune_outdated(days: 200)
|
||||
|
||||
expect(new_flaky_examples.to_h).to eq(report.to_h)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue