"output" name collission with RSpec::Matchers::BuiltIn::Output

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

"output" name collission with RSpec::Matchers::BuiltIn::Output

Ralph Shnelvar
I'm following along in The RSpec Book on page 43

The book is careful to specify all the version of the gems it uses.  My problem is likely I am using current gems.

The code I downloaded looks like this
#---
# Excerpted from "The RSpec Book",
# published by The Pragmatic Bookshelf.
# Copyrights apply to this code. It may not be used to create training material,
# courses, books, articles, and the like. Contact us if you are in doubt.
# We make no guarantees that this code is fit for any purpose.
# Visit http://www.pragmaticprogrammer.com/titles/achbd for more book information.
#---
class Output
 
def messages
   
@messages ||= []
 
end

 
def puts(message)
    messages
<< message
 
end
end

def output
 
@output ||= Output.new
end

Given /^I am not yet playing$/ do
end

When /^I start a new game$/ do
  game
= Codebreaker::Game.new(output)
  game
.start
end

Then /^I should see "([^"]*)"$/ do |message|
  output.messages.should include(message)
end

The author says he's creating a "test double" with the lines
class Output
 
def messages
   
@messages ||= []
 
end

 
def puts(message)
    messages
<< message
 
end
end

def output
 
@output ||= Output.new
end

If I use the above code, RSpec will say
  Scenario: start game                          # features/codebreaker_starts_game.feature:7
   
Given I am not yet playing                  # features/step_definitions/codebreaker_steps.rb:34
   
When I start a new game                     # features/step_definitions/codebreaker_steps.rb:37
    Then I should see "Welcome to Codebreaker!" # features/step_definitions/codebreaker_steps.rb:41
      undefined method `messages' for #<RSpec::Matchers::BuiltIn::Output:0x0055e95ffb9728> (NoMethodError)
      ./features/step_definitions/codebreaker_steps.rb:44:in `/^I should see "([^"]*)"$/'
      features/codebreaker_starts_game.feature:10:in `Then I should see "Welcome to Codebreaker!"'
    And I should see "Enter guess:"             # features/step_definitions/codebreaker_steps.rb:41

The "undefined method" message immediately above is not what the book says should be generated.

If, on the other hand, I rename the method named output with output_ralph (see immediately below)
# This works

#---
# Excerpted from "The RSpec Book",
# published by The Pragmatic Bookshelf.
# Copyrights apply to this code. It may not be used to create training material,
# courses, books, articles, and the like. Contact us if you are in doubt.
# We make no guarantees that this code is fit for any purpose.
# Visit http://www.pragmaticprogrammer.com/titles/achbd for more book information.
#---

require "byebug"
# byebug

class Output
 
def messages
   
@messages ||= []
 
end

 
def puts(message)
    messages
<< message
 
end
end

# byebug
def output_ralph
 
# byebug
 
@output ||= Output.new
  ret
= @output
 
# byebug
  ret
end

Given /^I am not yet playing$/ do
end

When /^I start a new game$/ do
 
# byebug
  game
= Codebreaker::Game.new(output_ralph)
  game
.start
end

Then /^I should see "([^"]*)"$/ do |message|
  # output.messages.should include(message)
  # byebug
  # x = output_ralph.messages
  # byebug
 
  expect(
output_ralph.messages).to include(message)
end

then I get the output the book says I should get (immediately below)
  Scenario: start game                          # features/codebreaker_starts_game.feature:7
   
Given I am not yet playing                  # features/step_definitions/codebreaker_steps.rb:34
   
When I start a new game                     # features/step_definitions/codebreaker_steps.rb:37
   
Then I should see "Welcome to Codebreaker!" # features/step_definitions/codebreaker_steps.rb:43
     
expected [] to include "Welcome to Codebreaker!" (RSpec::Expectations::ExpectationNotMetError)
     
./features/step_definitions/codebreaker_steps.rb:49:in `/^I should see "([^"]*)"$/'
      features/codebreaker_starts_game.feature:10:in `
Then I should see "Welcome to Codebreaker!"'
    And I should see "Enter guess:"             # features/step_definitions/codebreaker_steps.rb:43


I suspect I have a name collision with Class: RSpec::Matchers::BuiltIn::Output but I'm damned if I can figure out why.

I guess I could leave the code as-is but ... advice would be appreciated.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/01a0184f-502b-42fb-af8d-8c6902ac3fd5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: "output" name collission with RSpec::Matchers::BuiltIn::Output

Frederick Cheung-2


On Sunday, July 16, 2017 at 6:17:56 PM UTC+1, Ralph Shnelvar wrote:

I suspect I have a name collision with <a href="http://rspec.info/documentation/3.4/rspec-expectations/RSpec/Matchers/BuiltIn/Output.html" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frspec.info%2Fdocumentation%2F3.4%2Frspec-expectations%2FRSpec%2FMatchers%2FBuiltIn%2FOutput.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExar2Eqp_NDUZst0V0wrCdbOjMgA&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frspec.info%2Fdocumentation%2F3.4%2Frspec-expectations%2FRSpec%2FMatchers%2FBuiltIn%2FOutput.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExar2Eqp_NDUZst0V0wrCdbOjMgA&#39;;return true;">Class: RSpec::Matchers::BuiltIn::Output but I'm damned if I can figure out why.

I guess I could leave the code as-is but ... advice would be appreciated.

You are correct. rspec added the ability to test that some code has written something to stdout. You use it like this:

expect { print('foo') }.to output('foo').to_stdout

To make this work, rspec defines an output method (that returns an Output matcher, which is the class that you see) which is the thing colliding with your method

Fred

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/ae5bf767-a67d-46b4-9e56-66f5f81a03b8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...