Rspec and Rails for Zombies-Test not working - ruby

Im going through the rspec rails for zombies lessons and i am having trouble running the tests in that they are not reading my ruby code in my App/models folder. I even tried to put the ruby file i call zombie.rb into the spec folder itself and require_relative and still the test are failing can someone please help me out. I am a newbie and I find that TDD is the best and fastest way to learn to code profeciently.My code is below, What I have in both the zombie_spec.rb file as well as the zombie.rb file respecively:
require_relative 'spec_helper'
require_relative 'zombie'
describe Zombie do
it 'is invalid without a name' do
zombie = Zombie.new
zombie.should_not be_valid
end
it 'include tweets' do
tweet1 = Tweet.new(status: 'Uuuuunhhhhh')
tweet2 = Tweet.new(status: 'Arrrrggggg')
zombie = Zombie.new(name: 'Ash', tweets: [tweet1, tweet2])
zombie.tweets.should include(tweet1)
zombie.tweets.should include(tweet2)
end
end
and the zombie.rb file here
class Zombie < ActiveRecord::Base
attr_accessor :Tweet
validates :name, presence: true
end
This is the test result i'm getting
1) Zombie is invalid without a name
Failure/Error: zombie = Zombie.new
ActiveRecord::StatementInvalid:
Could not find table 'zombies'
# ./zombie_spec.rb:8:in `block (2 levels) in <top (required)>
2) Zombie include tweets
Failure/Error: tweet1 = Tweet.new(status: 'Uuuuunhhhhh')
NameError:
uninitialized constant Tweet
# ./zombie_spec.rb:15:in `block (2 levels) in <top (required)>'

It looks like your finding the Zombie model, because you're getting an error from ActiveRecord and it's complaining about the fact that it can't find the zombies table in your database, which suggests you haven't done your database migration yet (or had a problem with it).
The second error indicates that you haven't required any file that defines Tweet.

Related

Celluloid 0.17.3 giving unexpected "undefined method" error

