Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby Build a Todo List Application with Rails 4 Build a Todo List Application with Rails 4 Deleting Todo Lists

Error (Again!)

Here is the error:

treehouse:~/projects/odot (master *) $ bin/rake spec
/home/treehouse/.rbenv/versions/2.0.0-p353/bin/ruby -S rspec ./spec/controllers/todo_lists_controller_spec.rb ./spec/features/todo_lists/create_spec.rb ./spec/features/todo_lists/destroy_spec.rb ./spec/features/todo_lists/edit_spec.rb ./spec/helpers/todo_lists_helper_spec.rb ./spec/models/todo_list_spec.rb ./spec/requests/todo_lists_spec.rb ./spec/routing/todo_lists_routing_spec.rb ./spec/views/todo_lists/edit.html.erb_spec.rb ./spec/views/todo_lists/index.html.erb_spec.rb ./spec/views/todo_lists/new.html.erb_spec.rb ./spec/views/todo_lists/show.html.erb_spec.rb
..........................*....F.......*.

Pending:
  TodoListsHelper add some examples to (or delete) /home/treehouse/projects/odot/spec/helpers/todo_lists_helper_spec.rb
    # No reason given
    # ./spec/helpers/todo_lists_helper_spec.rb:14
  TodoList add some examples to (or delete) /home/treehouse/projects/odot/spec/models/todo_list_spec.rb
    # No reason given
    # ./spec/models/todo_list_spec.rb:4

Failures:

  1) Creating todo lists displays an error when the todo list has no descripton
     Failure/Error: expect(page).to have_content("error")
       expected to find text "error" in "Todo list was successfully created. Title: Grocery list Description: Food Edit | Back"
     # ./spec/features/todo_lists/create_spec.rb:65:in `block (2 levels) in <top (required)>'

Deprecation Warnings:

--------------------------------------------------------------------------------
The semantics of `RSpec::Core::ExampleGroup.pending` are changing in RSpec 3.
In RSpec 2.x, it caused the example to be skipped. In RSpec 3, the example will
still be run but is expected to fail, and will be marked as a failure (rather
than as pending) if the example passes, just like how `pending` with a block
from within an example already works.

To keep the same skip semantics, change `pending` to `skip`.  Otherwise, if you
want the new RSpec 3 behavior, you can safely ignore this warning and continue
to upgrade to RSpec 3 without addressing it.

Called from /home/treehouse/projects/odot/spec/helpers/todo_lists_helper_spec.rb:14:in `block in <top (required)>'.

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
The semantics of `RSpec::Core::ExampleGroup.pending` are changing in RSpec 3.
In RSpec 2.x, it caused the example to be skipped. In RSpec 3, the example will
still be run but is expected to fail, and will be marked as a failure (rather
than as pending) if the example passes, just like how `pending` with a block
from within an example already works.

To keep the same skip semantics, change `pending` to `skip`.  Otherwise, if you
want the new RSpec 3 behavior, you can safely ignore this warning and continue
to upgrade to RSpec 3 without addressing it.

Called from /home/treehouse/projects/odot/spec/models/todo_list_spec.rb:4:in `block in <top (required)>'.

--------------------------------------------------------------------------------

