saharspec 0.0.8 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 402e6f62d9abc17f1dad82a3a5f38ae8f844ca458ad87a4756192976e4cd5496
4
- data.tar.gz: 1541630eb677716d9ab2e58e1a25427ea86b67c5e001a52a25e9641491006971
3
+ metadata.gz: 9409e96bf31ffafcb98955b97ab75e2b78547b5d5bf5dc405f22f21fd62ff77c
4
+ data.tar.gz: b9d1cda3cd2796576612b4e888cf8fd97a9b39357c56417c293628958722bdb3
5
5
  SHA512:
6
- metadata.gz: 7923af91fee36b0a8b8c79fdba8d0bf6503598ca62589d8d30a2e8dace0428f9338e892d5e3a0538c4fc857a209b390b6b88eebf8637c41dc68dd6c61d6772d5
7
- data.tar.gz: 5b844ac0a0098001638d19a2113e0eca4bf7acb225a87a456133e3d1ff564fc96648b95a0e0c37478c07d2532fc005e9c4db35a15b00f6b92018565c70097175
6
+ metadata.gz: e10c863c94b4099cd6322029eda5129aec7cb12ddfae032c71a37436731f86189c8f1494a5f71d29e6eb17764ba4f6ad06e7f9a9ada6486d123aac0036d1d32a
7
+ data.tar.gz: d229e1aa4ecfa492f15b57b4249e51ae7cdf0805895f4a465a1ade675949a13526d3052e719b4abed0b98c858461aa5b30115642425883df0c66f0039728c766
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Saharspec history
2
2
 