I have started using Celluloid gem this morning for that first time. I am following this Railscasts tutorial and trying to figure things out.
I have a class called "SomeClass" and it has only one method. Here is the code:
require 'celluloid'
class SomeClass
include Celluloid
def initialize(name)
#name = name
end
def assholify()
puts "#{#name} has become an ASSHOLE."
end
end
When I create new instances of the class and call its method (with a bang i.e. "assholify!"), I am getting the undefined method 'assholify!', error. But Celluloid is supposed to trigger the method asynchronously when it is called with a bang. So here is how I am calling the method:
names = ['John', 'Tom', 'Harry']
names.each do |name|
n = SomeClass.new name
n.assholify!
end
Here is the full backtrace of the error:
I, [2016-09-09T11:28:02.488618 #3682] INFO -- : Celluloid 0.17.3 is running in BACKPORTED mode. [ http://git.io/vJf3J ]
/home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:42:in `rescue in check': undefined method `assholify!' for #<SomeClass:0x10897dc> (NoMethodError)
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:39:in `check'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:26:in `dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/call/sync.rb:16:in `dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/cell.rb:50:in `block in dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/cell.rb:76:in `block in task'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/actor.rb:339:in `block in task'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/task.rb:44:in `block in initialize'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/task/fibered.rb:14:in `block in create'
from (celluloid):0:in `remote procedure call'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/call/sync.rb:45:in `value'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/proxy/sync.rb:22:in `method_missing'
from some_class.rb:18:in `block in <main>'
from some_class.rb:16:in `each'
from some_class.rb:16:in `<main>'
Why am I getting this error? Is it the right way to call the function? Also how do I get rid of Celluloid 0.17.3 is running in BACKPORTED mode. warning?
The undefined method error occurred because actor methods are not called with a bang in the recent versions of celluloid gem. Instead you call the method like this: n.async.assholify. So here is what the code should look like:
names = ['John', 'Tom', 'Harry']
names.each do |name|
n = SomeClass.new name
n.async.assholify # Instead of "n.assholify!"
end
For "Celluloid 0.17.0 is running in BACKPORTED mode" warning, take a look at this wiki. Backported Mode is the default, for a limited time. If you use require 'celluloid/current' instead of require 'celluloid', you should not see this warning.

Rspec, capybara getting started issues

I have have started with simple example of Rspec,Capybara. I have come across few issues. This issues are probably because I have experience with cucumber and page_object gem, but here I am using capybara and Site_prism gem.
I have tried:
my_example_spec.rb
require_relative 'Support/spec_helper'
require_relative 'pages/login_page'
describe 'My behaviour' do
it 'should do something'do
#login_page = LoginPage.new
#login_page.load
#login_page.login('autouser','password')
end
end
and login_page.rb
class LoginPage < SitePrism::Page
set_url "/login"
element :username, "input[id='username']"
element :password, "input[id='password']"
element :submit, "input[id='submit']"
def login(username,password)
#login_page.username.set username
#login_page.password.set password
#login_page.submit.click
end
end
Issues are:
When I run my_example_spec.rb it gives error
Testing started at ...
Run options: include {:full_description=>/My\ behaviour\ should\ do\ something/}
NoMethodError: undefined method `username' for nil:NilClass
./pages/login_page.rb:10:in `login'
./my_example_spec.rb:11:in `block (2 levels) in <top (required)>'
-e:1:in `load'
-e:1:in `<main>'
Shouldn't it be on(LoginPage).login (autouser, password). It should navigate to the page and run login method. It is how it works in page_object gem whats the equivalent of site_prism gem
The login method in your LoginPage class should be
def login(username,password)
username.set username
password.set password
submit.click
end
#login_page is not an instance variable of the LoginPage class so it is not accessible inside the class. It's also not necessary inside the class since you're already inside the class.

Can't understand why I'm getting a `initialize': uninitialized constant Controller::View (NameError)

I'm trying to understand why I'm getting this error and I suspect it's because I have my Controller class and View class in two separate Ruby files. I was told that using require_relative 'filename' should reference all the code from one file into another, but I seem to be missing something. Okay here goes,
In controller.rb file, I have
require_relative 'view'
require_relative 'deck_model'
require_relative 'flashcard_model'
class Controller
def initialize
#deckofcards = Deck.new
#welcome = View.new.welcome
#player_guess = View.new.get_user_guess
#success_view = View.new.success
#failure_view = View.new.failure
end
def run
#Logic to run the game
# #current_card
# #user_guess
puts "Let's see if this prints"
# pull_card_from_deck
end
end
In my view.rb file, I have,
require_relative 'controller'
class View
attr_accessor :userguess
def initialize (userguess = " ")
#userguess = userguess
end
def welcome
system ("clear")
puts "Welcome! Let's play a game."
puts "I'll give you a definition and you have to give me the term"
puts "Ready..."
end
def get_user_guess
#userguess = gets.chomp.downcase
end
def success
puts "Excellent! You got it."
end
def failure
puts "No, that's not quite right."
end
end
However when I run controller.rb, I get the following error,
/Users/sean/Projects/flash/source/controller.rb:11:in `initialize': uninitialized constant Controller::View (NameError)
from /Users/sean/Projects/flash/source/controller.rb:51:in `new'
from /Users/sean/Projects/flash/source/controller.rb:51:in `<top (required)>'
from /Users/sean/Projects/flash/source/view.rb:1:in `require_relative'
from /Users/sean/Projects/flash/source/view.rb:1:in `<top (required)>'
from controller.rb:1:in `require_relative'
from controller.rb:1:in `<main>'
Can anyone please help me figure this out.
You did not post your full code, but it sounds like this is an error caused by the circular dependencies you specified in your project. You have view.rb depending on controller.rb and controller.rb depending on view.rb. The Ruby interpreter will not execute these files simultaneously; it has to execute one and then execute the other.
It looks like it is executing controller.rb first, but it sees that view.rb is required, so it starts executing that. Then in view.rb it sees that controller.rb is required, so it starts executing controller.rb again. Then at some point in controller.rb, you must be creating a new instance of the Controller class. But we aren't done defining the View class yet, so View is undefined and you get an exception while trying to create that controller.
To fix this, you should consider not creating any Controller or View objects until both of the classes are fully loaded.
+1 to #DavidGrayson comment.
If my assumption is correct, your issue is with require_relative 'controller' in your view.rb file.
If you see, it looks like View is requiring Controller then Controller gets loaded which seems to be sending new somewhere to Controller which then sends new to View but it hasn't been completely required.

Pure Ruby rspec test passes without method being defined

I have an rspec test on a pure Ruby model:
require 'spec_helper'
require 'organization'
describe Organization do
context '#is_root?' do
it "creates a root organization" do
org = Organization.new
expect { org.is_root?.to eq true }
end
end
end
My organization model looks like this:
class Organization
attr_accessor :parent
def initialize(parent = nil)
self.parent = parent
end
end
The output when running the tests:
bundle exec rspec spec/organization_spec.rb:6
Run options: include {:locations=>{"./spec/organization_spec.rb"=>[6]}}
.
Finished in 0.00051 seconds
1 example, 0 failures
When I run the test, it passes, despite the fact that the method is_root? doesn't exist on the model. I usually work in Rails, not pure Ruby, and I've never seen this happen. What is going on?
Thanks!
It should be:
expect(org.is_root?).to eq true
When you pass block to expect it is being wrapped in ExpectationTarget class (strictly speaking BlockExpectationTarget < ExpectationTarget). Since you didn't specify what you expect from this object, the block is never executed, hence no error is raised.
You are passing a block to expect, which is never being called. You can see this by setting an expectation on that block
expect { org.is_root?.to eq true }.to_not raise_error
1) Organization#is_root? creates a root organization
Failure/Error: expect { puts "HI";org.is_root?.to eq true }.to_not raise_error
expected no Exception, got #<NoMethodError: undefined method `is_root?' for #<Organization:0x007ffa798c2ed8 #parent=nil>> with backtrace:
# ./test_spec.rb:15:in `block (4 levels) in <top (required)>'
# ./test_spec.rb:15:in `block (3 levels) in <top (required)>'
# ./test_spec.rb:15:in `block (3 levels) in <top (required)>'
Or by just putting a plain raise or puts inside the block, neither of which will be called:
expect { puts "HI"; raise; org.is_root?.to eq true }
The block form is used for expecting that a piece of code raises an exception or not. The correct syntax for checking values is:
expect(org.is_root?).to eq(true)

Rails 4: Undefined method on module

I have a module in app/misc/dsl/builder.rb that has this code
module Dsl
class Builder
def initialize(context, &block)
return if not block_given?
parent_context = block.binding.eval "self"
parent_context.extend Proxy
parent_context.object = context
parent_context.instance_eval &block
end
end
def self.set_context(context, &block)
Dsl::Builder.new(context, &block)
end
end
Note: this directory misc is preloaded in application.rb
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**/}'),
Rails.root.join('app', 'misc', '{**/}')
]
Then, somewhere in the text (lets say at foo.rb) I have this code:
Dsl.set_context(obj) do
#some code with obj receiving messages
end
The test stack we are using consists on Zeus+Guard+Rspec. Now, lets say I rewrite the code to something not working
Dsl.set_context(obj) do
asdqwe #this message does not exists
end
From times to times, I receive this baffling message
1) SomeOtherClass search_hash receiving keywords params should query for those keywords
Failure/Error: subject.search_hash
NoMethodError:
undefined method `set_context' for Dsl:Module
# ./app/misc/product_query.rb:116:in `base_search_hash'
# ./app/misc/product_query.rb:25:in `search_hash'
# ./spec/misc/product_query_spec.rb:78:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
instead of the correct message that should be regarding undefined method asdqwe
Any clue about this?
Look here
it says:
Rails 3 has been updated such that classes/modules (henceforth, C/M)
are lazy loaded from the autoload paths as they are needed
so, you can do require_relative 'app/misc/dsl/builder.rb' in your rspec_helper.rb (can it be better with just require?) The problem must be that the loader doesn't know in advance where to find Dsl.set_context, but he will know once you have referenced Dsl::Builder
Hope it helps

Resources