`stub_model` is deprecated. Use the `rspec-activemodel-mocks` gem instead. Called from /home/treehouse/projects/odot/spec/views/todo_lists/edit.html.erb_spec.rb:5:in `block (2 levels) in <top (required)>'.
`stub_model` is deprecated. Use the `rspec-activemodel-mocks` gem instead. Called from /home/treehouse/projects/odot/spec/views/todo_lists/index.html.erb_spec.rb:6:in `block (2 levels) in <top (required)>'.
`stub_model` is deprecated. Use the `rspec-activemodel-mocks` gem instead. Called from /home/treehouse/projects/odot/spec/views/todo_lists/index.html.erb_spec.rb:10:in `block (2 levels) in <top (required)>'.
Too many uses of deprecated '`stub_model`'. Pass `--deprecation-out` or set `config.deprecation_stream` to a file for full output.


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.

7 deprecation warnings total

Finished in 4.67 seconds
41 examples, 1 failure, 2 pending

Failed examples:

rspec ./spec/features/todo_lists/create_spec.rb:60 # Creating todo lists displays an error when the todo list has no descripton

Randomized with seed 54960

/home/treehouse/.rbenv/versions/2.0.0-p353/bin/ruby -S rspec ./spec/controllers/todo_lists_controller_spec.rb ./spec/features/todo_lists/create_spec.rb ./spec/features/todo_lists/destroy_spec.rb ./spec/features/todo_lists/edit_spec.rb ./spec/helpers/todo_lists_helper_spec.rb ./spec/models/todo_list_spec.rb ./spec/requests/todo_lists_spec.rb ./spec/routing/todo_lists_routing_spec.rb ./spec/views/todo_lists/edit.html.erb_spec.rb ./spec/views/todo_lists/index.html.erb_spec.rb ./spec/views/todo_lists/new.html.erb_spec.rb ./spec/views/todo_lists/show.html.erb_spec.rb failed
treehouse:~/projects/odot (master *) $ 

Code

require 'spec_helper'

describe "Creating todo lists"  do
    def create_todo_list(options={})
        options[:title] ||= "My todo list"
        options[:description] ||= "This is my todo list."

        visit "/todo_lists"
        click_link "New Todo list"
        expect(page).to have_content("New todo_list")

        fill_in "Title", with: options[:title]
        fill_in "Description", with: options[:description]
        click_button "Create Todo list"

    end

    it "redirects to the todo list index page on success" do
        create_todo_list
        expect(page).to have_content("My todo list")
    end

    it "displays an error when the todo list has no title" do
        expect(TodoList.count).to eq(0)

        create_todo_list title: ""

        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("This is what I'm doing today.")
    end

    it "displays an error when the todo list has a title less than 3 characters" do
        expect(TodoList.count).to eq(0)

        create_todo_list title: "Hi"


        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("This is what I'm doing today.")
    end

    it "displays an error when the todo list has no descripton" do
        expect(TodoList.count).to eq(0)

        create_todo_list description: ""


        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("Grocery List")
    end

    it "displays an error when the todo list has no descripton" do
        expect(TodoList.count).to eq(0)

        create_todo_list title: "Grocery list", description: "Food"

        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("Grocery List")
    end
end

Code 2:

require 'spec_helper'

describe "Deleting todo lists"  do
    let!(:todo_list) { todo_list = TodoList.create(title: "Groceries", description: "Grocery list.") }

    it "is successful when clicking the destroy link" do
        visit "/todo_lists"

        within "#todo_list_#{todo_list.id}" do
            click_link "Destroy"
        end
        expect(page).to_not have_content(todo_list.title)
        expect(TodoList.count).to eq(0)
    end
end

13 Answers

Not quite - you're already testing for no description in the first of these two tests. That test is passing fine, exactly as you want it to.

The second test (I think) you need to say

it "displays an error when the todo list is less than three characters" do

In this test - again, I think! - you're making sure that a todo list with a description of less than 3 characters won't be saved to the database. You're passing in something you know won't be saved (i.e. a description which is knowingly too short), and you're expecting an error.

expect(page).to have_content("error")

This test is failing because the todo list description you're passing in is "Food". It has four characters - i.e. it won't kick up a failure because it's valid input for a todo list description. It is a string of four characters. To make this test pass, you'll need to either:

  • Replace "Food" with something you know to be too short - so it will fail.
  • In your model (app > models > todo_list.rb) you could change this line
 validates :description, length: { minimum: 3 }

to

 validates :description, length: { minimum: 5 }

and "Food" will be shorter than the minimum value, and therefore cause an error.

Both ways - the test will find the word "error" on the page, and your test will pass.

If you need any more clarification, please just ask :)

Blugghhh sorry. I can't believe I didn't spot this first.

You should be able to spot this. The error is in your tests. Have a really close look at the last two tests in your first code block.

If you give up, let me know :p

So here are your last two tests:

    it "displays an error when the todo list has no descripton" do
        expect(TodoList.count).to eq(0)

        create_todo_list description: ""


        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("Grocery List")
    end

    it "displays an error when the todo list has no descripton" do
        expect(TodoList.count).to eq(0)

        create_todo_list title: "Grocery list", description: "Food"

        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("Grocery List")
    end

You will see they are both testing for rejecting a todolist with no description.

  • it "displays an error when the todo list has no descripton" do

In the first test, you're actually testing for a todo list with no description - you can see this because you've set

description = ""

This test isn't failing - it's the next test, which also has the same name, which is why you're confused (I think).

The error message says:

1) Creating todo lists displays an error when the todo list has no descripton Failure/Error: expect(page).to have_content("error") expected to find text "error" in "Todo list was successfully created. Title: Grocery list Description: Food Edit | Back" # ./spec/features /todo_lists/create_spec.rb:65:in `block (2 levels) in '

Read all of it - expected "error", but found instead "title: grocery, description: food". Check out your second test where you've set description as "Food".

 create_todo_list title: "Grocery list", description: "Food"