3
+ ## 0.0.10 -- 2023-02-18
4
+
5
+ * Add `lets:` metadata helper for DRYer defining of simple `let`s in multiple contexts;
6
+ * Minimum supported Ruby version is 2.7
7
+ * Add a handler for when `saharspec` is called before/without `rspec`, to provide an informative error message ([@Vagab](https://github.com/Vagab))
8
+
9
+ ## 0.0.9 -- 2022-05-17
10
+
11
+ * Properly lint RSpec specs using `its_block`/`its_call`/`its_map` with `rubocop-rspec` >= 2.0 ([@ka8725](https://github.com/ka8725))
12
+ * Fix `its_block` and `its_call` to support RSpec 3.11
13
+
3
14
  ## 0.0.8 -- 2020-10-10
4
15
 
5
16
  * Better `dont` failure message (just use underlying matchers `failure_message_when_negated`)
data/README.md CHANGED
@@ -73,18 +73,18 @@ context 'when incompatible' do
73
73
  end
74
74
 
75
75
  # option 2. subject is block
76
- subject { -> {2 + x } }
77
-
78
- context 'when incompatible' do
79
- let(:x) { '3' }
80
- it { is_expected.to raise_error } # DRY
81
- end
76
+ subject { -> { 2 + x } }
82
77
 
83
78
  context 'when numeric' do
84
79
  let(:x) { 3 }
85
80
  it { expect(subject.call).to eq 5 } # not DRY
86
81
  end
87
82
 
83
+ context 'when incompatible' do
84
+ let(:x) { '3' }
85
+ it { is_expected.to raise_error } # DRY
86
+ end
87
+
88
88
  # after
89
89
  require 'saharspec/matchers/ret'
90
90
 
@@ -250,6 +250,59 @@ describe '#delete_at' do
250
250
  end
251
251
  ```
252
252
 
253
+ ### Metadata handlers
254
+
255
+ (Experimental.) Those aren't required by default, or by `require 'saharspec/metadata'`, you need to require each by its own. This is done to lessen the confusion if metadata processing isn't expected.
256
+
257
+ #### `lets:`
258
+
259
+ A shortcut for defining simple `let`s in the description
260
+
261
+ ```ruby
262
+ let(:user) { create(:user, role: role) }
263
+
264
+ # before: a lot of code to say simple things:
265
+
266
+ context 'when admin' do
267
+ let(:role) { :admin }
268
+
269
+ it { is_expected.to be_allowed }
270
+ end
271
+
272
+ context 'when user' do
273
+ let(:role) { :user }
274
+
275
+ it { is_expected.to be_denied }
276
+ end
277
+
278
+ # after
279
+
280
+ context 'when admin', lets: {role: :admin} do
281
+ it { is_expected.to be_allowed }
282
+ end
283
+
284
+ context 'when user', lets: {role: :user} do
285
+ it { is_expected.to be_denied }
286
+ end
287
+
288
+ # you can also give empty descriptions, then they would be auto-generated
289
+
290
+ # generates a context with description "with role=:admin"
291
+ context '', lets: {role: :admin} do
292
+ it { is_expected.to be_allowed }
293
+ end
294
+ ```
295
+
296
+ ### Linting with RuboCop RSpec
297
+
298
+ `rubocop-rspec` fails to properly detect RSpec constructs that Saharspec defines (`its_call`, `its_block`, `its_map`).
299
+ Make sure to use `rubocop-rspec` 2.0 or newer and add the following to your `.rubocop.yml`:
300
+
301
+ ```yaml
302
+ inherit_gem:
303
+ saharspec: config/rubocop-rspec.yml
304
+ ```
305
+
253
306
  ## State & future
254
307
 
255
308
  I use all of the components of the library on daily basis. Probably, I will extend it with other
@@ -0,0 +1,13 @@
1
+ RSpec:
2
+ Language:
3
+ Includes:
4
+ Examples:
5
+ - its_block
6
+ - its_call
7
+ - its_map
8
+ - fits_block
9
+ - fits_call
10
+ - fits_map
11
+ - xits_block
12
+ - xits_call
13
+ - xits_map
@@ -3,7 +3,7 @@
3
3
  module Saharspec
4
4
  module Its
5
5
  module Block
6
- # Creates nested example which converts current subject to a block-subject.
6
+ # Creates nested example that redefines implicit `is_expected` to use subject as a block.
7
7
  #
8
8
  # @example
9
9
  #
@@ -34,12 +34,13 @@ module Saharspec
34
34
  def its_block(*options, &block)
35
35
  # rubocop:disable Lint/NestedMethodDefinition
36
36
  describe('as block') do
37
+ # FIXME: Not necessary? (Previously, wrapped the subject in lambda, now just repeats it)
37
38
  let(:__call_subject) do
38
- -> { subject }
39
+ subject
39
40
  end
40
41
 
41
42
  def is_expected
42
- expect(__call_subject)
43
+ expect { __call_subject }
43
44
  end
44
45
 
45
46
  example(nil, *options, &block)
@@ -31,11 +31,11 @@ module Saharspec
31
31
  # rubocop:disable Lint/NestedMethodDefinition
32
32
  describe("(#{args.map(&:inspect).join(', ')})") do
33
33
  let(:__call_subject) do
34
- -> { subject.call(*args) }
34
+ subject.call(*args)
35
35
  end
36
36
 
37
37
  def is_expected
38
- expect(__call_subject)
38
+ expect { __call_subject }
39
39
  end
40
40
 
41
41
  example(nil, &block)
@@ -32,7 +32,7 @@ module Saharspec
32
32
  # @param block [Proc] The test itself. Inside it, `is_expected` (or `are_expected`) is related to result
33
33
  # of `map`ping the subject.
34
34
  #
35
- def its_map(attribute, *options, &block) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
35
+ def its_map(attribute, *options, &block) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
36
36
  # rubocop:disable Lint/NestedMethodDefinition
37
37
  # TODO: better desciption for different cases
38
38
  describe("map(&:#{attribute})") do
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saharspec
4
+ module Metadata
5
+ # Is included in `context`s and `describe`s that have `lets: Hash` defined, as a shortcut to
6
+ # define simple `let`s in a simple one-line way:
7
+ #
8
+ # ```ruby
9
+ # let(:user) { create(:user, role: role) }
10
+ #
11
+ # # before: a lot of code to say simple things:
12
+ # context 'when admin' do
13
+ # let(:role) { :admin }
14
+ #
15
+ # it { is_expected.to be_allowed }
16
+ # end
17
+ #
18
+ # context 'when user' do
19
+ # let(:role) { :user }
20
+ #
21
+ # it { is_expected.to be_denied }
22
+ # end
23
+ #
24
+ # # after
25
+ # context 'when admin', lets: {role: :admin} do
26
+ # it { is_expected.to be_allowed }
27
+ # end
28
+ #
29
+ # context 'when user', lets: {role: :user} do
30
+ # it { is_expected.to be_denied }
31
+ # end
32
+ #
33
+ # # you can also give empty descriptions, then they would be auto-generated
34
+ #
35
+ # # generates a context with description "with role=:admin"
36
+ # context '', lets: {role: :admin} do
37
+ # it { is_expected.to be_allowed }
38
+ # end
39
+ # ```
40
+ #
41
+ module Lets
42
+ def self.included(ctx)
43
+ lets = ctx.metadata[:lets]
44
+ .tap { _1.is_a?(Hash) or fail ArgumentError, "lets: is expected to be a Hash, got #{_1.class}" }
45
+
46
+ lets.each { |name, val| ctx.let(name) { val } }
47
+ ctx.metadata[:description].to_s.empty? and
48
+ ctx.metadata[:description] = lets.map { "#{_1}=#{_2.inspect}" }.join(', ').prepend('with ')
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ RSpec.configure do |config|
55
+ config.include Saharspec::Metadata::Lets, :lets
56
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saharspec
4
+ # Wrapper module for all RSpec additions available via example or context metadata.
5
+ #
6
+ # Note: because including some functionality by context metadata is not obvious,
7
+ # saharspec doesn't require them by default when you `require 'saharspec'` or
8
+ # `require 'saharspec/metadata'`, you need to require specifically the functionality
9
+ # you are planning to use.
10
+ #
11
+ # See:
12
+ #
13
+ # ## {Lets}
14
+ #
15
+ # ```ruby
16
+ # context 'with admin', lets: {role: :admin} do
17
+ # it { is_expected.to be_allowed }
18
+ # end
19
+ #
20
+ # # this is the same as
21
+ # context 'with admin' do
22
+ # let(:role) { :admin }
23
+ #
24
+ # it { is_expected.to be_allowed }
25
+ # end
26
+ # ```
27
+ #
28
+ module Metadata
29
+ end
30
+ end
@@ -3,6 +3,6 @@
3
3
  module Saharspec
4
4
  MAJOR = 0
5
5
  MINOR = 0
6
- PATCH = 8
6
+ PATCH = 10
7
7
  VERSION = [MAJOR, MINOR, PATCH].join('.')
8
8
  end
data/lib/saharspec.rb CHANGED
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ defined?(RSpec) or
4
+ fail 'RSpec is not present in the current environment, check that `rspec` ' \
5
+ 'is present in your Gemfile and is in the same group as `saharspec`' \
6
+
3
7
  # Umbrella module for all Saharspec RSpec DRY-ing features.
4
8
  #
5
- # See {file:README.md} or {Its} and {Matchers} separately.
9
+ # See {file:README.md} or {Its}, {Matchers}, and {Metadata} separately.
6
10
  #
7
11
  module Saharspec
8
12
  end
data/saharspec.gemspec CHANGED
@@ -23,14 +23,12 @@ Gem::Specification.new do |s|
23
23
  end
24
24
  s.require_paths = ["lib"]
25
25
 
26
- s.required_ruby_version = '>= 2.3.0'
26
+ s.required_ruby_version = '>= 2.7.0'
27
27
 
28
28
  s.add_runtime_dependency 'ruby2_keywords'
29
29
 
30
- if RUBY_VERSION >= '2.4' # Newest Rubocop fails on 2.3
31
- s.add_development_dependency 'rubocop', '~> 0.93'
32
- end
33
- s.add_development_dependency 'rspec', '~> 3.7.0'
30
+ s.add_development_dependency 'rubocop', '~> 0.93'
31
+ s.add_development_dependency 'rspec', '>= 3.7.0'
34
32
  s.add_development_dependency 'rspec-its'
35
33
  s.add_development_dependency 'simplecov', '~> 0.9'
36
34
  s.add_development_dependency 'rake'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saharspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Shepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-10 00:00:00.000000000 Z
11
+ date: 2023-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby2_keywords
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 3.7.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 3.7.0
55
55
  - !ruby/object:Gem::Dependency
@@ -133,6 +133,7 @@ files:
133
133
  - CHANGELOG.md
134
134
  - LICENSE.txt
135
135
  - README.md
136
+ - config/rubocop-rspec.yml
136
137
  - lib/saharspec.rb
137
138
  - lib/saharspec/its.rb
138
139
  - lib/saharspec/its/block.rb
@@ -145,6 +146,8 @@ files:
145
146
  - lib/saharspec/matchers/request_webmock.rb
146
147
  - lib/saharspec/matchers/ret.rb
147
148
  - lib/saharspec/matchers/send_message.rb
149
+ - lib/saharspec/metadata.rb
150
+ - lib/saharspec/metadata/lets.rb
148
151
  - lib/saharspec/util.rb
149
152
  - lib/saharspec/version.rb
150
153
  - saharspec.gemspec
@@ -160,14 +163,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
160
163
  requirements:
161
164
  - - ">="
162
165
  - !ruby/object:Gem::Version
163
- version: 2.3.0
166
+ version: 2.7.0
164
167
  required_rubygems_version: !ruby/object:Gem::Requirement
165
168
  requirements:
166
169
  - - ">="
167
170
  - !ruby/object:Gem::Version
168
171
  version: '0'
169
172
  requirements: []
170
- rubygems_version: 3.0.3
173
+ rubygems_version: 3.1.6
171
174
  signing_key:
172
175
  specification_version: 4
173
176
  summary: Several additions for DRYer RSpec code