Giter Club home page Giter Club logo

everydayrails-rspec-2017's People

Contributors

junichiito avatar ruralocity avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

everydayrails-rspec-2017's Issues

P.87 to P.88 the example "does not delete the project" should be under the context "as a guest"

So, the following should be amended from

  context "as a guest" do
    before do
      @project = FactoryGirl.create(:project)
    end

    it "returns a 302 response" do
      delete :destroy, params: { id: @project.id }
      expect(response).to have_http_status "302"
    end

    it "redirects to the sign-in page" do
      delete :destroy, params: { id: @project.id }
      expect(response).to redirect_to "/users/sign_in"
    end
  end
  
  it "does not delete the project" do
    expect {
      delete :destroy, params: { id: @project.id }
    }.to_not change(Project, :count)
  end

to

  context "as a guest" do
    before do
      @project = FactoryGirl.create(:project)
    end

    it "returns a 302 response" do
      delete :destroy, params: { id: @project.id }
      expect(response).to have_http_status "302"
    end

    it "redirects to the sign-in page" do
      delete :destroy, params: { id: @project.id }
      expect(response).to redirect_to "/users/sign_in"
    end

    it "does not delete the project" do
      expect {
        delete :destroy, params: { id: @project.id }
      }.to_not change(Project, :count)
    end
  end

Ch 5, P. 87 lines 36 - 40 are redundant

There is already an example for "does not delete the project" on p. 86, so the following code is redundant:

it "does not delete the project" do
  expect {
    delete :destroy, params: { id: @project.id }
  }.to_not change(Project, :count)
end

Chapter 2 Test::Unit

In Chapter 2, page 17,

Now that we’ve got RSpec installed, Rails’ stock generators will no longer generate the default Test::Unit files in the test directory

I think Rails generates Minitest files, not Test::Unit.

Chapter 8 Confusing failure message

Chapter 8, page 138-139,

  1. TasksController#show responds with JSON formatted output
    Failure/Error: expect(response).to_not have_content_type :json
    Expected "unknown content type (application/json)" to
    not be Content Type "application/json" (json)

The message "unknown content type (application/json)" is very confusing. I could not understand what happened for a moment. The actual content type is not "unknown" but "application/json".

content_type method expects short name like :html or :json as a parameter, so it can't be used for actual content type. I think failure_message or failure_message_when_negated should be implemented like this:

failure_message do |actual|
  "Expected \"#{actual.content_type}\" to be Content Type " +
  "\"#{content_type(expected)}\" (#{expected})"
end

Ch.2, p.33 - Missing spec "no email"

Think you skipped a spec for user_spec.rb: "is invalid without an email address". See page 33 to page 34.

Here is my version:

  it "is invalid without an email address" do
    user = User.new(
      first_name:   "Joe",
      last_name:    "Tester",
      password:     "dottle-nouveau-pavillion-tights-furze",
    )
    user.valid?
    expect(user.errors[:email]).to include("can't be blank")
  end

Also will need to update bottom of page 46.

Chapter 2 factories?

In Chapter 2, page 20,

Optionally, configure Rails’ generators to use RSpec, so that as you add new models and controllers to your application, you’ll be able to use the generators in your development workflow, and automatically be given starter files for
your specs and factories.

At this point, factories is not described in details, so readers might be confused.

P.97 typo

The filename should be Gemfile instead of config/application.rb

Chapter 6 page 98

click_button has no guarantee that any actions triggered by it will have completed when it returns. Because of this you should have an expectation after it that verifies/waits until the action has completed. In the example on page 98 that means moving at least one of the expectations inside the change block. Without that change the test will be flaky with some drivers.

expect {
    click_link "New Project"
    fill_in "Name", with: "Test Project"
    fill_in "Description", with: "Trying out Capybara"
    click_button "Create Project"
    expect(page).to have_content "Project was successfully created"
    expect(page).to have_content "Test Project"
    expect(page).to have_content "Owner: #{user.name}"
}.to change(user.projects, :count).by(1)

Chapter 5 change matcher

In Chapter 5,

