saharspec 0.0.8 → 0.0.10

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