class PseudoCleaner::MasterCleaner

Constants

CLEANING_STRATEGIES
DB_CLEANER_CLEANING_STRATEGIES
VALID_END_METHODS
VALID_START_METHODS
VALID_TEST_METHODS
VALID_TEST_TYPES

Public Class Methods

clean(test_type, test_strategy, &block) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 179
def clean(test_type, test_strategy, &block)
  raise "Invalid test_type \"#{test_type}\"" unless [:suite, :test].include? test_type
  raise "Invalid test_strategy \"#{test_strategy}\"" unless CLEANING_STRATEGIES.include? test_strategy

  master_cleaner = PseudoCleaner::MasterCleaner.send "start_#{test_type}", test_strategy

  body_error = nil
  begin
    block.yield master_cleaner
  rescue => error
    body_error = error
  end

  master_cleaner.end test_type: test_type, test_strategy: test_strategy

  raise body_error if body_error
end
cleaner_class(table_name) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 229
def cleaner_class(table_name)
  seed_class_name      = "#{table_name.to_s.classify}Cleaner"
  seed_class_base_name = seed_class_name.demodulize
  base_module          = seed_class_name.split("::")[0..-2].join("::")
  base_module_classes  = [Object]

  unless base_module.blank?
    base_module_classes = base_module_classes.unshift base_module.constantize
  end

  return_class = nil
  2.times do
    base_module_classes.each do |base_class|
      if (base_class.const_defined?(seed_class_base_name, false))
        if base_class == Object
          return_class = seed_class_base_name.constantize
        else
          return_class = "#{base_class.name}::#{seed_class_base_name}".constantize
        end

        break
      end
    end

    break if return_class

    seeder_file = "db/cleaners/"
    seeder_file += base_module.split("::").map { |module_name| module_name.underscore }.join("/")
    seeder_file += "/" unless seeder_file[-1] == "/"
    seeder_file += seed_class_base_name.underscore
    seeder_file += ".rb"
    seeder_file = File.join(Rails.root, seeder_file)

    break unless File.exists?(seeder_file)

    require seeder_file
  end

  # unless return_class &&
  #     VALID_TEST_METHODS.any? { |test_method| return_class.instance_methods.include?(test_method.to_sym) }
  #   return_class = table
  # end

  unless return_class &&
      VALID_TEST_METHODS.any? { |test_method| return_class.instance_methods.include?(test_method.to_sym) }
    return_class = PseudoCleaner::TableCleaner
  end

  return_class
end
cleaner_classes() click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 280
def cleaner_classes
  unless @@cleaner_classes
    @@cleaner_classes = []

    time = Benchmark.measure do
      puts "    Gathering cleaners" if PseudoCleaner::Configuration.instance.benchmark

      PseudoCleaner::MasterCleaner.create_table_cleaners
      PseudoCleaner::MasterCleaner.create_custom_cleaners
      # PseudoCleaner::MasterCleaner.create_redis_cleaners
    end
    puts "    Gathering cleaners time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
  end

  @@cleaner_classes
end
create_custom_cleaners(options = {}) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 314
def create_custom_cleaners(options = {})
  if Object.const_defined?("Rails", false)
    cleaner_root  = Rails.root.join("db/cleaners/").to_s
    cleaner_files = Dir[Rails.root.join("db/cleaners/**/*.rb")]

    cleaner_files.each do |cleaner_file|
      class_name = File.basename(cleaner_file, ".rb").classify

      check_class, full_module_name = find_file_class(cleaner_file, cleaner_root)
      unless check_class && check_class.const_defined?(class_name, false)
        require cleaner_file
        check_class, full_module_name = find_file_class(cleaner_file, cleaner_root)
      end

      if check_class
        full_module_name << class_name
        if check_class.const_defined?(class_name, false)
          check_class = full_module_name.join("::").constantize
        else
          check_class = nil
        end
      end

      if check_class &&
          PseudoCleaner::MasterCleaner::VALID_TEST_METHODS.
              any? { |test_method| check_class.instance_methods.include?(test_method) }
        unless PseudoCleaner::MasterCleaner.cleaner_classes.any? { |cleaner| check_class == cleaner[2] }
          PseudoCleaner::MasterCleaner.cleaner_classes << [nil, nil, check_class]
        end
      end
    end
  end
