rspec-declarative_requests 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4677665c93037dfeb0de4252fb3d1d7e77c36568b3298882e9c68bcfb60bc5cc
4
+ data.tar.gz: 5e8dfd0b6807f27d7720ec8dcc1a09fad189cf002f95ecb7032a83aab11cb052
5
+ SHA512:
6
+ metadata.gz: 810166577b4cf160a7ace109db319d46f59c663fc9b268693e23ba68a82097ae1e4d79a88bdbcbc7be5c79543b4c4692cd57335663e01473c0ca9ab9885ce69d
7
+ data.tar.gz: 8d6350811086f5fc5504730aa6633070762ed1f3f73a74b4508dfa8f3f02b22bacfbaa1202af48f0c56ed3dd2b26d0407f2b08fdc415dff19b302e15dc27883f
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
data/Gemfile.lock ADDED
@@ -0,0 +1,159 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rspec-declarative_requests (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ actioncable (5.2.3)
10
+ actionpack (= 5.2.3)
11
+ nio4r (~> 2.0)
12
+ websocket-driver (>= 0.6.1)
13
+ actionmailer (5.2.3)
14
+ actionpack (= 5.2.3)
15
+ actionview (= 5.2.3)
16
+ activejob (= 5.2.3)
17
+ mail (~> 2.5, >= 2.5.4)
18
+ rails-dom-testing (~> 2.0)
19
+ actionpack (5.2.3)
20
+ actionview (= 5.2.3)
21
+ activesupport (= 5.2.3)
22
+ rack (~> 2.0)
23
+ rack-test (>= 0.6.3)
24
+ rails-dom-testing (~> 2.0)
25
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
26
+ actionview (5.2.3)
27
+ activesupport (= 5.2.3)
28
+ builder (~> 3.1)
29
+ erubi (~> 1.4)
30
+ rails-dom-testing (~> 2.0)
31
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
32
+ activejob (5.2.3)
33
+ activesupport (= 5.2.3)
34
+ globalid (>= 0.3.6)
35
+ activemodel (5.2.3)
36
+ activesupport (= 5.2.3)
37
+ activerecord (5.2.3)
38
+ activemodel (= 5.2.3)
39
+ activesupport (= 5.2.3)
40
+ arel (>= 9.0)
41
+ activestorage (5.2.3)
42
+ actionpack (= 5.2.3)
43
+ activerecord (= 5.2.3)
44
+ marcel (~> 0.3.1)
45
+ activesupport (5.2.3)
46
+ concurrent-ruby (~> 1.0, >= 1.0.2)
47
+ i18n (>= 0.7, < 2)
48
+ minitest (~> 5.1)
49
+ tzinfo (~> 1.1)
50
+ arel (9.0.0)
51
+ builder (3.2.3)
52
+ byebug (11.0.1)
53
+ concurrent-ruby (1.1.5)
54
+ crass (1.0.4)
55
+ diff-lcs (1.3)
56
+ erubi (1.8.0)
57
+ gem-release (2.0.1)
58
+ globalid (0.4.2)
59
+ activesupport (>= 4.2.0)
60
+ i18n (1.6.0)
61
+ concurrent-ruby (~> 1.0)
62
+ json (2.2.0)
63
+ loofah (2.2.3)
64
+ crass (~> 1.0.2)
65
+ nokogiri (>= 1.5.9)
66
+ mail (2.7.1)
67
+ mini_mime (>= 0.1.1)
68
+ marcel (0.3.3)
69
+ mimemagic (~> 0.3.2)
70
+ method_source (0.9.2)
71
+ mimemagic (0.3.3)
72
+ mini_mime (1.0.1)
73
+ mini_portile2 (2.4.0)
74
+ minitest (5.11.3)
75
+ nio4r (2.3.1)
76
+ nokogiri (1.10.3)
77
+ mini_portile2 (~> 2.4.0)
78
+ rack (2.0.7)
79
+ rack-test (1.1.0)
80
+ rack (>= 1.0, < 3)
81
+ rails (5.2.3)
82
+ actioncable (= 5.2.3)
83
+ actionmailer (= 5.2.3)
84
+ actionpack (= 5.2.3)
85
+ actionview (= 5.2.3)
86
+ activejob (= 5.2.3)
87
+ activemodel (= 5.2.3)
88
+ activerecord (= 5.2.3)
89
+ activestorage (= 5.2.3)
90
+ activesupport (= 5.2.3)
91
+ bundler (>= 1.3.0)
92
+ railties (= 5.2.3)
93
+ sprockets-rails (>= 2.0.0)
94
+ rails-dom-testing (2.0.3)
95
+ activesupport (>= 4.2.0)
96
+ nokogiri (>= 1.6)
97
+ rails-html-sanitizer (1.0.4)
98
+ loofah (~> 2.2, >= 2.2.2)
99
+ railties (5.2.3)
100
+ actionpack (= 5.2.3)
101
+ activesupport (= 5.2.3)
102
+ method_source
103
+ rake (>= 0.8.7)
104
+ thor (>= 0.19.0, < 2.0)
105
+ rake (12.3.2)
106
+ rspec (3.8.0)
107
+ rspec-core (~> 3.8.0)
108
+ rspec-expectations (~> 3.8.0)
109
+ rspec-mocks (~> 3.8.0)
110
+ rspec-composable_json_matchers (1.1.1)
111
+ json (~> 2.0)
112
+ rspec (~> 3.0)
113
+ rspec-core (3.8.0)
114
+ rspec-support (~> 3.8.0)
115
+ rspec-expectations (3.8.3)
116
+ diff-lcs (>= 1.2.0, < 2.0)
117
+ rspec-support (~> 3.8.0)
118
+ rspec-mocks (3.8.0)
119
+ diff-lcs (>= 1.2.0, < 2.0)
120
+ rspec-support (~> 3.8.0)
121
+ rspec-rails (3.8.2)
122
+ actionpack (>= 3.0)
123
+ activesupport (>= 3.0)
124
+ railties (>= 3.0)
125
+ rspec-core (~> 3.8.0)
126
+ rspec-expectations (~> 3.8.0)
127
+ rspec-mocks (~> 3.8.0)
128
+ rspec-support (~> 3.8.0)
129
+ rspec-support (3.8.0)
130
+ sprockets (3.7.2)
131
+ concurrent-ruby (~> 1.0)
132
+ rack (> 1, < 3)
133
+ sprockets-rails (3.2.1)
134
+ actionpack (>= 4.0)
135
+ activesupport (>= 4.0)
136
+ sprockets (>= 3.0.0)
137
+ sqlite3 (1.4.1)
138
+ thor (0.20.3)
139
+ thread_safe (0.3.6)
140
+ tzinfo (1.2.5)
141
+ thread_safe (~> 0.1)
142
+ websocket-driver (0.7.0)
143
+ websocket-extensions (>= 0.1.0)
144
+ websocket-extensions (0.1.3)
145
+
146
+ PLATFORMS
147
+ ruby
148
+
149
+ DEPENDENCIES
150
+ byebug
151
+ gem-release
152
+ rails (~> 5.2)
153
+ rspec-composable_json_matchers
154
+ rspec-declarative_requests!
155
+ rspec-rails
156
+ sqlite3
157
+
158
+ BUNDLED WITH
159
+ 1.17.2
data/README.md ADDED
@@ -0,0 +1,181 @@
1
+ RSpec::DeclarativeRequests
2
+ ==========================
3
+
4
+ A standardized structure for request specs in Rails.
5
+
6
+ ```ruby
7
+ require 'rails_helper'
8
+
9
+ RSpec.describe 'Widgets' do
10
+ describe 'GET /widgets/:id' do
11
+ let(:id) { FactoryBot.create(:widget).id }
12
+ it { is_expected.to have_http_status(:ok) }
13
+ end
14
+ end
15
+ ```
16
+
17
+ Setup
18
+ -----
19
+
20
+ Add to your `Gemfile` (probably in the `:test` group):
21
+
22
+ ```ruby
23
+ # Gemfile
24
+ group :test do
25
+ gem 'rspec-declarative_requests'
26
+ end
27
+ ```
28
+
29
+ Include it in your RSpec config:
30
+
31
+ ```ruby
32
+ # spec/rails_helper.rb
33
+ RSpec.configure do |config|
34
+ # enabled for ALL request specs
35
+ config.include RSpec::DeclarativeRequests, type: :request
36
+
37
+ # OR: enable only for request specs tagged as :declarative
38
+ config.include RSpec::DeclarativeRequests, type: :request, declarative: true
39
+ end
40
+ ```
41
+
42
+ Or include it straight into the spec:
43
+
44
+ ```ruby
45
+ # spec/requests/whatever_spec.rb
46
+ require 'rails_helper'
47
+
48
+ RSpec.describe 'Whatever' do
49
+ include RSpec::DeclarativeRequests
50
+
51
+ describe 'GET /whatevers' do
52
+ # ...
53
+ end
54
+ end
55
+ ```
56
+
57
+
58
+ Using `subject`
59
+ ---------------
60
+
61
+ This gem sets the RSpec subject to the _response_, after making the request.
62
+ This allows you do use `is_expected` or `expect(subject)` to check the response.
63
+
64
+ ```ruby
65
+ describe 'GET /thing' do
66
+ it { is_expected.to be_ok }
67
+
68
+ # OR
69
+
70
+ it "responds with 200 OK" do
71
+ expect(subject).to have_http_status(:ok)
72
+ end
73
+ end
74
+ ```
75
+
76
+ Using `params`
77
+ --------------
78
+
79
+ There is a `let` for request params that starts as an empty Hash. You can
80
+ either override it:
81
+
82
+ ```ruby
83
+ let(:params) do
84
+ { my_param: 123 }
85
+ end
86
+ ```
87
+
88
+ Or you can modify it in a `before` block:
89
+
90
+ ```ruby
91
+ before do
92
+ params[:my_param] = 123
93
+ end
94
+ ```
95
+
96
+ Using `before` blocks, you can do nested contexts:
97
+
98
+ ```ruby
99
+ context 'with a user' do
100
+ before { params[:user] = { id: 123 } }
101
+
102
+ context 'who is cool' do
103
+ before { params[:user][:is_cool] = true }
104
+ # ...
105
+ end
106
+
107
+ context 'who is not cool' do
108
+ before { params[:user][:is_cool] = false }
109
+ # ...
110
+ end
111
+ end
112
+ ```
113
+
114
+ Using `headers`
115
+ ---------------
116
+
117
+ There is a `let` for request headers that starts as an empty Hash. This works
118
+ exactly the same as `params` described above.
119
+
120
+ ```ruby
121
+ context 'requesting JSON' do
122
+ before { headers['Accepts'] = 'application/json' }
123
+ # ...
124
+ end
125
+ ```
126
+
127
+ Path Interpolation
128
+ ------------------
129
+
130
+ The path in the request description behaves _kind of_ like a Rails route.
131
+ Named segments that start with a `:` will be replaced by the value of the `let`
132
+ (or method) with the same name.
133
+
134
+ ```ruby
135
+ describe 'POST /things/:thing_id' do
136
+ let(:thing_id) { 4444 }
137
+ # ...
138
+ end
139
+ ```
140
+
141
+ It's common to want to use an attribute of an object that you already have a
142
+ `let` for. To do that, use the `#` character.
143
+
144
+ ```ruby
145
+ describe 'POST /things/:thing#id' do
146
+ let(:thing) { FactoryBot.create(:thing) }
147
+ # ...
148
+ end
149
+ ```
150
+
151
+ Attributes can be chained together.
152
+
153
+ ```ruby
154
+ describe 'POST /things/:user#things#first#id' do
155
+ let(:user) { FactoryBot.create(:user, :with_things) }
156
+ # ...
157
+ end
158
+ ```
159
+
160
+ `Hash`s can also be interpolated by their keys, which can be either strings or
161
+ symbols.
162
+
163
+ ```ruby
164
+ describe 'POST /things/:user#things#first#id' do
165
+ let(:user) do
166
+ {
167
+ things: [
168
+ { id: 1 },
169
+ { id: 2 },
170
+ ]
171
+ }
172
+ end
173
+
174
+ #...
175
+ end
176
+ ```
177
+
178
+ License
179
+ -------
180
+
181
+ This gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,5 @@
1
+ module RSpec
2
+ module DeclarativeRequests
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,64 @@
1
+ module RSpec::DeclarativeRequests
2
+ def self.included(example_class)
3
+ example_class.let(:params) { {} }
4
+ example_class.let(:headers) { {} }
5
+ example_class.let(:subject) do
6
+ PerformRequest.(self)
7
+ response
8
+ end
9
+ end
10
+
11
+ class Error < StandardError; end
12
+
13
+ module PerformRequest
14
+ extend self
15
+
16
+ HTTP_METHODS = %w(CONNECT DELETE GET HEAD OPTIONS PATCH POST PUT TRACE)
17
+
18
+ def call(example)
19
+ group = ([RSpec.current_example] + example.class.parent_groups).find do |group|
20
+ HTTP_METHODS.any? do |http_method|
21
+ group.description.start_with?(http_method + ' ')
22
+ end
23
+ end
24
+
25
+ if group.nil?
26
+ raise Error, <<~END_ERROR
27
+ Could not find an RSpec example group that looks like a request. The
28
+ describe/context description must start with an uppercase HTTP verb
29
+ like "GET" or "POST".
30
+
31
+ Try something like:
32
+
33
+ describe "GET /foo" do
34
+ it { is_expected.to have_http_status(:ok) }
35
+ end
36
+ END_ERROR
37
+ end
38
+
39
+ method, _, path = group.description.partition(/\s+/)
40
+ example.send(
41
+ method.downcase,
42
+ interpolate(path, example),
43
+ params: example.params,
44
+ headers: example.headers,
45
+ )
46
+ end
47
+
48
+ def interpolate(path, example)
49
+ path.gsub(/\:[a-z_#]+/) do |match|
50
+ match[1..-1].split('#').reduce(example) do |value, attr|
51
+ if value.is_a?(Hash)
52
+ case
53
+ when value.key?(attr) then value[attr]
54
+ when value.key?(attr.to_sym) then value[attr.to_sym]
55
+ else raise Error, "Couldn't find '#{attr}' while interpolating '#{match}' in the request path"
56
+ end
57
+ else
58
+ value.send(attr)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rspec/declarative_requests/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rspec-declarative_requests"
8
+ spec.version = RSpec::DeclarativeRequests::VERSION
9
+ spec.authors = ["Tom Dalling"]
10
+ spec.email = ["tom" + "@" + "tomdalling.com"]
11
+
12
+ spec.summary = %q{A standardized structure for request specs in Rails.}
13
+ spec.description = %q{A standardized structure for request specs in Rails.}
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "rails", "~> 5.2"
24
+ spec.add_development_dependency "sqlite3"
25
+ spec.add_development_dependency "rspec-rails"
26
+ spec.add_development_dependency 'rspec-composable_json_matchers'
27
+ spec.add_development_dependency "byebug"
28
+ spec.add_development_dependency 'gem-release'
29
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-declarative_requests
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tom Dalling
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-06-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-composable_json_matchers
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: gem-release
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: A standardized structure for request specs in Rails.
98
+ email:
99
+ - tom@tomdalling.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".rspec"
105
+ - ".ruby-version"
106
+ - Gemfile
107
+ - Gemfile.lock
108
+ - README.md
109
+ - lib/rspec/declarative_requests.rb
110
+ - lib/rspec/declarative_requests/version.rb
111
+ - rspec-declarative_requests.gemspec
112
+ homepage:
113
+ licenses:
114
+ - MIT
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubygems_version: 3.0.3
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: A standardized structure for request specs in Rails.
135
+ test_files: []