You used change matcher for the first time, but there is no description about it. It should be described for beginners.

Chapter 3 @note1 and @note1?

In Chapter 3, page 47

we used @note1 and @note1 as test notes

@note1 and @note1 should be @note1 and @note2 or anything, right?

Chapter 10 "include the matchers"

Chapter 10, page 169,

First, include the matchers near the top of the file:

I think "require the matchers" is easier to understand the following code.

Chapter 10 Why using regexp?

Chapter 10, page 177,

expect(mail.body).to match(/Hello #{user.first_name},/)

I am not sure why you used regexp here. I think using string is simpler:

expect(mail.body).to match "Hello #{user.first_name},"

Chapter 8 additional examples?

Chapter 8, page 141,

But in version 3.3, RSpec gained the ability to aggregate failures, so that additional examples can continue to run and, perhaps, provide some extra context for the failure.

Perhaps "additional examples" should be "additional expectations".

Chapter 4 p. 64 testing late status fails

I implemented the model specs testing the late status of a project on p.64. I cloned the first chapter and followed along for chapter 2,3 and 4. But when I run the spec "is late when the due date is past today" I get this failure message:

Failure/Error: expect(project).to be_late │
expected #<Project id: 1, name: "Project 2", description:
"Sample project for testing purposes", due_on: "2017-07-04", created_at: "2017-07-05 07:30:40", updated_at: "2017-07-05 07:30:40", user_id: 1> to respond to late?

I suppose these test should pass, but I not sure why they are failing.

Check Paperclip for update

If you enable warnings in spec output, you'll see numerous warnings from the Paperclip gem. These are not caused by specs, but are noisy and can cause confusion for people beginning to learn testing. I think they're caused by changes in either Rails or Ruby. I opted to move forward with Paperclip in spite of the warnings, and will review its status to see if the warnings have been addressed.

Chapter 6 JavaScript Driver

I couldn't get :selenium_chrome to work at all with the given instructions. It kept saying the driver couldn't be found. I finally came across the chromedriver-helper gem. Followed their instructions and it worked great. Maybe it was just my setup on macOS Sierra, but thought I'd share anyhow.

Chapter 8: Typos and Type Issues

Everyday Rails Testing with RSpec: September 18th, 2017
format: mobi

Support Modules

8th paragraph, last sentence:

"In other Words, we’re testing project-specific functionality here, not user or login-specific functionality.”

4th word has unicode characters in place of the apostrophe

2nd and 3rd code block after 8th paragraph (1st code block being spec/rails_helper.rb)

spec/features/projects_feature.spec

should be spec/features/projects_spec.rb

Lazy-loading with let

3rd paragraph, 1st sentence:

“To demonstrate, let’s create a model spec for the Task model, since we haven’t done that yet.”

another case of apostrophe being replaced with unicode charcters in haven't

Ch6 P.105 to P.106 Typo

The text used as selector should "RSpec Tutorial" instead of "RSpec tutorial" (capital T), otherwise the test will fail.
i.e. the code should change from

require 'rails_helper'

RSpec.feature "Tasks", type: :feature do
  scenario "user toggles a task", js: true do
    user = FactoryGirl.create(:user)
    project = FactoryGirl.create(:project,
      name: "RSpec tutorial",
      owner: user)
    task = project.tasks.create!(name: "Finish RSpec tutorial")

    visit root_path
    click_link "Sign in"
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    click_button "Log in"

    click_link "RSpec tutorial"
    check "Finish RSpec tutorial"

    expect(page).to have_css "label#task_#{task.id}.completed"
    expect(task.reload).to be_completed

    uncheck "Finish RSpec tutorial"

    expect(page).to_not have_css "label#task_#{task.id}.completed"
    expect(task.reload).to_not be_completed
  end
end

to

require 'rails_helper'

RSpec.feature "Tasks", type: :feature do
  scenario "user toggles a task", js: true do
    user = FactoryGirl.create(:user)
    project = FactoryGirl.create(:project,
      name: "RSpec tutorial",
      owner: user)
    task = project.tasks.create!(name: "Finish RSpec tutorial")

    visit root_path
    click_link "Sign in"
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    click_button "Log in"

    click_link "RSpec Tutorial"
    check "Finish RSpec tutorial"

    expect(page).to have_css "label#task_#{task.id}.completed"
    expect(task.reload).to be_completed

    uncheck "Finish RSpec tutorial"

    expect(page).to_not have_css "label#task_#{task.id}.completed"
    expect(task.reload).to_not be_completed
  end
end

Chapter 9 Indentation in Gemfile

Chapter 9, page 152,

group :test do
gem 'capybara', '~> 2.15.4' 
gem 'selenium-webdriver' 
gem 'launchy', '~> 2.4.3'
  gem 'shoulda-matchers',
    git: 'https://github.com/thoughtbot/shoulda-matchers.git',
    branch: 'rails-5'
end

It should be:

group :test do
  gem 'capybara', '~> 2.15.4' 
  gem 'selenium-webdriver' 
  gem 'launchy', '~> 2.4.3'
  gem 'shoulda-matchers',
    git: 'https://github.com/thoughtbot/shoulda-matchers.git',
    branch: 'rails-5'
end

Ch.3, p.38 to 39 - Note.search scope is case sensitive

Not to spam you, but found another slight error.

In note.rb, the search scope is case sensitive:

  scope :search, ->(term) {
    where("message LIKE ?", "%#{term}%")
  }

Which breaks the search term spec, since note3 has a capital F:

    note3 = project.notes.create(
      message: "First, preheat the oven.",
      user: user
    )

Perhaps change the scope in note.rb to:

  scope :search, ->(term) {
    where("LOWER(message) LIKE ?", "%#{term}%")
  }

Chapter 10 "attachment.jpg (image/jpeg" is confusing

Chapter 10, page 167

expect(page).to have_content "attachment.jpg (image/jpeg"

I thought it should be "attachment.jpg (image/jpeg)" but the actual string was attachment.jpg (image/jpeg, 14.5 KB).

However, it is still confusing, so I suggest:

expect(page).to have_content "attachment.jpg"

or

expect(page).to have_content /attachment\.jpg \(image\/jpeg, [\d\w\s.]+\)/

Task controller specs pass unnecessary data to create action (Ch. 5, p. 92)

The examples in the describe #create block do not need id: @task.id to be passed along. For example, the first example should look like

it "responds with JSON formatted output" do
      new_task = { name: "New test task" }
      sign_in @user
      post :create, format: :json,
        params: { project_id: @project.id, task: new_task }
      expect(response.content_type).to eq "application/json"
end

I'll include the fixed versions in the next release.

Chapter 4 create tasks?

In Chapter 4, page 66

Let’s add a callback to automatically create tasks on a new project.

"create tasks" should be "create notes", correct?

Chapter 6 - page 110 - find_button(...).click

The text and example appear to imply that only the find methods will wait for elements to appear. The actions methods like click_button will also wait since they are implemented as find(...).click. Therefore recommending find_button('Close').click over click_button('Close') doesn't make sense.

[request/issue]: Expectations Using Procs

Specifically discussing the test environment is there anything to be aware of aside from the usual use of procs? In the feature spec chapter, they are referred to as “the expect{} Proc we checked out in chapter 5” (controller specs), but they are not discussed in that chapter, just used obscurely.

Huge thanks for this book!

Chapter 8 CONTENT_TYPES hash

Chapter 8, page 135,

CONTENT_TYPES hash

Why is CONTENT_TYPES written in uppercase? Maybe it should be content_types.

P.105 typo

The directory should be spec/support instead of spec_support

[request]: Request Tests when testing Table-less Data

I'm very curious to hear your thoughts on testing data that changes outside of the database, but is used above the model level. I know with request tests this would go against your practice of the skinny controller layout, but surely I'm not the only dev that has been put in front of a project where this is the case.

Along the same lines, Services are always easy as they can be included and tested in their own model/unit-tests, but request tests when working with such services where the return values come back to the frontend and not that obvious. I guess as long as there was a good known way to corner the data with a proc, that would be a great start.

EDIT: Just to give an idea of what I'm doing now for these cases, I'm using the rails-controller-testing gem to have access to the assigns method so that I can grab the instance variable and test against the data going in with the data being returned (in the assigns). I don't like to do this, since they are depreciated, and why I ask what can be done instead.

Thanks for everything, and I hope you consider this request!

Chapter 10 DRY testing techniques?

Chapter 10, page 173,

You could also experiment with DRY testing techniques from chapter 8, should you have tests across multiple files requiring the test queue.

I am not sure what "DRY testing techniques from chapter 8" is. You mean using shared_context, right?

Separate test-only gems into their own group

As of chapter 9, group :development, :test includes

group :development, :test do
  gem 'rspec-rails', '~> 3.6.0'
  gem 'factory_girl_rails', '~> 4.8.0'
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'capybara', '~> 2.14.0'
  gem 'selenium-webdriver'
  # Or use poltergeist and PhantomJS as an alternative to Selenium/Chrome
  # gem 'poltergeist', '~> 1.15.0'
  gem 'launchy', '~> 2.4.3'
  gem 'shoulda-matchers',
    git: 'https://github.com/thoughtbot/shoulda-matchers.git',
    branch: 'rails-5'
end

Everything after byebug should be able to go in a standalone group :test, but I need to confirm. This will be addressed in a future release.

Ch.3, p.36 - second test of project_spec.rb fails (missing owner attribute)

From project_spec.rb:

it "allows two users to share a project name" do
    user = User.create(
      first_name:   "Joe",
      last_name:    "Tester",
      email:        "[email protected]",
      password:     "dottle-nouveau-pavillion-tights-furze",
    )

    user.projects.create(
      name: "Test Project",
    )

    other_user = User.create(
      first_name:   "Jane",
      last_name:    "Tester",
      email:        "[email protected]",
      password:     "dottle-nouveau-pavillion-tights-furze",
    )

    other_project = other_user.projects.build(
      name: "Test Project"
    )
    expect(other_project).to be_valid
  end

I get:

1) Project allows two users to share a project name
     Failure/Error: expect(other_project).to be_valid
       expected #<Project id: nil, name: "Test Project", description: nil, due_on: nil, created_at: nil, updated_at: nil, user_id: nil> to be valid, but got errors: Owner must exist

