rspec-wait icon indicating copy to clipboard operation
rspec-wait copied to clipboard

Unexpected behavior when waiting for contain_exactly matcher

Open martosaur opened this issue 6 years ago • 0 comments

In order to reproduce this you need to:

  1. wait for a block...
  2. ... yielding an array of values of different types ...
  3. ... to contain_exactly correct values but placed in different order

Here's a small suite for illustration:

describe "wait_for + contain exactly" do
  let(:progress) { [1] }

  before do
    Thread.new do
      2.times do
        sleep 1
        progress << "2"
      end
    end
  end

  it "contain_exactly + correct order" do
    expect {
      wait_for { progress }.to contain_exactly(1, "2")
    }.not_to raise_error
  end

  it "contain_exactly + incorrect order" do
    expect {
      wait_for { progress }.to contain_exactly("2", 1)
    }.not_to raise_error
  end
  
  it "contain_exactly wrapped in satisfy + incorrect order" do
    expect {
      wait_for { progress }.to satisfy { |p| expect(p).to contain_exactly("2", 1) }
    }.not_to raise_error
  end
end

and the output:

Randomized with seed 62057

wait_for + contain exactly
  contain_exactly wrapped in satisfy + incorrect order
  contain_exactly + incorrect order (FAILED - 1)
  contain_exactly + correct order

Failures:

  1) wait_for + contain exactly contain_exactly + incorrect order
     Failure/Error:
       expect {
         wait_for { progress }.to contain_exactly("2", 1)
       }.not_to raise_error

       expected no Exception, got #<RSpec::Expectations::ExpectationNotMetError: expected collection contained:  ["2", 1]
       actual collection contained:    [1, "2", "2"]
       the missing elements were:      ["2"]
       > with backtrace:
         # ./lib/rspec/wait/handler.rb:12:in `block in handle_matcher'
         # ./lib/rspec/wait/handler.rb:9:in `handle_matcher'
         # ./lib/rspec/wait/target.rb:34:in `block in to'
         # ./lib/rspec/wait/target.rb:51:in `block in with_wait'
         # ./lib/rspec/wait.rb:29:in `with_wait'
         # ./lib/rspec/wait/target.rb:51:in `with_wait'
         # ./lib/rspec/wait/target.rb:33:in `to'
         # ./spec/wait_for_spec.rb:21:in `block (3 levels) in <top (required)>'
         # ./spec/wait_for_spec.rb:20:in `block (2 levels) in <top (required)>'
         # ./lib/rspec/wait.rb:47:in `block (2 levels) in <top (required)>'
     # ./spec/wait_for_spec.rb:20:in `block (2 levels) in <top (required)>'
     # ./lib/rspec/wait.rb:47:in `block (2 levels) in <top (required)>'

Finished in 12.13 seconds (files took 0.15105 seconds to load)
3 examples, 1 failure

This is reproduced on ruby 2.5.1, rspec 3.7.0 and rspec-wait master.

martosaur avatar Jun 01 '18 14:06 martosaur