class FixtureReducer::FixtureReducer

Constants

FIXTURE_REX

also use multiline fixture declarations

Attributes

test_file[R]

Public Class Methods

new(test_file) click to toggle source
# File lib/fixture_reducer.rb, line 10
def initialize(test_file)
  @test_file = test_file
  @test_folder = test_file.split("/").first
  @test_extension = "_#{@test_folder}.rb"
end

Public Instance Methods

reduce_fixtures!() click to toggle source
# File lib/fixture_reducer.rb, line 16
def reduce_fixtures!
  if fixtures = fixture_params(test_file)
    puts "#{test_file} uses #{fixtures.join(", ")}"

    if run_with(fixtures)
      puts "initial run: SUCCESS"
      original_fixtures = fixtures.dup
      fixtures = reduced_via_common([99, 95, 90, 80, 50]) if fixtures == [":all"]
      fixtures = reduce_one_by_one(fixtures)
      report_and_keep_reduction(original_fixtures, fixtures)
    else
      puts "initial run: FAILED"
    end
  else
    puts "did not find fixtures in #{test_file}"
  end
end

Private Instance Methods

available_fixtures() click to toggle source
# File lib/fixture_reducer.rb, line 97
def available_fixtures
  folder = "#{@test_folder}/fixtures/"
  extensions = ["yml", "csv"]
  Dir["#{folder}*.{#{extensions.join(",")}}"].map{|f| f.sub(%r{#{folder}(.*)(\.#{extensions.join("|")})}, ":\\1") }
end
common_fixtures(percent) click to toggle source
# File lib/fixture_reducer.rb, line 44
def common_fixtures(percent)
  usage = usage_stats.dup
  total = usage.map(&:last).inject(&:+)
  used = 0
  used += usage.shift.last while used < (total / 100 * percent)
  usage.reverse.map(&:first)
end
fixture_params(file) click to toggle source
# File lib/fixture_reducer.rb, line 91
def fixture_params(file)
  content = File.read(file)
  return unless match = content.match(FIXTURE_REX)
  match[2].split(/,\s+/)
end
fixtures_in_file() click to toggle source
# File lib/fixture_reducer.rb, line 86
def fixtures_in_file
  found = fixture_params(test_file)
  found == [":all"] ? available_fixtures : found
end
read(file) click to toggle source
# File lib/fixture_reducer.rb, line 82
def read(file)
  File.read(file)
end
reduce_one_by_one(fixtures) click to toggle source
# File lib/fixture_reducer.rb, line 130
def reduce_one_by_one(fixtures)
  necessary_fixtures = fixtures
  fixtures.each do |fixture|
    current_try = necessary_fixtures - [fixture]

    if read(test_file) =~ /(^|[^a-z\d_])#{fixture.sub(':','')}[\( ]:/
      puts "#{fixture} is called directly"
    elsif run_with(current_try)
      puts "#{fixture} is not needed"
      necessary_fixtures = current_try
    else
      puts "#{fixture} is needed"
    end
  end
  necessary_fixtures
end
reduced_via_common(percentages) click to toggle source
# File lib/fixture_reducer.rb, line 115
def reduced_via_common(percentages)
  last_success = nil
  percentages.each do |percent|
    fixtures = common_fixtures(percent)
    if run_with(fixtures)
      puts "common #{percent}% run: SUCCESS"
      last_success = fixtures
    else
      puts "common #{percent}% run: FAILED"
      break
    end
  end
  last_success || available_fixtures
end
report_and_keep_reduction(original_fixtures, fixtures) click to toggle source
# File lib/fixture_reducer.rb, line 103
def report_and_keep_reduction(original_fixtures, fixtures)
  original_fixtures = available_fixtures if original_fixtures == [":all"]
  removed_fixtures = original_fixtures - fixtures

  if removed_fixtures.empty?
    puts "could not reduce fixtures"
  else
    puts "could reduce fixtures by #{removed_fixtures.size}"
    write_fixtures(fixtures)
  end
end
run(file) click to toggle source
# File lib/fixture_reducer.rb, line 52
def run(file)
  `bundle exec rake db:test:prepare && #{test_runner} #{file}`
  $?.success?
end
run_with(fixtures) click to toggle source
# File lib/fixture_reducer.rb, line 65
def run_with(fixtures)
  old = read(test_file)
  write_fixtures(fixtures)
  run test_file
ensure
  write(test_file, old)
end
test_runner() click to toggle source
# File lib/fixture_reducer.rb, line 57
def test_runner
  if File.exist? ".zeus.sock"
    "zeus testrb"
  else
    "bundle exec ruby"
  end
end
usage_stats() click to toggle source
# File lib/fixture_reducer.rb, line 36
def usage_stats
  @usage_stats ||= begin
    used_fixtures = Dir["#{@test_folder}/**/*#{@test_extension}"].map { |file| fixture_params(file) }.compact.flatten
    used_fixtures -= [":all"]
    used_fixtures.flatten.group_by(&:to_s).map { |g, f| [g, f.size] }.sort_by(&:last)
  end.freeze
end
write(file, content) click to toggle source
# File lib/fixture_reducer.rb, line 73
def write(file, content)
  File.open(file, 'w'){|f| f.write content }
end
write_fixtures(fixtures) click to toggle source
# File lib/fixture_reducer.rb, line 77
def write_fixtures(fixtures)
  code = (fixtures.empty? ? "" : "fixtures #{fixtures.join(', ')}")
  write(test_file, File.read(test_file).sub(FIXTURE_REX, "\\1#{code}"))
end