Code matches the book. Guess we're missing a user_id, although calling projectson other_user should have done the trick.

shoulda-matchers install fails

Solution: See shoulda-matchers#1057 for full discussion


Solution Text

Yes, we rebased rails-5 and then merged it into master. Sorry for the mess -- it won't happen again!

For anyone else who found this, we fixed this by deleting the revision sha from our Gemfile.lock and re-ran bundle install.

Be advised that we will remove rails-5 at a certain point, so I would recommend switching to master now if you really want to continue being on the bleeding edge :)


It fails with following error log

Fetching https://github.com/thoughtbot/shoulda-matchers.git
fatal: Could not parse object '0b2e0da6035b9c45b0430bc6eb9a8bab4aeba50e'.
Git error: command `git reset --hard 0b2e0da6035b9c45b0430bc6eb9a8bab4aeba50e`
in directory
C:/Ruby24-x64/lib/ruby/gems/2.4.0/bundler/gems/shoulda-matchers-0b2e0da6035b has
failed.
If this error persists you could try removing the cache directory
'C:/Ruby24-x64/lib/ruby/gems/2.4.0/cache/bundler/git/shoulda-matchers-e04e9ade87805b3667f97d976fd84556605e66f8'

Process finished with exit code 11

Ch7 P.114 line 29 - missing code

The code should be

expect(json[0]["name"]).to eq "Second Sample Project"

instead of

expect(json["name"]).to eq "Second Sample Project"

Ch.4, p.58 - Wrong association

FactoryGirl.definedo factory :note do
  message "My important note."
  association :project
  association :note
end end

should be

FactoryGirl.definedo factory :note do
  message "My important note."
  association :project
  association :user
end end

otherwise, we will get this validation error:

FactoryGirl::AssociationDefinitionError:
       Self-referencing association 'note' in 'note'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.