This is the test which is failing. I don't really know what you're testing for here, but I guess it will be for a description which has less than 3 characters?

I think for this one, you'll need to post your model code too - have you set the validation for description?

Sorry what do you mean by model code, I am new to ruby.

No worries. It's the model file for the todo_lists. We won't need all of it, just the validations at the top.

app > models > todo_list.rb

Okay thank you!

 class TodoList < ActiveRecord::Base
    validates :title, presence: true
    validates :title, length: { minimum: 3 }
    validates :description, presence: true
    validates :description, length: { minimum: 3 }
end

Also do you have Skype, It would be awesome to talk with you if you want email me: rptduffy1@gmail.com

I probably wouldn't be worth skyping! I'm still very much a beginner myself.

That's looking okay to me.. now for your controller code

app > controllers > the todo list controller.

We'll only need the 'create' method I think.

class TodoListsController < ApplicationController
  before_action :set_todo_list, only: [:show, :edit, :update, :destroy]

  # GET /todo_lists
  # GET /todo_lists.json
  def index
    @todo_lists = TodoList.all
  end

  # GET /todo_lists/1
  # GET /todo_lists/1.json
  def show
  end

  # GET /todo_lists/new
  def new
    @todo_list = TodoList.new
  end

  # GET /todo_lists/1/edit
  def edit
  end

  # POST /todo_lists
  # POST /todo_lists.json
  def create
    @todo_list = TodoList.new(todo_list_params)

    respond_to do |format|
      if @todo_list.save
        format.html { redirect_to @todo_list, notice: 'Todo list was successfully created.' }
        format.json { render action: 'show', status: :created, location: @todo_list }
      else
        format.html { render action: 'new' }
        format.json { render json: @todo_list.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /todo_lists/1
  # PATCH/PUT /todo_lists/1.json
  def update
    respond_to do |format|
      if @todo_list.update(todo_list_params)
        format.html { redirect_to @todo_list, notice: 'Todo list was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @todo_list.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /todo_lists/1
  # DELETE /todo_lists/1.json
  def destroy
    @todo_list.destroy
    respond_to do |format|
      format.html { redirect_to todo_lists_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_todo_list
      @todo_list = TodoList.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def todo_list_params
      params.require(:todo_list).permit(:title, :description)
    end
end

Thank you for your help!

This is the error:

rspec ./spec/features/todo_lists/create_spec.rb:61

Code:

require 'spec_helper'

describe "Creating todo lists"  do
    def create_todo_list(options={})
        options[:title] ||= "My todo list"
        options[:description] ||= "This is my todo list."

        visit "/todo_lists"
        click_link "New Todo list"
        expect(page).to have_content("New todo_list")

        fill_in "Title", with: options[:title]
        fill_in "Description", with: options[:description]
        click_button "Create Todo list"

    end

    it "redirects to the todo list index page on success" do
        create_todo_list
        expect(page).to have_content("My todo list")
    end

    it "displays an error when the todo list has no title" do
        expect(TodoList.count).to eq(0)

        create_todo_list title: ""

        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("This is what I'm doing today.")
    end

    it "displays an error when the todo list has a title less than 3 characters" do
        expect(TodoList.count).to eq(0)

        create_todo_list title: "Hi"


        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("This is what I'm doing today.")
    end

    it "displays an error when the todo list has no descripton" do
        expect(TodoList.count).to eq(0)

        create_todo_list description: ""


        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("Grocery List")
    end

    it "displays an error when the todo list has no descripton" do
        expect(TodoList.count).to eq(0)

        create_todo_list title: "Grocery list", description: "Food"

        expect(page).to have_content("error")
        expect(TodoList.count).to eq(0)

        visit "/todo_lists"
        expect(page).to_not have_content("Grocery List")
    end
end

Take a really close look at the last two tests! You'll kick yourself I promise.

Okay, thanks.

I must be coming across as an utter fool! I can't seem to find the error!

I'll give you a pointer - look at the names of the last two tests... Anything familiar?

I can see the pattern that follows along with the rest of the code

 1) "displays an error with no title"

 1a) "displays an error with too short a title"

  2) "displays an error with no description"

  2a)  "displays an error with too short a description"

But that is as far as I got :/.

Ohhhhh.... I was looking at the wrong document! I am so foolish! Thank you so much for your time, the document I was looking at was edit_spec.rb rather than create_spec.rb that is why I was so confused! Thank you!

No worries. Do you understand why the test is failing?

Yes, I think so because it expected it to have no description and I put a description in there so that is why it failed.