end
create_table_cleaners(options = {}) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 297
def create_table_cleaners(options = {})
  SortedSeeder::Seeder.create_order(PseudoCleaner::Configuration.db_connection(nil)).each do |table|
    cleaner_class = PseudoCleaner::MasterCleaner.cleaner_class(table.name)
    if cleaner_class
      PseudoCleaner::MasterCleaner.cleaner_classes << [table, nil, cleaner_class]
    end
  end
  if SortedSeeder::Seeder.respond_to?(:unclassed_tables)
    SortedSeeder::Seeder.unclassed_tables(PseudoCleaner::Configuration.db_connection(nil)).each do |table_name|
      cleaner_class = PseudoCleaner::MasterCleaner.cleaner_class(table_name)
      if cleaner_class
        PseudoCleaner::MasterCleaner.cleaner_classes << [nil, table_name, cleaner_class]
      end
    end
  end
end
database_cleaner() click to toggle source

def clean_redis(redis)

@@redis_classes ||= []
@@redis_classes << redis

end

# File lib/pseudo_cleaner/master_cleaner.rb, line 89
def database_cleaner
  if Object.const_defined?("ActiveRecord", false) && ActiveRecord.const_defined?("Base", false)
    DatabaseCleaner[:active_record, connection: PseudoCleaner::Configuration.db_connection(:active_record)]
  elsif Object.const_defined?("Sequel", false) && Sequel.const_defined?("Model", false)
    DatabaseCleaner[:sequel, connection: PseudoCleaner::Configuration.db_connection(:sequel)]
  end
end
database_reset() click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 212
def database_reset
  PseudoCleaner::MasterCleaner.seed_data
  PseudoCleaner::MasterCleaner.start_suite
end
end_example(example_class, options = {}) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 125
def end_example(example_class, options = {})
  options[:description] ||= "PseudoCleaner::MasterCleaner.end_example"

  time = Benchmark.measure do
    puts options[:description] if PseudoCleaner::Configuration.instance.benchmark

    within_report_block(options) do
      pseudo_cleaner_data = example_class.instance_variable_get(:@pseudo_cleaner_data)

      unless pseudo_cleaner_data[:test_strategy] == :none
        unless [:pseudo_delete].include? pseudo_cleaner_data[:test_strategy]
          PseudoCleaner::MasterCleaner.database_cleaner.clean
        end

        case pseudo_cleaner_data[:test_strategy]
          when :deletion, :truncation
            PseudoCleaner::MasterCleaner.database_reset
        end

        pseudo_cleaner_data[:pseudo_state].end test_type: :test, test_strategy: pseudo_cleaner_data[:test_strategy]
      end
    end
  end
  puts "#{options[:description]} time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
end_suite(description = nil) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 151
def end_suite(description = nil)
  description ||= "PseudoCleaner::MasterCleaner.end_suite"

  time = Benchmark.measure do
    puts description if PseudoCleaner::Configuration.instance.benchmark

    within_report_block(description: description) do
      @@suite_cleaner.end test_strategy: :pseudo_delete if @@suite_cleaner
    end
  end

  puts "#{description} time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
find_file_class(seeder_file, seeder_root) click to toggle source

def create_redis_cleaners

if @@redis_classes
  @@redis_classes.each do |redis|
    PseudoCleaner::MasterCleaner.cleaner_classes << [redis, nil, PseudoCleaner::RedisMonitorCleaner]
  end
end

end

# File lib/pseudo_cleaner/master_cleaner.rb, line 356
def find_file_class(seeder_file, seeder_root)
  check_class      = Object
  full_module_name = []

  File.dirname(seeder_file.to_s[seeder_root.length..-1]).split("/").map do |module_element|
    if (module_element != ".")
      full_module_name << module_element.classify
      if check_class.const_defined?(full_module_name[-1], false)
        check_class = full_module_name.join("::").constantize
      else
        check_class = nil
        break
      end
    end
  end

  return check_class, full_module_name
end
new(test_type) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 438
def initialize(test_type)
  raise "Invalid test type.  Must be one of: #{VALID_TEST_TYPES}" unless VALID_TEST_TYPES.include?(test_type)

  @test_type = test_type
