Skip to content

Upgrade to RSpec 3.0 #128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 27, 2014
Merged

Upgrade to RSpec 3.0 #128

merged 5 commits into from
Jun 27, 2014

Conversation

jdantonio
Copy link
Member

All specs now pass with RSpec 3.0.

Original PR Comments:

This branch represents my attempt to upgrade us to RSpec 3.0. We now have almost 30 failing tests.

I followed the step-by-step Instructions verbatim and used the transpec tool as directed. I ran everything under ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0] on my MacBook Pro. The test suite was green at the start. Now I get numerous failed tests when running bundle exec rspec -fd --color --seed 1. None of our intermittently failing specs are amongst the current set of failing tests. All the failing tests are in two files:

  • spec/concurrent/obligation_spec.rb
  • spec/concurrent/actress_spec.rb

I'll work on these specific tests later then report the issues to the RSpec team. The full output of the test run is below.

RSpec Output

Failures:

  1. Concurrent::Obligation pending it should behave like incomplete #value should return immediately if timeout is zero
    Failure/Error: expect(obligation.send(method, 0)).to(method eq(:no_error!) ? eq(obligation) : be_nil)
    TypeError:
    #<RSpec::Matchers::BuiltIn::Eq:0x007fcb5aceb990 @expected=#<#Class:0x007fcb5acebee0:0x007fcb5acebaf8 @mutex=#Mutex:0x007fcb5acebaa8, @State=:pending>> is not a symbol
    Shared Example Group: "incomplete" called from ./spec/concurrent/obligation_spec.rb:67

    ./spec/concurrent/obligation_spec.rb:39:in `method'

    ./spec/concurrent/obligation_spec.rb:39:in`block (5 levels) in module:Concurrent'

  2. Concurrent::Obligation pending it should behave like incomplete #no_error! should return immediately if timeout is zero
    Failure/Error: expect(obligation.send(method, 0)).to(method eq(:no_error!) ? eq(obligation) : be_nil)
    TypeError:
    #<RSpec::Matchers::BuiltIn::Eq:0x007fcb5ad12d38 @expected=#<#Class:0x007fcb5ad081a8:0x007fcb5ad13530 @mutex=#Mutex:0x007fcb5ad132d8, @State=:pending>> is not a symbol
    Shared Example Group: "incomplete" called from ./spec/concurrent/obligation_spec.rb:67

    ./spec/concurrent/obligation_spec.rb:39:in `method'

    ./spec/concurrent/obligation_spec.rb:39:in`block (5 levels) in module:Concurrent'

  3. Concurrent::Obligation pending it should behave like incomplete #value! should return immediately if timeout is zero
    Failure/Error: expect(obligation.send(method, 0)).to(method eq(:no_error!) ? eq(obligation) : be_nil)
    TypeError:
    #<RSpec::Matchers::BuiltIn::Eq:0x007fcb5ad3a4f0 @expected=#<#Class:0x007fcb5ad3abd0:0x007fcb5ad3a720 @mutex=#Mutex:0x007fcb5ad3a6f8, @State=:pending>> is not a symbol
    Shared Example Group: "incomplete" called from ./spec/concurrent/obligation_spec.rb:67

    ./spec/concurrent/obligation_spec.rb:39:in `method'

    ./spec/concurrent/obligation_spec.rb:39:in`block (5 levels) in module:Concurrent'

  4. Concurrent::Obligation unscheduled it should behave like incomplete #value should return immediately if timeout is zero
    Failure/Error: expect(obligation.send(method, 0)).to(method eq(:no_error!) ? eq(obligation) : be_nil)
    TypeError:
    #<RSpec::Matchers::BuiltIn::Eq:0x007fcb5adc5488 @expected=#<#Class:0x007fcb5adc64f0:0x007fcb5adc5e60 @mutex=#Mutex:0x007fcb5adc5d98, @State=:unscheduled>> is not a symbol
    Shared Example Group: "incomplete" called from ./spec/concurrent/obligation_spec.rb:62

    ./spec/concurrent/obligation_spec.rb:39:in `method'

    ./spec/concurrent/obligation_spec.rb:39:in`block (5 levels) in module:Concurrent'

  5. Concurrent::Obligation unscheduled it should behave like incomplete #no_error! should return immediately if timeout is zero
    Failure/Error: expect(obligation.send(method, 0)).to(method eq(:no_error!) ? eq(obligation) : be_nil)
    TypeError:
    #<RSpec::Matchers::BuiltIn::Eq:0x007fcb5ae260d0 @expected=#<#Class:0x007fcb5ae26738:0x007fcb5ae262b0 @mutex=#Mutex:0x007fcb5ae26288, @State=:unscheduled>> is not a symbol
    Shared Example Group: "incomplete" called from ./spec/concurrent/obligation_spec.rb:62

    ./spec/concurrent/obligation_spec.rb:39:in `method'

    ./spec/concurrent/obligation_spec.rb:39:in`block (5 levels) in module:Concurrent'

  6. Concurrent::Obligation unscheduled it should behave like incomplete #value! should return immediately if timeout is zero
    Failure/Error: expect(obligation.send(method, 0)).to(method eq(:no_error!) ? eq(obligation) : be_nil)
    TypeError:
    #<RSpec::Matchers::BuiltIn::Eq:0x007fcb5ae64128 @expected=#<#Class:0x007fcb5ae64920:0x007fcb5ae64448 @mutex=#Mutex:0x007fcb5ae643f8, @State=:unscheduled>> is not a symbol
    Shared Example Group: "incomplete" called from ./spec/concurrent/obligation_spec.rb:62

    ./spec/concurrent/obligation_spec.rb:39:in `method'

    ./spec/concurrent/obligation_spec.rb:39:in`block (5 levels) in module:Concurrent'

  7. Concurrent::Actress spawning Actress#spawn context_spawn_by_hash #name should eq "ping"
    Failure/Error: actor.backdoor { terminate! }
    NoMethodError:
    undefined method `backdoor' for "ping":String

    ./spec/concurrent/actress_spec.rb:23:in`block in terminate_actors'

    ./spec/concurrent/actress_spec.rb:22:in `each'

    ./spec/concurrent/actress_spec.rb:22:in`terminate_actors'

    ./spec/concurrent/actress_spec.rb:106:in `block (6 levels) in module:Actress'

  8. Concurrent::Actress spawning Actress#spawn context_spawn_by_hash #path should eq "/ping"
    Failure/Error: actor.backdoor { terminate! }
    NoMethodError:
    undefined method `backdoor' for "/ping":String

    ./spec/concurrent/actress_spec.rb:23:in`block in terminate_actors'

    ./spec/concurrent/actress_spec.rb:22:in `each'

    ./spec/concurrent/actress_spec.rb:22:in`terminate_actors'

    ./spec/concurrent/actress_spec.rb:106:in `block (6 levels) in module:Actress'

  9. Concurrent::Actress spawning Actress#spawn spawn_by_hash executor should be global
    Failure/Error: it('executor should be global') { expect(subject.executor).to eq Concurrent.configuration.global_task_pool }
    NoMethodError:
    undefined method `executor' for nil:NilClass

    ./spec/concurrent/actress_spec.rb:122:in`block (6 levels) in module:Actress'

  10. Concurrent::Actress spawning Actress#spawn spawn_by_hash returns arg
    Failure/Error: expect(subject.ask!(:anything)).to eq 'arg'
    NoMethodError:
    undefined method ask!' for nil:NilClass # ./spec/concurrent/actress_spec.rb:129:inblock (6 levels) in module:Actress'

  11. Concurrent::Actress spawning Actress#spawn spawn_by_hash #reference
    Failure/Error: subject { super().reference }
    NoMethodError:
    undefined method reference' for nil:NilClass # ./spec/concurrent/actress_spec.rb:125:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:126:in `block (7 levels) in module:Actress'

  12. Concurrent::Actress spawning Actress#spawn spawn_by_hash #name
    Failure/Error: subject { super().name }
    NoMethodError:
    undefined method name' for nil:NilClass # ./spec/concurrent/actress_spec.rb:119:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:120:in `block (7 levels) in module:Actress'

  13. Concurrent::Actress spawning Actress#spawn spawn_by_hash #path
    Failure/Error: subject { super().path }
    NoMethodError:
    undefined method path' for nil:NilClass # ./spec/concurrent/actress_spec.rb:109:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:110:in `block (7 levels) in module:Actress'

  14. Concurrent::Actress spawning Actress#spawn spawn executor should be global
    Failure/Error: it('executor should be global') { expect(subject.executor).to eq Concurrent.configuration.global_task_pool }
    NoMethodError:
    undefined method executor' for nil:NilClass # ./spec/concurrent/actress_spec.rb:122:inblock (6 levels) in module:Actress'

  15. Concurrent::Actress spawning Actress#spawn spawn returns arg
    Failure/Error: expect(subject.ask!(:anything)).to eq 'arg'
    NoMethodError:
    undefined method ask!' for nil:NilClass # ./spec/concurrent/actress_spec.rb:129:inblock (6 levels) in module:Actress'

  16. Concurrent::Actress spawning Actress#spawn spawn #reference
    Failure/Error: subject { super().reference }
    NoMethodError:
    undefined method reference' for nil:NilClass # ./spec/concurrent/actress_spec.rb:125:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:126:in `block (7 levels) in module:Actress'

  17. Concurrent::Actress spawning Actress#spawn spawn #name
    Failure/Error: subject { super().name }
    NoMethodError:
    undefined method name' for nil:NilClass # ./spec/concurrent/actress_spec.rb:119:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:120:in `block (7 levels) in module:Actress'

  18. Concurrent::Actress spawning Actress#spawn spawn #path
    Failure/Error: subject { super().path }
    NoMethodError:
    undefined method path' for nil:NilClass # ./spec/concurrent/actress_spec.rb:109:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:110:in `block (7 levels) in module:Actress'

  19. Concurrent::Actress spawning Actress#spawn context_spawn executor should be global
    Failure/Error: it('executor should be global') { expect(subject.executor).to eq Concurrent.configuration.global_task_pool }
    NoMethodError:
    undefined method executor' for nil:NilClass # ./spec/concurrent/actress_spec.rb:122:inblock (6 levels) in module:Actress'

  20. Concurrent::Actress spawning Actress#spawn context_spawn returns arg
    Failure/Error: expect(subject.ask!(:anything)).to eq 'arg'
    NoMethodError:
    undefined method ask!' for nil:NilClass # ./spec/concurrent/actress_spec.rb:129:inblock (6 levels) in module:Actress'

  21. Concurrent::Actress spawning Actress#spawn context_spawn #reference
    Failure/Error: subject { super().reference }
    NoMethodError:
    undefined method reference' for nil:NilClass # ./spec/concurrent/actress_spec.rb:125:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:126:in `block (7 levels) in module:Actress'

  22. Concurrent::Actress spawning Actress#spawn context_spawn #name
    Failure/Error: subject { super().name }
    NoMethodError:
    undefined method name' for nil:NilClass # ./spec/concurrent/actress_spec.rb:119:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:120:in `block (7 levels) in module:Actress'

  23. Concurrent::Actress spawning Actress#spawn context_spawn #path
    Failure/Error: subject { super().path }
    NoMethodError:
    undefined method path' for nil:NilClass # ./spec/concurrent/actress_spec.rb:109:inblock (7 levels) in module:Actress'
    # ./spec/concurrent/actress_spec.rb:110:in `block (7 levels) in module:Actress'

  24. Concurrent::Actress envelope
    Failure/Error: envelope = subject.ask!('a')
    NoMethodError:
    undefined method ask!' for nil:NilClass # ./spec/concurrent/actress_spec.rb:189:inblock (3 levels) in module:Actress'

  25. Concurrent::Actress stress test run 0
    Failure/Error: expect(Concurrent::Actress.root.send(:core).instance_variable_get(:@children)).to include(actor)
    expected #<Set: {}> to include nil
    Diff:
    @@ -1,2 +1,2 @@
    -[nil]
    +[]

 # ./spec/concurrent/actress_spec.rb:70:in `block (7 levels) in <module:Actress>'
 # ./spec/concurrent/actress_spec.rb:64:in `times'
 # ./spec/concurrent/actress_spec.rb:64:in `block (6 levels) in <module:Actress>'
  1. Concurrent::Actress children has children set after a child is created
    Failure/Error: child = parent.ask!(:child)
    NoMethodError:
    undefined method ask!' for nil:NilClass # ./spec/concurrent/actress_spec.rb:178:inblock (3 levels) in module:Actress'

  2. Concurrent::Actress termination terminates with all its children
    Failure/Error: child = subject.ask! :child
    NoMethodError:
    undefined method ask!' for nil:NilClass # ./spec/concurrent/actress_spec.rb:214:inblock (3 levels) in module:Actress'

