I'm working on Rails Tutorial Chapter 11 ex 2
The tutorial asks to complete the test by replacing the FILL_IN variables to check for the number of microposts (which could be any number)
test "micropost sidebar count" do
log_in_as(@user)
get root_path
assert_match "#{FILL_IN} microposts", response.body
# User with zero microposts
other_user = users(:mallory)
log_in_as(other_user)
get root_path
assert_match "0 microposts", response.body
other_user.microposts.create!(content: "A micropost")
get root_path
assert_match FILL_IN, response.body
end
In the first FILL_IN I added in a regex for any number /^[1-9]\d*$/
and tries to interpolating it by assigning it to a variable as follows
regex_number = /^[1-9]\d*$/
assert_match "#{regex_number } microposts", response.body
This is not working for me (there are 34 microposts in the response body for my fixtures)
I checked the regex using a tool and there should be a match for 34
Last thing, how do you check a match for plurals like micropost(s) This is because the final FILL_IN is for "1 micropost"
You shouldn't use regex in this exercise. But let's take this step by step:
First of all, I don't think regex will work in quotes. After interpolation, your code reads assert_match "/^[1-9]\d*$/ microposts", response.body
. For assert_match, you either want a regex OR a string to match, not both. You should drop the interpolation, remove the quotes, and put 'microposts' inside the regex.
Secondly, I think your regex is broken for this context. '^' matches the beginning of a string, and '$' matches the end of a string, but the assert_match is comparing your regex to only one string: the entire body of the home page! You don't really care where the match is, as long as it exists somewhere in the string. This makes the start and end anchors inappropriate for that search.
Here's a version of your regex that passes this test:
assert_match(/[1-9]\d microposts/, response.body)
But this is far too generic for what this test is intended to accomplish. You don't want to look for just any number on the page. You want to look for the correct number of microposts displaying just before the word 'microposts'.
Looking around the web, this is how most people are completing the FILL_INs for this exercise:
assert_match "#{@user.microposts.count} microposts", response.body
and
assert_match "#{other_user.microposts.count} micropost", response.body
Some even simply filled in the number they expect the test to find rather than looking at the User object for the number, but I think that's too easy to break, and probably not what Hartl intended.
As for Pluralize... I pounded my head against this problem for quite a while. After much agony, I finally found two ways to do it. And I honestly don't think Hartl intended us to use it in this test, because he never used it in a test before. I think he intended for us to directly put the correct pluralization in the search strings as demonstrated above.
Anyway, here are two ways to complete the second FILL_IN with a pluralization method if you really want to do it this way:
assert_match "#{other_user.microposts.count} micropost".pluralize(other_user.microposts.count), response.body
or
assert_match ActionController::Base.helpers.pluralize(other_user.microposts.count, "micropost"), response.body
In practice, you might want to improve readability by doing something like this:
num = other_user.microposts.count
assert_match "#{num} micropost".pluralize(num), response.body