end
peek_data_inline(options = {}) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 379
def peek_data_inline(options = {})
  @@report_error = false
  @@report_table = nil

  options[:description] ||= "PseudoCleaner::MasterCleaner.peek_data"

  time = Benchmark.measure do
    puts options[:description] if PseudoCleaner::Configuration.instance.benchmark

    if Object.const_defined?("Cornucopia", false) &&
        Cornucopia.const_defined?("Util", false) &&
        Cornucopia::Util.const_defined?("ReportBuilder", false) &&
        !PseudoCleaner::Configuration.current_instance.disable_cornucopia_output
      Cornucopia::Util::ReportBuilder.current_report.within_section(options[:description]) do |report|
        report.within_hidden_table do |outer_report_table|
          Cornucopia::Util::ReportTable.new(
              nested_table:         outer_report_table,
              suppress_blank_table: true) do |report_table|
            # redundant, but I like it because it is consistent.
            if options[:location]
              report_table.write_stats "location", options[:location]
            end

            @@report_table = report_table

            peek_values
          end
        end
      end

      @@report_table = nil
    else
      PseudoCleaner::Logger.write(options[:description])

      peek_values
    end
  end

  puts "#{options[:description]} time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
peek_data_new_test(options = {}) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 420
def peek_data_new_test(options = {})
  options[:description] ||= "PseudoCleaner::MasterCleaner.peek_data"

  time = Benchmark.measure do
    puts options[:description] if PseudoCleaner::Configuration.instance.benchmark

    within_report_block(options) do
      peek_values
    end
  end
  puts "#{options[:description]} time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
peek_values() click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 433
def peek_values
  @@suite_cleaner.peek_values
end
process_exception(error) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 222
def process_exception(error)
  PseudoCleaner::Logger.write("    An exception has occurred:".red.on_light_white)
  PseudoCleaner::Logger.write("")
  PseudoCleaner::Logger.write(error.to_s)
  PseudoCleaner::Logger.write(error.backtrace.join("\n")) if error.backtrace
end
report_error() click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 31
def report_error
  @@report_error = true
end
report_table() click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 27
def report_table
  @@report_table
end
reset_database(description = nil) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 197
def reset_database(description = nil)
  description ||= "PseudoCleaner::MasterCleaner.reset_database"

  time = Benchmark.measure do
    puts description if PseudoCleaner::Configuration.instance.benchmark

    within_report_block(description: description) do
      PseudoCleaner::MasterCleaner.database_cleaner.clean_with(:truncation)

      PseudoCleaner::MasterCleaner.database_reset
    end
  end
  puts "#{description} time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
review_rows(&block) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 375
def review_rows(&block)
  @@suite_cleaner.review_rows(&block)
end
seed_data() click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 217
def seed_data
  PseudoCleaner::Logger.write("Re-seeding database".red.on_light_white)
  SortedSeeder::Seeder.seed_all(PseudoCleaner::Configuration.db_connection(nil))
end
start_example(example_class, strategy, options = {}) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 97
def start_example(example_class, strategy, options = {})
  options[:description] ||= "PseudoCleaner::MasterCleaner.start_example"

  time = Benchmark.measure do
    puts options[:description] if PseudoCleaner::Configuration.instance.benchmark

    within_report_block(options) do
      pseudo_cleaner_data                 = {}
      pseudo_cleaner_data[:test_strategy] = strategy

      unless strategy == :none
        raise "invalid strategy" unless PseudoCleaner::MasterCleaner::DB_CLEANER_CLEANING_STRATEGIES.has_key? strategy

        DatabaseCleaner.strategy = PseudoCleaner::MasterCleaner::DB_CLEANER_CLEANING_STRATEGIES[strategy]
        unless [:pseudo_delete].include? strategy
          PseudoCleaner::MasterCleaner.database_cleaner.start
        end

        pseudo_cleaner_data[:pseudo_state] = PseudoCleaner::MasterCleaner.start_test strategy
      end

      example_class.instance_variable_set(:@pseudo_cleaner_data, pseudo_cleaner_data)
    end
  end

  puts "#{options[:description]} time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
start_suite(description = nil) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 66
def start_suite(description = nil)
  description ||= "PseudoCleaner::MasterCleaner.start_suite"

  time = Benchmark.measure do
    puts description if PseudoCleaner::Configuration.instance.benchmark

    within_report_block(description: description) do
      if @@suite_cleaner
        @@suite_cleaner.reset_suite
      end
      @@suite_cleaner = PseudoCleaner::MasterCleaner.new(:suite)
      @@suite_cleaner.start :pseudo_delete
      @@suite_cleaner
    end
  end
  puts "#{description} time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
start_test(test_strategy) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 165
def start_test test_strategy
  raise "Invalid test_strategy \"#{test_strategy}\"" unless CLEANING_STRATEGIES.include? test_strategy

  cleaner = if PseudoCleaner::Configuration.current_instance.single_cleaner_set
              @@suite_cleaner
            else
              PseudoCleaner::MasterCleaner.new(:test)
            end

  cleaner.start test_strategy, test_type: :test, test_strategy: test_strategy

  cleaner