Deprecation Warnings:

RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values= is deprecated, it is now set to true as default and setting it to false has no effect.

If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
config.raise_errors_for_deprecations!, and it will turn the
deprecation warnings into errors, giving you the full backtrace.

1 deprecation warning total

Finished in 2 minutes 41.5 seconds (files took 0.49893 seconds to load)
1310 examples, 27 failures, 5 pending

Failed examples:

rspec ./spec/concurrent/obligation_spec.rb:38 # Concurrent::Obligation pending it should behave like incomplete #value should return immediately if timeout is zero
rspec ./spec/concurrent/obligation_spec.rb:38 # Concurrent::Obligation pending it should behave like incomplete #no_error! should return immediately if timeout is zero
rspec ./spec/concurrent/obligation_spec.rb:38 # Concurrent::Obligation pending it should behave like incomplete #value! should return immediately if timeout is zero
rspec ./spec/concurrent/obligation_spec.rb:38 # Concurrent::Obligation unscheduled it should behave like incomplete #value should return immediately if timeout is zero
rspec ./spec/concurrent/obligation_spec.rb:38 # Concurrent::Obligation unscheduled it should behave like incomplete #no_error! should return immediately if timeout is zero
rspec ./spec/concurrent/obligation_spec.rb:38 # Concurrent::Obligation unscheduled it should behave like incomplete #value! should return immediately if timeout is zero
rspec ./spec/concurrent/actress_spec.rb:120 # Concurrent::Actress spawning Actress#spawn context_spawn_by_hash #name should eq "ping"
rspec ./spec/concurrent/actress_spec.rb:110 # Concurrent::Actress spawning Actress#spawn context_spawn_by_hash #path should eq "/ping"
rspec ./spec/concurrent/actress_spec.rb:122 # Concurrent::Actress spawning Actress#spawn spawn_by_hash executor should be global
rspec ./spec/concurrent/actress_spec.rb:128 # Concurrent::Actress spawning Actress#spawn spawn_by_hash returns arg
rspec ./spec/concurrent/actress_spec.rb:126 # Concurrent::Actress spawning Actress#spawn spawn_by_hash #reference
rspec ./spec/concurrent/actress_spec.rb:120 # Concurrent::Actress spawning Actress#spawn spawn_by_hash #name
rspec ./spec/concurrent/actress_spec.rb:110 # Concurrent::Actress spawning Actress#spawn spawn_by_hash #path
rspec ./spec/concurrent/actress_spec.rb:122 # Concurrent::Actress spawning Actress#spawn spawn executor should be global
rspec ./spec/concurrent/actress_spec.rb:128 # Concurrent::Actress spawning Actress#spawn spawn returns arg
rspec ./spec/concurrent/actress_spec.rb:126 # Concurrent::Actress spawning Actress#spawn spawn #reference
rspec ./spec/concurrent/actress_spec.rb:120 # Concurrent::Actress spawning Actress#spawn spawn #name
rspec ./spec/concurrent/actress_spec.rb:110 # Concurrent::Actress spawning Actress#spawn spawn #path
rspec ./spec/concurrent/actress_spec.rb:122 # Concurrent::Actress spawning Actress#spawn context_spawn executor should be global
rspec ./spec/concurrent/actress_spec.rb:128 # Concurrent::Actress spawning Actress#spawn context_spawn returns arg
rspec ./spec/concurrent/actress_spec.rb:126 # Concurrent::Actress spawning Actress#spawn context_spawn #reference
rspec ./spec/concurrent/actress_spec.rb:120 # Concurrent::Actress spawning Actress#spawn context_spawn #name
rspec ./spec/concurrent/actress_spec.rb:110 # Concurrent::Actress spawning Actress#spawn context_spawn #path
rspec ./spec/concurrent/actress_spec.rb:188 # Concurrent::Actress envelope
rspec ./spec/concurrent/actress_spec.rb:60 # Concurrent::Actress stress test run 0
rspec ./spec/concurrent/actress_spec.rb:177 # Concurrent::Actress children has children set after a child is created
rspec ./spec/concurrent/actress_spec.rb:213 # Concurrent::Actress termination terminates with all its children

