Skip to content

Commit

Permalink
Merge pull request #2727 from threeplanetssoftware/update-documentati…
Browse files Browse the repository at this point in the history
…on-for-code-blocks

Improve code blocks in documentation
  • Loading branch information
JonRowe committed Feb 23, 2024
1 parent 38aef20 commit 129bcc5
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 115 deletions.
4 changes: 3 additions & 1 deletion features/Generators.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down
38 changes: 28 additions & 10 deletions features/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,62 @@

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
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:

Expand Down
20 changes: 14 additions & 6 deletions features/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ for even older versions.

## Install

gem install rspec-rails
```console
gem install rspec-rails
```

This installs the following gems:

Expand All @@ -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

Expand Down
76 changes: 43 additions & 33 deletions features/Transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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.
48 changes: 26 additions & 22 deletions features/controller_specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
```
28 changes: 15 additions & 13 deletions features/mailer_specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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(["[email protected]"])
expect(mail.from).to eq(["[email protected]"])
end
it "renders the headers" do
expect(mail.subject).to eq("Signup")
expect(mail.to).to eq(["[email protected]"])
expect(mail.from).to eq(["[email protected]"])
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
```
20 changes: 13 additions & 7 deletions features/matchers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
```
22 changes: 12 additions & 10 deletions features/model_specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Loading

0 comments on commit 129bcc5

Please sign in to comment.