end
within_report_block(options, &block) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 35
def within_report_block(options, &block)
  @@report_error = false
  @@report_table = nil

  if Object.const_defined?("Cornucopia", false) &&
      Cornucopia.const_defined?("Util", false) &&
      Cornucopia::Util.const_defined?("ReportBuilder", false)
    Cornucopia::Util::ReportBuilder.current_report.within_test(options[:description]) do
      Cornucopia::Util::ReportBuilder.current_report.within_section(options[:description]) do |report|
        report.within_table do |report_table|
          if options[:location]
            report_table.write_stats "location", options[:location]
          end

          @@report_table = report_table

          block.yield
        end
      end

      unless @@report_error
        Cornucopia::Util::ReportBuilder.current_report.test_succeeded
      end
    end

    @@report_table = nil
  else
    block.yield
  end
end

Public Instance Methods

end(options = {}) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 500
def end(options = {})
  test_type = options[:test_type] || @test_type
  if PseudoCleaner::Configuration.current_instance.output_diagnostics ||
      PseudoCleaner::Configuration.current_instance.post_transaction_analysis
    PseudoCleaner::Logger.write("Cleaning #{test_type}")
  end
  end_all_cleaners options
end
end_all_cleaners(options) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 515
def end_all_cleaners(options)
  test_type     = options[:test_type] || @test_type
  test_strategy = options[:test_strategy] || @test_strategy
  run_all_cleaners("#{test_type}_end".to_sym, @cleaners.reverse, test_strategy)
end
peek_values() click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 549
def peek_values
  run_all_cleaners(:peek_values, @cleaners)
end
reset_suite() click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 521
def reset_suite
  run_all_cleaners(:reset_suite, @cleaners.reverse)
end
review_rows(&block) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 545
def review_rows(&block)
  run_all_cleaners(:review_rows, @cleaners, &block)
end
run_all_cleaners(cleaner_function, cleaners, *args, &block) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 525
def run_all_cleaners(cleaner_function, cleaners, *args, &block)
  last_error = nil

  if cleaners
    cleaners.each do |cleaner|
      begin
        if cleaner.respond_to?(cleaner_function)
          cleaner.send(cleaner_function, *args, &block)
        end
      rescue => error
        PseudoCleaner::MasterCleaner.process_exception(last_error) if last_error

        last_error = error
      end
    end
  end

  raise last_error if last_error
end
start(test_strategy, options = {}) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 444
def start(test_strategy, options = {})
  test_type = options[:test_type] || @test_type

  unless @cleaners
    @cleaners      = []
    @test_strategy = test_strategy

    time = Benchmark.measure do
      puts "  Building cleaners" if PseudoCleaner::Configuration.instance.benchmark

      start_method = "#{test_type}_start".to_sym
      end_method   = "#{test_type}_end".to_sym

      PseudoCleaner::MasterCleaner.cleaner_classes.each do |clean_class|
        table = clean_class[0]
        table ||= clean_class[1]

        begin
          @cleaners << clean_class[2].new(start_method, end_method, table, options)
        rescue Exception => error
          puts error.to_s
          raise error
        end
      end

      unless @@cleaner_classes_sorted
        seed_sorts = @cleaners.map { |cleaner| SortedSeeder::Seeder::SeederSorter.new(cleaner) }
        seed_sorts.sort!

        @cleaners = seed_sorts.map(&:seed_base_object)

        sorted_classes = []
        @cleaners.each do |cleaner|
          cleaner_class = PseudoCleaner::MasterCleaner.cleaner_classes.detect do |unsorted_cleaner|
            if cleaner.class == unsorted_cleaner[2]
              if unsorted_cleaner[2] == PseudoCleaner::TableCleaner
                cleaner.table == unsorted_cleaner[0] || cleaner.table == unsorted_cleaner[1]
              else
                true
              end
            end
          end

          sorted_classes << cleaner_class
        end

        @@cleaner_classes        = sorted_classes
        @@cleaner_classes_sorted = true
      end
    end
    puts "  Building cleaners time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
  end

  start_all_cleaners options
end
start_all_cleaners(options) click to toggle source
# File lib/pseudo_cleaner/master_cleaner.rb, line 509
def start_all_cleaners(options)
  test_type     = options[:test_type] || @test_type
  test_strategy = options[:test_strategy] || @test_strategy
  run_all_cleaners("#{test_type}_start".to_sym, @cleaners, test_strategy)
end