rspec-tapas 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +304 -0
- data/VERSION +1 -1
- data/lib/rspec_tapas/behavior_dsl.rb +30 -14
- data/rspec-tapas.gemspec +5 -5
- metadata +4 -4
- data/README.rdoc +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac612ac4ea7957a55f94f98fe712c54e47d0e1c0
|
4
|
+
data.tar.gz: e588c6af989d560c2979566309555d4954031029
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 063ab3599b8834d5a79864716c0ae2c2159c95b604f57351fac1fe19899afc7fe3b03b72131053cb97b3279871bd8d064a4f8f90b3c23382e12b85d063a92f28
|
7
|
+
data.tar.gz: 773b4f7ffc6013d08f8eb6ce59d8d89c6e3f715222575a2fea861b123a0d19f370f44adab00e215545f36f1cc8dd2b2e32c86084ab32f4b960ff9a7754e49b61
|
data/README.md
ADDED
@@ -0,0 +1,304 @@
|
|
1
|
+
# rspec-tapas
|
2
|
+
|
3
|
+
rspec-tapas is a set of small helpers and extensions we often use in [Selleo](https://selleo.com/) when testing our ruby apps.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
To install rspec-tapas just add following line to your `Gemfile`s `:test` group
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'ruby-tapas'
|
11
|
+
```
|
12
|
+
|
13
|
+
then just `bundle install` and require it in `rails_helper.rb`
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require 'rspec_tapas/all'
|
17
|
+
```
|
18
|
+
|
19
|
+
## Helpers
|
20
|
+
|
21
|
+
### StubEnv
|
22
|
+
|
23
|
+
`StubEnv` is an extension that allows you to quickly stub values that should be retrieved from `ENV`.
|
24
|
+
It is assumed here, that you will use `fetch` method to retrieve such value (so it yields an exception when given ENV is not defined what sounds like a reasonable default).
|
25
|
+
|
26
|
+
*Example*
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
it 'sends a notification after checkout' do
|
30
|
+
stub_env('CHECKOUT_TIME', '13:00')
|
31
|
+
#...
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
To include this extension only, call `require rspec_tapas/stub_env`
|
36
|
+
|
37
|
+
`StubEnv` is accessible in all types of specs
|
38
|
+
|
39
|
+
### DateHelpers
|
40
|
+
|
41
|
+
`DateHelpers` is a set of two methods that facilitate using `ActiveSupport::Testing::TimeHelpers`. Therefore you need to include `ActiveSupport::Testing::TimeHelpers` in your config if you want to use `DateHelpers`. It is as simple as
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
RSpec.configure do |config|
|
45
|
+
config.include ActiveSupport::Testing::TimeHelpers
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
#### at_date
|
50
|
+
|
51
|
+
`at_date` runs contents of the block at given date, provided in a format acceptable by `Date.new`. It is basically a shortcut to `travel_to(Date.new(*args)){}`.
|
52
|
+
|
53
|
+
*Example*
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
context 'one day before deadline' do
|
57
|
+
it 'sends a reminder' do
|
58
|
+
#...
|
59
|
+
at_date(2018, 1, 12) do
|
60
|
+
SendPendingReminders.call
|
61
|
+
end
|
62
|
+
#...
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
#### freeze_time
|
68
|
+
|
69
|
+
`freeze_time` freezes the time and runs contents of the block at. It is basically a shortcut to `travel_to(Time.current){}`.
|
70
|
+
|
71
|
+
*Example*
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
it 'discards records created at the same time' do
|
75
|
+
#...
|
76
|
+
freeze_time do
|
77
|
+
user_1 = create(:user)
|
78
|
+
user_2 = create(:user)
|
79
|
+
end
|
80
|
+
#...
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
To include this extension only, call `require rspec_tapas/date_helpers`
|
85
|
+
|
86
|
+
`DateHelpers` are accessible in all types of specs
|
87
|
+
|
88
|
+
### ViewPage
|
89
|
+
|
90
|
+
`ViewPage` is a small helper that allows testing views using capybara helpers, usually limited only to feature specs.
|
91
|
+
|
92
|
+
*Example*
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
RSpec.describe 'users/show.html.erb', type: :view do
|
96
|
+
it 'renders user name' do
|
97
|
+
user = create(:user, name: "Tony")
|
98
|
+
allow(view).to receive(:user) { user }
|
99
|
+
|
100
|
+
render
|
101
|
+
|
102
|
+
expect(page).to have_content("Tony")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
To include this extension only, call `require rspec_tapas/view_page`
|
108
|
+
|
109
|
+
`ViewPage` is accessible only in view specs
|
110
|
+
|
111
|
+
|
112
|
+
### InvokeTask
|
113
|
+
|
114
|
+
`InvokeTask` is a small helper that facilitates calling rake tasks when testing them.
|
115
|
+
|
116
|
+
*Example*
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
RSpec.describe 'db:materialize', type: :rake do
|
120
|
+
it 'materializes db view by name' do
|
121
|
+
database = double(:database)
|
122
|
+
allow(Scenic).to receive(:database) { database }
|
123
|
+
allow(database).to receive(:refresh_materialized_view)
|
124
|
+
|
125
|
+
invoke_task('db:materialize', view_name: 'sample_view')
|
126
|
+
|
127
|
+
expect(database).to \
|
128
|
+
have_received(:refresh_materialized_view).with('sample_view')
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
To include this extension only, call `require rspec_tapas/invoke_task`
|
134
|
+
|
135
|
+
`InvokeTask` is accessible only in rake specs
|
136
|
+
|
137
|
+
|
138
|
+
### GetMessagePart
|
139
|
+
|
140
|
+
`GetMessagePart` is a set of helpers to facilitate extraction of html/plain parts of emails sent. To extract plaintext part from email, use `text_part(mail)`. To extract HTML part, use `html_part(mail)`.
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
RSpec.describe ReportMailer, type: :mailer do
|
144
|
+
describe '#summary' do
|
145
|
+
it 'creates email containing orders summary' do
|
146
|
+
create_list(:order, 2)
|
147
|
+
mail = ReportMailer.summary
|
148
|
+
|
149
|
+
expect(mail.subject).to eq('Orders summary')
|
150
|
+
expect(html_part(mail)).to include_html(
|
151
|
+
<<~HTML
|
152
|
+
<h1>Orders summary</h1>
|
153
|
+
<strong>Total orders created:</strong> 2 <br />
|
154
|
+
HTML
|
155
|
+
)
|
156
|
+
expect(text_part(mail)).to include('Total orders created: 2')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
```
|
161
|
+
|
162
|
+
To include this extension only, call `require rspec_tapas/get_message_part`
|
163
|
+
|
164
|
+
`GetMessagePart` is accessible only in mailer specs
|
165
|
+
|
166
|
+
### JsonResponse
|
167
|
+
|
168
|
+
`JsonResponse` is a simple helper that transforms JSON encoded response body to `HashWithIndifferentAccess` or an array of those. This is to facilitate using regular matchers to assert such response.
|
169
|
+
|
170
|
+
*Example*
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
it 'returns user names and emails' do
|
174
|
+
create(:user, name: 'Tony', email: 'tony@stark.dev')
|
175
|
+
create(:user, name: 'Bruce', email: 'bruce@wayne.dev')
|
176
|
+
|
177
|
+
get '/v1/users'
|
178
|
+
|
179
|
+
expect(json_response).to match(
|
180
|
+
data: [
|
181
|
+
{ name: 'Tony', email: 'tony@stark.dev' },
|
182
|
+
{ name: 'Bruce', email: 'bruce@wayne.dev' },
|
183
|
+
]
|
184
|
+
)
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
188
|
+
To include this extension only, call `require rspec_tapas/json_response`
|
189
|
+
|
190
|
+
`JsonResponse` is accessible only in request and controller specs
|
191
|
+
|
192
|
+
### DownloadsHelpers
|
193
|
+
|
194
|
+
`DownloadsHelpers` is a set of two helpers oriented on facilitating testing downloads. First, we need to allow downloading file in given feature spec by calling `allow_file_downloads(page)`. Then, to get downloaded file contents, we need to use `downloaded_file_contents(file_name)` helper.
|
195
|
+
|
196
|
+
To allow downloads with headless-chrome capybara driver, we need to configure it in specific way. See example below:
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
require 'selenium/webdriver'
|
200
|
+
|
201
|
+
Capybara.register_driver :headless_chrome do |app|
|
202
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
203
|
+
options.add_argument('--headless')
|
204
|
+
options.add_argument('--no-sandbox')
|
205
|
+
options.add_argument('--disable-gpu')
|
206
|
+
options.add_argument('--disable-popup-blocking')
|
207
|
+
options.add_argument('--window-size=1920,1200')
|
208
|
+
options.add_preference(
|
209
|
+
:download,
|
210
|
+
directory_upgrade: true,
|
211
|
+
prompt_for_download: false,
|
212
|
+
default_directory: RspecExtensions::DownloadsHelpers::DOWNLOADS_PATH
|
213
|
+
)
|
214
|
+
options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })
|
215
|
+
|
216
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
|
217
|
+
end
|
218
|
+
|
219
|
+
Capybara.javascript_driver = :headless_chrome
|
220
|
+
```
|
221
|
+
|
222
|
+
Then, testing downloads is just a matter of few lines of code.
|
223
|
+
|
224
|
+
*Example*
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
allow_file_downloads(page)
|
228
|
+
|
229
|
+
click_on 'Download report'
|
230
|
+
|
231
|
+
expect(downloaded_file_contents('daily_report.csv')).to eq("Name, Total revenue\nBatman suits, 1000")
|
232
|
+
```
|
233
|
+
|
234
|
+
To include this extension only, call `require rspec_tapas/downloads_helpers`
|
235
|
+
|
236
|
+
`DownloadsHelpers` are accessible only in feature specs
|
237
|
+
|
238
|
+
### FeatureHelpers
|
239
|
+
|
240
|
+
`FeatureHelpers` module contains a couple of methods useful in features specs.
|
241
|
+
|
242
|
+
- `display_logs` will display browser logs in console. This is useful for debugging javascript errors in feature specs.
|
243
|
+
- `ss` is a shortcut for `page.save_and_open_screenshot`
|
244
|
+
- `reload_page` is a handy shortcut for reloading current page.
|
245
|
+
|
246
|
+
To include this extension only, call `require rspec_tapas/feature_helpers`
|
247
|
+
|
248
|
+
`FeatureHelpers` are accessible only in feature specs
|
249
|
+
|
250
|
+
### BehaviorDSL
|
251
|
+
|
252
|
+
`BehaviorDSL` module has two roles. First one is to add some syntactic sugar to feature specs, by introducing additional level of describing context, but without interrupting test. This way you can group actions and assertions in readable blocks.
|
253
|
+
|
254
|
+
Second role of `BehaviorDSL` is to add capability of asserting feature - controller integration. This way we can ensure, that given block of capybara interactions were using particular controller action.
|
255
|
+
|
256
|
+
*Example*
|
257
|
+
|
258
|
+
```ruby
|
259
|
+
RSpec.describe 'Users management' do
|
260
|
+
scenario do
|
261
|
+
behavior 'Admin browses existing users', using: 'Admin::UsersController#index' do
|
262
|
+
create(:user, name: 'Luke Cage')
|
263
|
+
create(:unit, name: 'Jessica Jones')
|
264
|
+
|
265
|
+
visit '/admin/users'
|
266
|
+
|
267
|
+
expect(page).to have_row_content('Full name' => 'Luke Cage')
|
268
|
+
expect(page).to have_row_content('Full name' => 'Jessica Jones')
|
269
|
+
end
|
270
|
+
|
271
|
+
behavior 'Admin updates existing user' do
|
272
|
+
#...
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
```
|
277
|
+
|
278
|
+
To include this extension only, call `require rspec_tapas/behavior_dsl`
|
279
|
+
|
280
|
+
`BehaviorDSL` is accessible only in feature specs
|
281
|
+
|
282
|
+
## Matchers
|
283
|
+
|
284
|
+
### have_table_row
|
285
|
+
|
286
|
+
`have_table_row` is a matcher dedicated to finding table rows by their values correlated with specific headers. As so, this is mostly useful in feature specs.
|
287
|
+
|
288
|
+
*Examples*
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
# Asserting headers by their names
|
292
|
+
expect(page).to have_table_row('First name' => 'Tony', 'Last name' => 'Stark', 'Rating' => 4.5)
|
293
|
+
|
294
|
+
# Asserting headers by their indices
|
295
|
+
expect(page).to have_table_row(1 => 'Tony', 2 => 'Stark', 3 => 4.5)
|
296
|
+
|
297
|
+
# Asserting headers by their indices - shorter version
|
298
|
+
expect(page).to have_table_row('Tony', 'Stark', 4.5)
|
299
|
+
|
300
|
+
# Composing matchers
|
301
|
+
expect(page).to have_table_row(have_content('ny'), 'Stark')
|
302
|
+
```
|
303
|
+
|
304
|
+
To include this matcher only, call `require rspec_tapas/matchers/have_table_row`
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -1,24 +1,40 @@
|
|
1
1
|
module RspecExtensions
|
2
2
|
module BehaviorDSL
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
BehaviorNotification = Struct.new(:message)
|
4
|
+
class BehaviorNotification
|
5
|
+
def execution_result
|
6
|
+
RSpec::Core::Example::ExecutionResult.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def description
|
10
|
+
message
|
11
|
+
end
|
9
12
|
end
|
10
13
|
|
11
|
-
|
14
|
+
def behavior(name, using: nil)
|
15
|
+
if using.present?
|
16
|
+
@controller_actions_called = []
|
17
|
+
callback = lambda do |*args|
|
18
|
+
options = args.extract_options!
|
19
|
+
@controller_actions_called << "#{options[:controller]}##{options[:action]}"
|
20
|
+
end
|
21
|
+
ActiveSupport::Notifications.subscribed(callback, 'start_processing.action_controller') do
|
22
|
+
yield
|
23
|
+
end
|
24
|
+
|
25
|
+
expect(@controller_actions_called).to(
|
26
|
+
include(using),
|
27
|
+
"expected #{using} to be used for #{name}, but it was not"
|
28
|
+
)
|
29
|
+
else
|
30
|
+
yield
|
31
|
+
end
|
12
32
|
|
13
|
-
|
14
|
-
metadata[:description] = metadata[:description_args].join(' ')
|
15
|
-
metadata[:full_description] = \
|
16
|
-
[metadata[:example_group][:full_description]].
|
17
|
-
concat(metadata[:description_args]).join(' ')
|
33
|
+
reporter.example_passed(BehaviorNotification.new(name))
|
18
34
|
end
|
19
35
|
|
20
|
-
def
|
21
|
-
RSpec.current_example.
|
36
|
+
def reporter
|
37
|
+
RSpec.current_example.reporter
|
22
38
|
end
|
23
39
|
end
|
24
40
|
end
|
data/rspec-tapas.gemspec
CHANGED
@@ -2,28 +2,28 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: rspec-tapas 0.
|
5
|
+
# stub: rspec-tapas 0.2.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "rspec-tapas".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.2.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["B\u0142a\u017Cej Kosmowski".freeze]
|
14
|
-
s.date = "2018-06-
|
14
|
+
s.date = "2018-06-27"
|
15
15
|
s.description = "A selection of small rSpec extensions".freeze
|
16
16
|
s.email = "b.kosmowski@selleo.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE.txt",
|
19
|
-
"README.
|
19
|
+
"README.md"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
".document",
|
23
23
|
"Gemfile",
|
24
24
|
"Gemfile.lock",
|
25
25
|
"LICENSE.txt",
|
26
|
-
"README.
|
26
|
+
"README.md",
|
27
27
|
"Rakefile",
|
28
28
|
"VERSION",
|
29
29
|
"lib/rspec-tapas.rb",
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-tapas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Błażej Kosmowski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-06-
|
11
|
+
date: 2018-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: shoulda
|
@@ -86,13 +86,13 @@ executables: []
|
|
86
86
|
extensions: []
|
87
87
|
extra_rdoc_files:
|
88
88
|
- LICENSE.txt
|
89
|
-
- README.
|
89
|
+
- README.md
|
90
90
|
files:
|
91
91
|
- ".document"
|
92
92
|
- Gemfile
|
93
93
|
- Gemfile.lock
|
94
94
|
- LICENSE.txt
|
95
|
-
- README.
|
95
|
+
- README.md
|
96
96
|
- Rakefile
|
97
97
|
- VERSION
|
98
98
|
- lib/rspec-tapas.rb
|
data/README.rdoc
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
= rspec-tapas
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Contributing to rspec-tapas
|
6
|
-
|
7
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
-
* Fork the project.
|
10
|
-
* Start a feature/bugfix branch.
|
11
|
-
* Commit and push until you are happy with your contribution.
|
12
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2018 Błażej Kosmowski. See LICENSE.txt for
|
18
|
-
further details.
|