Mark
Mark

Reputation: 105

Rails Tutorial Chap 5 Exercise 3 - What did the original full_title function do?

I am confused by Chap 5 Exercise 3 here that replaces the need for the full_title test helper

spec/support/utilities.rb:

def full_title(page_title)
  base_title = "Ruby on Rails Tutorial Sample App"
  if page_title.empty?
    base_title
  else
    "#{base_title} | #{page_title}"
  end
end

There is also a rails helper function by the same name:

module ApplicationHelper
  # Returns the full title on a per-page basis.
  def full_title(page_title)
    base_title = "Ruby on Rails Tutorial Sample App"
    if page_title.empty?
      base_title
    else
      "#{base_title} | #{page_title}"
    end
  end
end

by creating an application helper that test the function directly with: spec/helpers/application_helper_spec.rb

require 'spec_helper'

describe ApplicationHelper do

 describe "full_title" do
   it "should include the page title" do
     full_title("foo").should =~ /foo/
   end

   it "should include the base title" do
     full_title("foo").should =~ /^Ruby on Rails Tutorial Sample App/
   end

   it "should not include a bar for the home page" do
     full_title("").should_not =~ /\|/
   end
  end
end

This is great that it tests the rails helper function directly but I thought that the full title function in the utilities.rb was for use in the Rspec code. Therefore, how come we can eliminate the above code in utilities.rb and replace with just:

include ApplicationHelper

I made the swap and everything still worked. I was expecting Rspec code that I though was using the rspec function like the following to error but it does not:

it "should have the right links on the layout" do
  visit root_path
  click_link "About"
  page.should have_selector 'title', text: full_title('About Us')
  ...

Has the the above function call always pointed to the actual rails function and not the respec function? If I was able to eliminate it what was it for in the first place? I feel like I am missing something here. Thanks for any help. Seems like a bad idea to making changes I do not understand when my goal is to learn Rails.

Thanks, Mark

Upvotes: 4

Views: 1045

Answers (2)

7stud
7stud

Reputation: 48599

Unfortunately, the exercise says:

Eliminate the need for the full_title test helper in Listing 5.29 by writing tests for the original helper method, as shown in Listing 5.41. (You will have to create both the spec/helpers directory and the application_helper_spec.rb file.) Then include it into the test using the code in Listing 5.42.

...which is completely wrong.

Some preliminaries:

The full_title() method in app/helpers/application_helper.rb is a method that is available to regular code throughout the application--not the rspec tests. The full_title() method in spec/support/utilities.rb was added so that the rspec tests could call it.

Terminology:

application helper = the full_title method in app/helpers/application_helper.rb

rspec helper = the full_title method in spec/support/utilities.rb

Writing tests for the application helper does not eliminate the need for the rspec helper--because writing a test for one method does not magically eliminate the need for some other method. What the text should say is something like this:

You can eliminate the need for the rspec helper, which is a duplicate of the application helper, by replacing the rspec helper with the following include statement:

include ApplicationHelper

For the time being, you can pretend that including a module inserts the methods in the module at the point of the include statement. The application helper happens to be defined inside a module named ApplicationHelper--open the file app/helpers/application_helper.rb and take a look.

Next, write tests for the application helper to ensure that it works correctly.

Upvotes: 0

Sun
Sun

Reputation: 777

full_title in the specs always calls from spec/support/utilities.rb.

Before you replaced the code with include ApplicationHelper, full_title in the specs were calling the function found in utilities.rb:

def full_title(page_title)
  base_title = "Ruby on Rails Tutorial Sample App"
  if page_title.empty?
    base_title
  else
    "#{base_title} | #{page_title}"
  end
end

By replacing the code with just

include ApplicationHelper

to be clear, you are actually including

module ApplicationHelper

from helpers/application_helper.rb.

This has nothing to do with describe ApplicationHelper in spec/helpers/application_helper_spec.rb

What really happens is that the full_title function from module ApplicationHelper is now mixed in (see Mixins) to utilities.rb. Hence, utilities.rb gains access to the function full_title from module ApplicationHelper(helpers/application_helper.rb).

So, when the specs call the full_title function, it is called from utilities.rb, which is possible because the function has been mixed in via the use of include ApplicationHelper.

Upvotes: 4

Related Questions