rspec-declarative_requests 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []