Skip to content

Instantly share code, notes, and snippets.

@jaimerson

jaimerson/rewrite_subject.rb Secret

Last active Apr 27, 2020
Embed
What would you like to do?
Fast experiments
# Usage:
# ruby rewrite_subject.rb spec/some_spec.rb spec/some_other_spec.rb
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'ffast', git: 'https://github.com/jonatas/fast'
end
require 'fast/experiment'
# From activesupport
def underscore(str)
str.to_s.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
end
# We need this to remove the files at the end
module ExperimentFileCleanup
def run_partial_replacement_with(combination)
content = partial_replace(*combination)
experimental_file = experimental_filename(combination)
$tempfiles << experimental_file
File.open(experimental_file, 'w+') { |f| f.puts content }
puts 'No changes were made to the file.' && return if FileUtils.compare_file(@file, experimental_file)
result = experiment.ok_if.call(experimental_file)
if result
ok_with(combination)
puts "✅ #{experimental_file} - Combination: #{combination}"
else
failed_with(combination)
puts "🔴 #{experimental_file} - Combination: #{combination}"
end
end
end
Fast::ExperimentFile.prepend ExperimentFileCleanup
def subject_name_for(file)
subject_name = Fast.capture_file('(send nil subject (sym $_))', file).first
subject_name ||= underscore(Fast.capture_file('(send _ describe $const)', file).first.children.last)
subject_name
rescue
File.basename(file, '_spec.rb')
end
def subject_in_context(file)
Fast.search_file('(block (send nil subject) _ $_)', file).first.location.expression.source
rescue
nil
end
ARGV.flat_map { |a| Dir.glob(a) }.each do |file|
# Check for usages of `subject` before
next if Fast.search_file('(send nil subject)', file).empty?
subject_name = subject_name_for(file)
context = subject_in_context(file)
puts "File: #{file}"
puts "Subject name: #{subject_name}"
puts "Context: #{context}" if context
puts "Enter new subject name (or leave it blank if it is fine):"
new_subject_name = $stdin.gets.strip
subject_name = new_subject_name unless new_subject_name.empty?
$tempfiles = []
experiment = Fast.experiment('RSpec/NamedSubject1') do
lookup file
search '(block (send nil subject) _ $_)'
edit do |node, (block)|
replace(node.location.expression, "subject(:#{subject_name}) { #{block.location.expression.source} }")
end
policy { |file| "bundle exec rspec {file}" }
end
experiment.run
# Force reset
Fast.instance_variable_set('@cache', nil)
other_experiment = Fast.experiment("RSpec/NamedSubject2") do
lookup file
search '(send nil subject)'
edit do |node|
next if Fast.match?([:send, nil, :subject, :sym], node)
replace(node.location.expression, subject_name.to_s)
end
policy { |file| system("bundle exec rubocop --only RSpec/NamedSubject #{file}") }
end
other_experiment.run
end
at_exit do
$tempfiles.each do |file|
FileUtils.rm(file)
rescue
next
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.