Randomized with seed 1

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.11%) when pulling be440fa on refactor/rspec3 into 140faa9 on master.

@yujinakayama
Copy link

The cause I've identified so far is the invalid conversion of its(:attr).

Your spec has an after hook in the same example group with its. Then transpec converted the its to a nested example group with overridden subject. In this case, the outer after hook is still run for the example in the nested group, but the subject in the hook is not the same object as before because its does not change the subject internally. So it fails in the terminate_actors helper method invoked from the hook.

@yujinakayama
Copy link

So, I think there are 2 options:

1. Name the subject and use the name in the hook

subject(:actor, &subject_definition)
after { terminate_actors actor }

2. Continue using its

Require rspec-its gem in your spec helper before running transpec so that transpec does not convert its.

@jdantonio
Copy link
Member Author

@yujinakayama Thank you for the help and the suggestions! I'll refactor the tests this evening.

@jdantonio
Copy link
Member Author

@yujinakayama I've made the changes you suggested and all the tests pass on my local machine. I expect that Travis will verify a successful upgrade to RSpec 3.0. Thank you again for your assistance.

@jdantonio jdantonio mentioned this pull request Jun 27, 2014
@coveralls
Copy link

Coverage Status

Coverage remained the same when pulling ddb29e2 on refactor/rspec3 into 73be654 on master.

jdantonio added a commit that referenced this pull request Jun 27, 2014
@jdantonio jdantonio merged commit f4204a6 into master Jun 27, 2014
@pitr-ch
Copy link
Member

pitr-ch commented Jun 27, 2014

@jdantonio you've been faster by few minutes I was just about to push actress_fixes too :)

@pitr-ch
Copy link
Member

pitr-ch commented Jun 27, 2014

Thanks

@yujinakayama
Copy link

@jdantonio You're welcome :).

@jdantonio
Copy link
Member Author

@pitr-ch I woke up this morning much earlier than normal so I took advantage of the time. Than you for looking into those tests.

@jdantonio jdantonio deleted the refactor/rspec3 branch July 7, 2014 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants