diff --git a/features/Generators.md b/features/Generators.md index f3a6ef2f1..61fc83fec 100644 --- a/features/Generators.md +++ b/features/Generators.md @@ -10,7 +10,9 @@ out of the box for with Rails' defaults. RSpec generators can also be run independently. For instance, - rails generate rspec:model widget +```console +rails generate rspec:model widget +``` will create a new spec file in `spec/models/widget_spec.rb`. diff --git a/features/GettingStarted.md b/features/GettingStarted.md index 7e251ed6e..0f3ea7938 100644 --- a/features/GettingStarted.md +++ b/features/GettingStarted.md @@ -2,28 +2,40 @@ Install Rails 6 - $ gem install rails -v "~> 6.0.0" +```console +$ gem install rails -v "~> 6.0.0" +``` ### Generate an app - $ rails new example_app - $ cd example_app +```console +$ rails new example_app +$ cd example_app +``` ### Add `rspec-rails` to the Gemfile - $ echo 'gem "rspec-rails", group: [:development, :test]' >> Gemfile +```console +$ echo 'gem "rspec-rails", group: [:development, :test]' >> Gemfile +``` ### Install the bundle - $ bundle install +```console +$ bundle install +``` ### Bootstrap RSpec - $ rails generate rspec:install +```console +$ rails generate rspec:install +``` ### Generate a scaffold - $ rails generate scaffold Widget name:string +```console +$ rails generate scaffold Widget name:string +``` This generates files in the `app` and `spec` directories. The files in the `app` directory are generated by Rails, and Rails delegates the generation of @@ -31,15 +43,21 @@ the files in the `spec` directory to RSpec. ### Run migrations - $ rails db:migrate && rails db:test:prepare +```console +$ rails db:migrate && rails db:test:prepare +``` ### Run RSpec - $ rake spec +```console +$ rake spec +``` or - $ rspec spec --format documentation +```console +$ rspec spec --format documentation +``` If all went well, you should see output ending with: diff --git a/features/README.md b/features/README.md index 5fb816609..e60cff5d2 100644 --- a/features/README.md +++ b/features/README.md @@ -15,7 +15,9 @@ for even older versions. ## Install - gem install rspec-rails +```console +gem install rspec-rails +``` This installs the following gems: @@ -29,23 +31,29 @@ This installs the following gems: Add rspec-rails to the :test and :development groups in the Gemfile: - group :test, :development do - gem 'rspec-rails', '~> 6.0.0' - end +```ruby +group :test, :development do + gem 'rspec-rails', '~> 6.0.0' +end +``` It needs to be in the :development group to expose generators and rake tasks without having to type RAILS_ENV=test. Now you can run: - bundle exec rails generate rspec:install +```console +bundle exec rails generate rspec:install +``` This adds the spec directory and some skeleton files, including a .rspec file. You can also customize the default spec path with `--default-path` option: - bundle exec rails generate rspec:install --default-path behaviour +```console +bundle exec rails generate rspec:install --default-path behaviour +``` ## Issues diff --git a/features/Transactions.md b/features/Transactions.md index 8dfc8cf55..1fcc34fcb 100644 --- a/features/Transactions.md +++ b/features/Transactions.md @@ -3,9 +3,11 @@ When you run `rails generate rspec:install`, the `spec/rails_helper.rb` file includes the following configuration: - RSpec.configure do |config| - config.use_transactional_fixtures = true - end +```ruby +RSpec.configure do |config| + config.use_transactional_fixtures = true +end +``` The name of this setting is a bit misleading. What it really means in Rails is "run every test method within a transaction." In the context of rspec-rails, @@ -21,9 +23,11 @@ If you prefer to manage the data yourself, or using another tool like [database_cleaner](https://github.com/bmabey/database_cleaner) to do it for you, simply tell RSpec to tell Rails not to manage transactions: - RSpec.configure do |config| - config.use_transactional_fixtures = false - end +```ruby +RSpec.configure do |config| + config.use_transactional_fixtures = false +end +``` ### Data created in `before(:example)` are rolled back @@ -32,19 +36,21 @@ the example. This is a good thing because it means that each example is isolated from state that would otherwise be left around by the examples that already ran. For example: - describe Widget do - before(:example) do - @widget = Widget.create - end +```ruby +describe Widget do + before(:example) do + @widget = Widget.create + end - it "does something" do - expect(@widget).to do_something - end + it "does something" do + expect(@widget).to do_something + end - it "does something else" do - expect(@widget).to do_something_else - end - end + it "does something else" do + expect(@widget).to do_something_else + end +end +``` The `@widget` is recreated in each of the two examples above, so each example has a different object, _and_ the underlying data is rolled back so the data @@ -60,27 +66,31 @@ guidelines: 1. Be sure to clean up any data in an `after(:context)` hook: - before(:context) do - @widget = Widget.create! - end + ```ruby + before(:context) do + @widget = Widget.create! + end - after(:context) do - @widget.destroy - end + after(:context) do + @widget.destroy + end + ``` If you don't do that, you'll leave data lying around that will eventually - interfere with other examples. +interfere with other examples. 2. Reload the object in a `before(:example)` hook. - before(:context) do - @widget = Widget.create! - end + ```ruby + before(:context) do + @widget = Widget.create! + end - before(:example) do - @widget.reload - end + before(:example) do + @widget.reload + end + ``` - Even though database updates in each example will be rolled back, the - object won't _know_ about those rollbacks so the object and its backing - data can easily get out of sync. +Even though database updates in each example will be rolled back, the +object won't _know_ about those rollbacks so the object and its backing +data can easily get out of sync. diff --git a/features/controller_specs/README.md b/features/controller_specs/README.md index 39ba99c54..fdf678576 100644 --- a/features/controller_specs/README.md +++ b/features/controller_specs/README.md @@ -42,21 +42,23 @@ To specify outcomes, you can use: ## Examples - RSpec.describe TeamsController do - describe "GET index" do - it "assigns @teams" do - team = Team.create - get :index - expect(assigns(:teams)).to eq([team]) - end - - it "renders the index template" do - get :index - expect(response).to render_template("index") - end - end +```ruby +RSpec.describe TeamsController do + describe "GET index" do + it "assigns @teams" do + team = Team.create + get :index + expect(assigns(:teams)).to eq([team]) end + it "renders the index template" do + get :index + expect(response).to render_template("index") + end + end +end +``` + ## Views * by default, views are not rendered. See @@ -67,14 +69,16 @@ To specify outcomes, you can use: We encourage you to use [request specs](./request-specs/request-spec) if you want to set headers in your call. If you still want to use controller specs with custom http headers you can use `request.headers`: - require "rails_helper" +```ruby +require "rails_helper" - RSpec.describe TeamsController, type: :controller do - describe "GET index" do - it "returns a 200" do - request.headers["Authorization"] = "foo" - get :show - expect(response).to have_http_status(:ok) - end - end +RSpec.describe TeamsController, type: :controller do + describe "GET index" do + it "returns a 200" do + request.headers["Authorization"] = "foo" + get :show + expect(response).to have_http_status(:ok) end + end +end +``` diff --git a/features/mailer_specs/README.md b/features/mailer_specs/README.md index 555cc4851..ea14570e4 100644 --- a/features/mailer_specs/README.md +++ b/features/mailer_specs/README.md @@ -9,20 +9,22 @@ behavior and expectations. ## Examples - require "rails_helper" +```ruby +require "rails_helper" - RSpec.describe Notifications, type: :mailer do - describe "notify" do - let(:mail) { Notifications.signup } +RSpec.describe Notifications, type: :mailer do + describe "notify" do + let(:mail) { Notifications.signup } - it "renders the headers" do - expect(mail.subject).to eq("Signup") - expect(mail.to).to eq(["to@example.org"]) - expect(mail.from).to eq(["from@example.com"]) - end + it "renders the headers" do + expect(mail.subject).to eq("Signup") + expect(mail.to).to eq(["to@example.org"]) + expect(mail.from).to eq(["from@example.com"]) + end - it "renders the body" do - expect(mail.body.encoded).to match("Hi") - end - end + it "renders the body" do + expect(mail.body.encoded).to match("Hi") end + end +end +``` diff --git a/features/matchers/README.md b/features/matchers/README.md index 78810444b..1fc7b5388 100644 --- a/features/matchers/README.md +++ b/features/matchers/README.md @@ -5,16 +5,22 @@ rspec-compatible wrappers for Rails' assertions. ### redirects - # delegates to assert_redirected_to - expect(response).to redirect_to(path) +```ruby +# delegates to assert_redirected_to +expect(response).to redirect_to(path) +``` ### templates - # delegates to assert_template - expect(response).to render_template(template_name) +```ruby +# delegates to assert_template +expect(response).to render_template(template_name) +``` ### assigned objects - # passes if assigns(:widget) is an instance of Widget - # and it is not persisted - expect(assigns(:widget)).to be_a_new(Widget) +```ruby +# passes if assigns(:widget) is an instance of Widget +# and it is not persisted +expect(assigns(:widget)).to be_a_new(Widget) +``` diff --git a/features/model_specs/README.md b/features/model_specs/README.md index 418a4a303..820c3ac24 100644 --- a/features/model_specs/README.md +++ b/features/model_specs/README.md @@ -9,15 +9,17 @@ behavior and expectations. ## Examples - require "rails_helper" +```ruby +require "rails_helper" - RSpec.describe Post, type: :model do - context "with 2 or more comments" do - it "orders them in reverse chronologically" do - post = Post.create! - comment1 = post.comments.create!(:body => "first comment") - comment2 = post.comments.create!(:body => "second comment") - expect(post.reload.comments).to eq([comment2, comment1]) - end - end +RSpec.describe Post, type: :model do + context "with 2 or more comments" do + it "orders them in reverse chronologically" do + post = Post.create! + comment1 = post.comments.create!(:body => "first comment") + comment2 = post.comments.create!(:body => "second comment") + expect(post.reload.comments).to eq([comment2, comment1]) end + end +end +``` diff --git a/features/request_specs/request_spec.feature b/features/request_specs/request_spec.feature index 1a27f7a5a..d1f915db6 100644 --- a/features/request_specs/request_spec.feature +++ b/features/request_specs/request_spec.feature @@ -17,8 +17,10 @@ Feature: Request specs RSpec provides two matchers that delegate to Rails assertions: - render_template # delegates to assert_template - redirect_to # delegates to assert_redirected_to + ```ruby + render_template # delegates to assert_template + redirect_to # delegates to assert_redirected_to + ``` Check the Rails docs for details on these methods as well. diff --git a/features/routing_specs/README.md b/features/routing_specs/README.md index fc8922be9..8695c85f3 100644 --- a/features/routing_specs/README.md +++ b/features/routing_specs/README.md @@ -7,12 +7,16 @@ Simple apps with nothing but standard RESTful routes won't get much value from routing specs, but they can provide significant value when used to specify customized routes, like vanity links, slugs, etc. - expect(:get => "/articles/2012/11/when-to-use-routing-specs").to route_to( - :controller => "articles", - :month => "2012-11", - :slug => "when-to-use-routing-specs" - ) +```ruby +expect(:get => "/articles/2012/11/when-to-use-routing-specs").to route_to( + :controller => "articles", + :month => "2012-11", + :slug => "when-to-use-routing-specs" +) +``` They are also valuable for routes that should not be available: - expect(:delete => "/accounts/37").not_to be_routable +```ruby +expect(:delete => "/accounts/37").not_to be_routable +``` diff --git a/features/routing_specs/route_to_matcher.feature b/features/routing_specs/route_to_matcher.feature index 4253dd3d2..19ed0fd49 100644 --- a/features/routing_specs/route_to_matcher.feature +++ b/features/routing_specs/route_to_matcher.feature @@ -4,11 +4,14 @@ Feature: `route_to` matcher It is most valuable when specifying routes other than standard RESTful routes. - expect(get("/")).to route_to("welcome#index") # new in 2.6.0 - - or - - expect(:get => "/").to route_to(:controller => "welcome") + ```ruby + expect(get("/")).to route_to("welcome#index") # new in 2.6.0 + ``` + or + + ```ruby + expect(:get => "/").to route_to(:controller => "welcome") + ``` Scenario: Passing route spec with shortcut syntax Given a file named "spec/routing/widgets_routing_spec.rb" with: