(I commented on your gist but I'll comment here as well for completeness.)
It might be a bit easier for your brain if you think of specs not as "Ruby-language scripts", but as "RSpec-language scripts", a language which is a superset of Ruby.
RSpec is a DSL — domain-specific language — on top of Ruby. It purposely pollutes the top-level namespace with shorthand methods so that you don't have to qualify them. Yes, the range of what is available is essentially something you will need to hunt down in the documentation. And yes, the available shorthands are also dependent on what RSpec extensions you have installed; things like WebMock extend the namespace with its own methods.
After the confusion settles I think you will find that the reduced syntax is very helpful. It removes boilerplate to a large extent. In a more verbose test framework such as Test::Unit, developers always move common boilerplate (eg., test setup, common mocks) into test-wide helpers. RSpec just sets the table in a way that also reduces common test boilerplate.
For example, surely `describe Foo` is better than `class FooTest < Test::Unit::TestCase` — even if you don't understand what `describe` really does or where it comes from. You don't need to if you accept it's RSpec syntax.
And surely you will agree that this:
get "/"
last_response.status.should eq 200
...more concisely expresses the intent of the test than this:
I personally quite like writing assertions as infix-style expressions (`x.should y`) rather than assertions (`assert_equal`). One reason is the wonderful flexibility in choosing what goes on the left and right sides:
You are going about this all wrong. If you are still struggling with ruby the language, you shouldn't be learning at the same time one of the most opinionated DSLs around (rspec), because it will confuse the hell out of a beginner rubyist
I agree with you that RSpec is confusing as hell - thus the blog post.
A lot of my frustration with Ruby tutorials is that a large pack of them are geared for someone who has never, ever coded before. Syntactically, Ruby isn't that bad. I tried a few courses in Ruby and eventually just switched them off for being too slow.
Part of my issue with Ruby (currently) is that the language can be so flagrantly violated with a gem. I am sure that Python could receive similar treatment... but it would be difficult to pull off, and the community would rip it apart for not being "Pythonic." There's not as strong of a "Ruby-ic" approach to doing things as there is with Python, from my first interactions with the language.
In the Ruby webdev community, RSpec and Devise are considered to be the most Ruby-ic gems around. The idea, much as with Lisp, is to transform the language into something that describes the problem at hand as naturally as possible. RSpec is considered to be a fine example of a language designed for writing software specifications, and it still happens to be valid Ruby.
One of the take-aways from this is that within the Python community, "Pythonic" means "keep close to the language as envisioned by GVR", and within the Ruby community, "Ruby-ic" means "the closer you can get it to English and still keep the code executing, the better."
I personally dislike RSpec, but that's a minority opinion. I dislike the general aim to make everything look as natural as possible, because that approach hides too much complexity, a lot of which leaks often in unpredictable ways. Nevertheless, when it comes to pumping out websites, Ruby is my language of choice, and my efficiency in Rails smokes my efficiency in everything else out of the water.
Your second paragraph was huge for me. I think that's a critical learning point for someone making the jump from Python to Ruby.
I'll probably still have some frustrations, but knowing that gems are written to look natural by design rather than by accident will likely keep me from throwing my computer at the wall. Two completely different communities operating here.
I happen to think that people that say "ruby and python are really similar languages, I don't understand what the arguing is about" almost willfully ignore the fact that in modern (aka Lego) programming, a language doesn't exist on its own, but it is surrounded by a huge community, and in case of Ruby vs Python, the communities couldn't be more different.
You don't have to use the rspec controller matches if it's outside of what you're used to/how you understand it. You can use response.status.should == 200.
Thanks for the feedback. It looks like there were plenty of approaches to doing easy unit tests... which is part of why I kept scratching my head with "why the hell did they do that..."
It might be a bit easier for your brain if you think of specs not as "Ruby-language scripts", but as "RSpec-language scripts", a language which is a superset of Ruby.
RSpec is a DSL — domain-specific language — on top of Ruby. It purposely pollutes the top-level namespace with shorthand methods so that you don't have to qualify them. Yes, the range of what is available is essentially something you will need to hunt down in the documentation. And yes, the available shorthands are also dependent on what RSpec extensions you have installed; things like WebMock extend the namespace with its own methods.
After the confusion settles I think you will find that the reduced syntax is very helpful. It removes boilerplate to a large extent. In a more verbose test framework such as Test::Unit, developers always move common boilerplate (eg., test setup, common mocks) into test-wide helpers. RSpec just sets the table in a way that also reduces common test boilerplate.
For example, surely `describe Foo` is better than `class FooTest < Test::Unit::TestCase` — even if you don't understand what `describe` really does or where it comes from. You don't need to if you accept it's RSpec syntax.
And surely you will agree that this:
...more concisely expresses the intent of the test than this: I personally quite like writing assertions as infix-style expressions (`x.should y`) rather than assertions (`assert_equal`). One reason is the wonderful flexibility in choosing what goes on the left and right sides: Or: