Last active
January 28, 2019 10:10
-
-
Save Nondv/6c3e6b584f43a0837f6b2666b33cb943 to your computer and use it in GitHub Desktop.
RSpec multiple changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec/autorun' | |
RSpec.describe 'Multiple changes' do | |
subject do | |
proc do | |
a << 123 | |
a << 456 | |
b[:key] = 789 | |
end | |
end | |
let!(:a) { [] } | |
let!(:b) { {} } | |
let!(:c) { [] } | |
def expect_multiple_changes(callable, to: [], not_to: []) | |
message = ->(method, index) { "Matcher: #{method}[#{index}]" } | |
expectations = to.map.with_index { |matcher, i| [:to, matcher, message[:to, i]] } | |
expectations += not_to.map.with_index { |matcher, i| [:not_to, matcher, message[:not_to, i]] } | |
generate_multiple_changes_example(callable, expectations) | |
.call | |
end | |
def generate_multiple_changes_example(result_proc, expectations) | |
return result_proc if expectations.empty? | |
method, matcher, error_message = expectations.first | |
next_result = -> { expect(result_proc).send(method, matcher, error_message) } | |
generate_multiple_changes_example(next_result, expectations[1..-1]) | |
end | |
describe '#expect_multiple_changes' do | |
it 'works but with inconvinient failure messages' do | |
expect_multiple_changes subject, | |
to: [change(a, :size).by(2), | |
change { b.key?(:key) }.from(false).to(true)], | |
not_to: [change(c, :size)] | |
end | |
# failing example | |
it do | |
expect_multiple_changes subject, | |
to: [change(a, :size).by(2), | |
change(b, :size).by(9999999999)], | |
not_to: [change(c, :size)] | |
end | |
end | |
describe '#and' do | |
it 'works but doesnt allow to mix #to with #not_to' do | |
old_c_size = c.size | |
# Additionally, text editor auto indentation is going crazy | |
expect(subject).to change(a, :size).by(2).and \ | |
change { b.key?(:key) }.from(false).to(true) | |
expect(c.size).to eq(old_c_size) | |
end | |
end | |
describe 'block chaining' do | |
it 'works but pretty ugly' do | |
expect { | |
expect { | |
expect(subject).to change(a, :size).by(2) | |
}.to change { b.key?(:key) }.from(false).to(true) | |
}.not_to change(c, :size) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment