Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Writing cucumber/turnip steps that would as both "I should XYZ" and "I should not XYZ"
module AuthenticationSteps
# Before, this required two steps, one for "should" and one for "should not".
# Alternatively, you could write a single step that had a `:should` placeholder,
# but required an `if negated ... else ... end`, which still duplicated the matchers.
step "I :should be on the main app page" do |negated|
with_negation(negated) do
expect(page).to have_current_path("/#")
expect(page).to have_text(@authenticated_user.full_name)
end
end
RSpec.configure { |c| c.include self }
end
module StepPlaceholders
extend Turnip::DSL
# order matters, longer regex goes first
placeholder :should do
match(/should not/) { true }
match(/should/) { false }
end
def with_negation(negated, &block)
if negated
begin
swap_methods(::RSpec::Expectations::ExpectationTarget, :to, :not_to)
yield
ensure
restore_methods(::RSpec::Expectations::ExpectationTarget, :to, :not_to)
end
else
yield
end
end
def swap_methods(mod, a, b)
mod.module_exec do
orig_a = :"__orig_#{a}"
orig_b = :"__orig_#{b}"
alias_method orig_a, a unless respond_to?(orig_a)
alias_method orig_b, b unless respond_to?(orig_b)
remove_method a
remove_method b
alias_method b, orig_a
alias_method a, orig_b
end
end
def restore_methods(mod, a, b)
mod.module_exec do
orig_a = :"__orig_#{a}"
orig_b = :"__orig_#{b}"
alias_method a, orig_a
alias_method b, orig_b
end
end
RSpec.configure { |c| c.include self }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment