diff options
Diffstat (limited to 'lib/rspec_flaky')
-rw-r--r-- | lib/rspec_flaky/config.rb | 4 | ||||
-rw-r--r-- | lib/rspec_flaky/examples_pruner.rb | 25 | ||||
-rw-r--r-- | lib/rspec_flaky/flaky_examples_collection.rb | 8 | ||||
-rw-r--r-- | lib/rspec_flaky/listener.rb | 39 | ||||
-rw-r--r-- | lib/rspec_flaky/report.rb | 54 |
5 files changed, 74 insertions, 56 deletions
diff --git a/lib/rspec_flaky/config.rb b/lib/rspec_flaky/config.rb index a17ae55910e..06e96f969f1 100644 --- a/lib/rspec_flaky/config.rb +++ b/lib/rspec_flaky/config.rb @@ -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 diff --git a/lib/rspec_flaky/examples_pruner.rb b/lib/rspec_flaky/examples_pruner.rb deleted file mode 100644 index de6cf30d8ee..00000000000 --- a/lib/rspec_flaky/examples_pruner.rb +++ /dev/null @@ -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 diff --git a/lib/rspec_flaky/flaky_examples_collection.rb b/lib/rspec_flaky/flaky_examples_collection.rb index 27a2845fb50..dea23c325be 100644 --- a/lib/rspec_flaky/flaky_examples_collection.rb +++ b/lib/rspec_flaky/flaky_examples_collection.rb @@ -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 diff --git a/lib/rspec_flaky/listener.rb b/lib/rspec_flaky/listener.rb index 4a5bfec9967..5b5e4f7c7de 100644 --- a/lib/rspec_flaky/listener.rb +++ b/lib/rspec_flaky/listener.rb @@ -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 diff --git a/lib/rspec_flaky/report.rb b/lib/rspec_flaky/report.rb new file mode 100644 index 00000000000..a8730d3b7c7 --- /dev/null +++ b/lib/rspec_flaky/report.rb @@ -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 |