rspecz 0.1.1 → 0.1.2

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: 8b437acabae389beb51eda1e28f49ed9f19502536b6dbcdbfacdb0ed7f3b144c
4
- data.tar.gz: e83aba1baed93bd0d1208f22386103bbd791b87854e90f86101fc42a308aefe0
3
+ metadata.gz: 0a70abeda07ff4667c437333890cdcff13274fe69c9b48d34e969675380b9839
4
+ data.tar.gz: be9d9924e73c8c9e0a618e7afb69988bda6b6e21e30d4865b4629ad49fea29c5
5
5
  SHA512:
6
- metadata.gz: abdac6c31c319e1d6a0ebd1538ad686a67588c056fd6b524098f7cdde3d1344e4a58ce6875d8e5ee61b2dae07ee15078016625c48c4ce3beafe036a274862f0f
7
- data.tar.gz: 17b20b3397efe8951ac991a9fde7362b4b5ac1ed105e2059ba870be831637fca8fa57804bd6b499b429d121d22e3d5d1e48220f04d550ad4d963ad347c9b714e
6
+ metadata.gz: a9f097c4e7c1d3b6a4ecc581ec7d03b6a05c0651cfc0a044da4e3e0a4af81da17761714c788e40caa352acc72417e64b32d3231cdcaf07b6976ea6fb8a4d0cb7
7
+ data.tar.gz: 03041a3c5637ea20572fb12dfbd107d6a7e0dfdcfa75430bba743b20c822af914792dae539a778afc121626759b81a412fff158a4ddf81e9c8dc0a94c76b49d3
data/Gemfile.lock CHANGED
@@ -1,13 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspecz (0.1.1)
4
+ rspecz (0.1.2)
5
+ method_source (~> 0.9.0)
5
6
  rspec (>= 3.0)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
11
+ coderay (1.1.2)
10
12
  diff-lcs (1.3)
13
+ method_source (0.9.2)
14
+ pry (0.12.2)
15
+ coderay (~> 1.1.0)
16
+ method_source (~> 0.9.0)
11
17
  rake (10.5.0)
12
18
  rspec (3.8.0)
13
19
  rspec-core (~> 3.8.0)
@@ -15,7 +21,7 @@ GEM
15
21
  rspec-mocks (~> 3.8.0)
16
22
  rspec-core (3.8.0)
17
23
  rspec-support (~> 3.8.0)
18
- rspec-expectations (3.8.1)
24
+ rspec-expectations (3.8.2)
19
25
  diff-lcs (>= 1.2.0, < 2.0)
20
26
  rspec-support (~> 3.8.0)
21
27
  rspec-mocks (3.8.0)
@@ -28,8 +34,9 @@ PLATFORMS
28
34
 
29
35
  DEPENDENCIES
30
36
  bundler (~> 1.16)
37
+ pry
31
38
  rake (~> 10.0)
32
39
  rspecz!
33
40
 
34
41
  BUNDLED WITH
35
- 1.16.1
42
+ 1.17.2
data/README.md CHANGED
@@ -1,43 +1,315 @@
1
1
  # RSpecZ
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/RSpecZ`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ RSpecZ is a powerful extension for RSpec with strong and straightforward syntaxes.
4
+ With RSpecZ you can handle different contexts with only a single line of code.
5
+ RSpecZ also provides a number of aliases to improve the readability of RSpec code.
6
+
7
+ ## Effect of RSpecZ
8
+
9
+ ![image](https://user-images.githubusercontent.com/10380303/46996479-c60e8380-d157-11e8-9c8a-58ca1012e2ed.png)
4
10
 
5
- TODO: Delete this and the text above, and describe your gem
6
11
 
7
12
  ## Installation
8
13
 
9
14
  Add this line to your application's Gemfile:
10
15
 
16
+ Use github syntax until release Version 1.0.
17
+
11
18
  ```ruby
12
- gem 'rspecz'
19
+ gem 'rspecz', github: 'RSpecZ/RSpecZ'
13
20
  ```
14
21
 
15
- And then execute:
22
+ ## Features
23
+
24
+ ### Context
25
+
26
+ This is one of the most powerful features in RSpecZ.
27
+ RSpecZ has a number of context-related methods that can automatically
28
+ generate context descriptions for you.
29
+ You can also use methods like `set_values` to assign different values to a variable without writing multiple lines of code in your test.
30
+
31
+ ### Let
32
+
33
+ RSpecZ provides variable assignment methods like `create_params` and `strings`, which allows you to create complex variables in only one line of code.
34
+
35
+ ### Subject
36
+
37
+ RSpecZ also provides subject-related methods to simplify your code when you test subjects.
16
38
 
17
- $ bundle
39
+ ### Alias
18
40
 
19
- Or install it yourself as:
41
+ To improve the readability of your test code, RSpecZ provides aliases such as `make` and `behave`. These aliases can help to greatly simplify your code and make them easier to review.
20
42
 
21
- $ gem install RSpecZ
22
43
 
23
44
  ## Usage
24
45
 
25
- TODO: Write usage instructions here
46
+ ### context
47
+
48
+ #### with(name, value)
49
+
50
+ You can use `with` to set value to a variable, and execute the specified block:
51
+
52
+ ```
53
+ with(name, value).so { my_block }
54
+ ```
55
+
56
+ This will automatically create context description for you based on the name and value you specified, like this:
57
+
58
+ ```
59
+ context "when #{name} is #{value}" do
60
+ let(name) { value }
61
+ my_block
62
+ end
63
+ ```
64
+
65
+ In the example above, `value` is assigned to `name` and the specified block will be executed.
66
+
67
+ You can also specify your own description:
68
+
69
+ ```
70
+ with(name, value).desc('my_context_description').so { my_block }
71
+ ```
72
+
73
+ #### with(name, *values)
74
+
75
+ `with` allows you to assign multiple values to a variable in only one line of code,
76
+ it also creates context for each value, for example:
77
+
78
+ ```
79
+ with(:age, 20, 30).so { my_block }
80
+ ```
81
+
82
+ This is equals to:
83
+
84
+ ```
85
+ context "when age is 20" do
86
+ let(:age) { 20 }
87
+ my_block
88
+ end
89
+
90
+ context "when age is 30" do
91
+ let(:age) { 30 }
92
+ my_block
93
+ end
94
+ ```
95
+
96
+ Using multiple values don't allow you to set your own context description.
97
+
98
+ If you want to set description, you should write `with(name, value)` multiple times.
99
+
100
+ #### with(name) { value }
101
+
102
+ `with` also allow you to assign block value to a variable.
103
+
104
+ You can use dynamic values like `FactoryBot`.
105
+
106
+ ```
107
+ with(:person) { create(:person) }.so { my_block }
108
+ ```
109
+
110
+ This is equals to:
111
+
112
+ ```
113
+ context "when person is create(:person)" do
114
+ let(:person) { create(:person) }
115
+ my_block
116
+ end
117
+ ```
118
+
119
+ `with` with block produce description from your block source, so you can know what kind of context it is.
120
+
121
+ #### `and`
122
+
123
+ Each `with` method can chain `and` method.
124
+
125
+ If you want to set another variable for spec, you can set additional variable with `and` method.
126
+
127
+ ```
128
+ with(:name, 'test').and(:age) { 10 }.so { my_block }
129
+ ```
130
+
131
+ This is equals to:
132
+
133
+ ```
134
+ context 'when name is test and age is 10' do
135
+ let(:name) { 'test' }
136
+ let(:age) { 10 }
137
+ my_block
138
+ end
139
+ ```
140
+
141
+ #### with_nil(*variables)
142
+
143
+ `with_nil` is a specific method to set nil to variables.
144
+
145
+ ```
146
+ with_nil(:name, :age, :phone_number).so { my_block }
147
+ ```
148
+
149
+ This is equals to:
150
+
151
+ ```
152
+ %i[name age phone_number].each do |variable|
153
+ context "when #{variable} is nil" do
154
+ let(variable) { nil }
155
+ my_block
156
+ end
157
+ end
158
+ ```
159
+
160
+
161
+ ### valid, invalid, missing
162
+
163
+ `with` method doesn't provide any information about what kind of spec it is.
164
+
165
+ RSpecZ has `with_valid` , `with_invalid` , `with_missing` provide spec information by method name.
166
+
167
+ You can use these method to make specs review easy.
168
+
26
169
 
27
- ## Development
170
+ ### super in with method
28
171
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
172
+ RSpec's `super` in `let` cannot be used in RSpecZ.
30
173
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
174
+ RSpecZ has `_super` method for this.
175
+
176
+ You can use `_super` like this.
177
+
178
+ ```
179
+ let(:name) { 'test' }
180
+
181
+ with(:name) { _super + '10' }.so { my_block }
182
+ ```
183
+
184
+ #### set_context
185
+
186
+ `set_context` will include the specified shared context and generate a proper context description, for example:
187
+
188
+ ```
189
+ set_context(shared_context) { my_block }
190
+ ```
191
+
192
+ will act like this:
193
+
194
+ ```
195
+ context "when include context(#{name})" do
196
+ include_context name
197
+ my_block
198
+ end
199
+ ```
200
+
201
+ ---
202
+
203
+ ### let
204
+
205
+ #### create_params
206
+
207
+ `create_params` helps to create hash in just one line.
208
+
209
+ Suppose you have some variables like this:
210
+
211
+ ```
212
+ let(:name) { 'Alan' }
213
+ let(:age) { 20 }
214
+ ```
215
+
216
+ Generally, to create a hash with these variables, you need to write:
217
+
218
+ ```
219
+ let(:params) {{
220
+ name: name,
221
+ age: age
222
+ }}
223
+ ```
224
+
225
+ While in RSpecZ, you just use `create_params` and it will automatically create a hash with proper keys and values:
226
+
227
+ ```
228
+ create_params(:name, :age)
229
+ ```
230
+
231
+ #### string
232
+
233
+ `string` is useful when you are trying to create a number of strings,
234
+ it will create strings using the variable name with the prefix `test-`.
235
+
236
+ For example:
237
+
238
+ ```
239
+ string(name, address)
240
+ ```
241
+
242
+ This equals to:
243
+
244
+ ```
245
+ let(:name) { 'test-name' }
246
+ let(:address) { 'test-address' }
247
+ ```
248
+
249
+ ---
250
+
251
+ ### subject
252
+
253
+ #### subject_freezed
254
+
255
+ Some times the code needs to be tested under a specified time.
256
+ In RSpec, you will write code like this:
257
+
258
+ ```
259
+ let(:now) { Time.zone.now }
260
+ subject do
261
+ travel_to(now) do
262
+ my_block
263
+ end
264
+ end
265
+ ```
266
+
267
+ However, RSpecZ provides a simpler way to do this:
268
+
269
+ ```
270
+ let(:now) { Time.zone.now }
271
+ subject_freezed { my_block }
272
+ ```
273
+
274
+ ---
275
+
276
+ ### alias
277
+
278
+ #### make
279
+
280
+ `let` and `let!` are so confusing for rubyists when writing specs, for example:
281
+
282
+ ```
283
+ let(:user) { create(:user) }
284
+ let!(:post) { create(:post, user: user) } # eager evaluation
285
+ let(:like) { create(:like, user: user, post: post) }
286
+ let(:comment) { create(:comment, user: user, post: post) }
287
+ ```
288
+
289
+ In RSpecZ, you can use `make` instead of `let!`, which provides better identification and readability.
290
+
291
+ ```
292
+ let(:user) { create(:user) }
293
+ make(:post) { create(:post, user: user) } # eager evaluation
294
+ let(:like) { create(:like, user: user, post: post) }
295
+ let(:comment) { create(:comment, user: user, post: post) }
296
+ ```
297
+
298
+ #### behave
299
+
300
+ RSpecZ also provides a short version of `it_behaves_like` when you use `shared_examples`, just use the keyword `behave`:
301
+
302
+ ```
303
+ behave 'my_shared_examples'
304
+
305
+ # equals to:
306
+ # it_behaves_like 'my_shared_examples'
307
+ ```
32
308
 
33
309
  ## Contributing
34
310
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/RSpecZ. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
311
+ Bug reports and pull requests are welcome on GitHub.
36
312
 
37
313
  ## License
38
314
 
39
315
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
40
-
41
- ## Code of Conduct
42
-
43
- Everyone interacting in the RSpecZ project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/RSpecZ/blob/master/CODE_OF_CONDUCT.md).
@@ -71,7 +71,7 @@ module RSpec
71
71
  alias_method :block_context, :set_block
72
72
 
73
73
  def set_missing(name, value = 'missing-value', description = nil, &block)
74
- context description || "when #{name} is not exist(#{value})" do
74
+ context description || "when #{name} does not exist(#{value})" do
75
75
  let(name) { value }
76
76
  instance_exec(name, &block)
77
77
  end
@@ -0,0 +1,14 @@
1
+ module RSpecZ
2
+ METADATA_WITH_COUNT = :___rspecz_with_count
3
+ METADATA_SO_COUNT = :___rspecz_so_count
4
+
5
+ class << self
6
+ def describe(*args, &example_group_block)
7
+ RSpec.describe(*args, &example_group_block).tap do |result|
8
+ if result.metadata[RSpecZ::METADATA_WITH_COUNT] != result.metadata[RSpecZ::METADATA_SO_COUNT]
9
+ raise RuntimeError.new('You have some .with method without .so method. You may miss .so method in your code.')
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/rspecz/lets.rb CHANGED
@@ -15,7 +15,7 @@ module RSpec
15
15
  let(:with_nil) { false } unless __lib_method_defined?(:with_nil)
16
16
  let(:params) {
17
17
  array.each_with_object({}) do |elem, acc|
18
- acc[elem] = send(elem) if send(:with_nil) || send(elem).present?
18
+ acc[elem] = send(elem) if send(:with_nil) || !send(elem).nil?
19
19
  end
20
20
  }
21
21
  end
@@ -1,3 +1,3 @@
1
1
  module RSpecZ
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
data/lib/rspecz/with.rb CHANGED
@@ -30,6 +30,10 @@ module RSpec
30
30
  end
31
31
 
32
32
  def so(&block)
33
+ root_context = @myobject.send(:root_context)
34
+ so_count = root_context.metadata[RSpecZ::METADATA_SO_COUNT]
35
+ root_context.metadata[RSpecZ::METADATA_SO_COUNT] = so_count == nil ? 1 : so_count + 1;
36
+
33
37
  continue_object = self
34
38
  continue_object_block = @block
35
39
  # TODO: create description from block.source
@@ -46,7 +50,10 @@ module RSpec
46
50
  spec = @and_block.nil? ? spec_without_and : lambda do
47
51
  context "and #{continue_object.and_name} is #{continue_object.__get_description(continue_object.and_block.source, 'and')}" do
48
52
  let(continue_object.and_name) do
49
- @super = super() if defined? super
53
+ @super = lambda { super() } if defined? super
54
+ def _super
55
+ @super.call()
56
+ end
50
57
  instance_eval(&continue_object.and_block)
51
58
  end
52
59
  instance_exec(&spec_without_and)
@@ -65,7 +72,10 @@ module RSpec
65
72
  spec_without_and = lambda do
66
73
  if continue_object.name
67
74
  let(continue_object.name) do
68
- @super = super() if defined? super
75
+ @super = lambda { super() } if defined? super
76
+ def _super
77
+ @super.call()
78
+ end
69
79
  instance_eval(&continue_object_block)
70
80
  end
71
81
  else
@@ -151,6 +161,8 @@ module RSpec
151
161
  private
152
162
 
153
163
  def _with(name, hint, focused, values, block)
164
+ count_up_with_count
165
+
154
166
  with_context = WithContext.new(name, values, block, self)
155
167
  with_context.hint(hint) if hint
156
168
  with_context.focused if focused
@@ -159,6 +171,7 @@ module RSpec
159
171
 
160
172
  def _with_nil(names, focused)
161
173
  raise RuntimeError.new("Argument Error. You should set names.") if names.nil? || names.length == 0
174
+ count_up_with_count
162
175
 
163
176
  continue_object = { names: names, focused: focused, myobject: self }
164
177
 
@@ -167,6 +180,10 @@ module RSpec
167
180
  end
168
181
 
169
182
  def continue_object.so(&block)
183
+ root_context = self[:myobject].send(:root_context)
184
+ so_count = root_context.metadata[RSpecZ::METADATA_SO_COUNT]
185
+ root_context.metadata[RSpecZ::METADATA_SO_COUNT] = so_count == nil ? 1 : so_count + 1;
186
+
170
187
  continue_object = self
171
188
  continue_object[:names].each do |name|
172
189
  spec = lambda do
@@ -182,6 +199,19 @@ module RSpec
182
199
  end
183
200
  continue_object
184
201
  end
202
+
203
+ def count_up_with_count
204
+ with_count = root_context.metadata[RSpecZ::METADATA_WITH_COUNT]
205
+ root_context.metadata[RSpecZ::METADATA_WITH_COUNT] = with_count == nil ? 1 : with_count + 1
206
+ end
207
+
208
+ def root_context
209
+ current = self
210
+ # RSpec module describe how deep context is. So, minimum module class is the root context
211
+ current.parent_groups.min do |a,b|
212
+ a.ancestors.length <=> b.ancestors.length
213
+ end
214
+ end
185
215
  end
186
216
  end
187
217
  end
data/lib/rspecz.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'method_source'
1
2
  require 'rspec/core'
2
3
  require 'rspecz/version'
3
4
  require 'rspecz/contexts'
@@ -5,5 +6,6 @@ require 'rspecz/subjects'
5
6
  require 'rspecz/lets'
6
7
  require 'rspecz/with'
7
8
  require 'rspecz/behave'
9
+ require 'rspecz/describe'
8
10
  require 'rspecz/aliases/behave'
9
11
  require 'rspecz/aliases/make'
data/rspecz.gemspec CHANGED
@@ -6,11 +6,11 @@ require "rspecz/version"
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "rspecz"
8
8
  spec.version = RSpecZ::VERSION
9
- spec.authors = ["seteen"]
9
+ spec.authors = ["yazumoto"]
10
10
  spec.email = ["app.zenn@gmail.com"]
11
11
 
12
12
  spec.summary = %q{Provide functions for smart RSpec.}
13
- spec.homepage = "https://github.com/seteen/RSpecZ"
13
+ spec.homepage = "https://github.com/RSpecZ/RSpecZ"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
@@ -21,7 +21,9 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ["lib"]
22
22
 
23
23
  spec.add_dependency 'rspec', '>= 3.0'
24
+ spec.add_dependency 'method_source', '~> 0.9.0'
24
25
 
25
26
  spec.add_development_dependency "bundler", "~> 1.16"
26
27
  spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency 'pry'
27
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspecz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
- - seteen
7
+ - yazumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-09-01 00:00:00.000000000 Z
11
+ date: 2019-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: method_source
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
68
  version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
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'
55
83
  description:
56
84
  email:
57
85
  - app.zenn@gmail.com
@@ -75,12 +103,13 @@ files:
75
103
  - lib/rspecz/aliases/make.rb
76
104
  - lib/rspecz/behave.rb
77
105
  - lib/rspecz/contexts.rb
106
+ - lib/rspecz/describe.rb
78
107
  - lib/rspecz/lets.rb
79
108
  - lib/rspecz/subjects.rb
80
109
  - lib/rspecz/version.rb
81
110
  - lib/rspecz/with.rb
82
111
  - rspecz.gemspec
83
- homepage: https://github.com/seteen/RSpecZ
112
+ homepage: https://github.com/RSpecZ/RSpecZ
84
113
  licenses:
85
114
  - MIT
86
115
  metadata: {}
@@ -99,8 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
128
  - !ruby/object:Gem::Version
100
129
  version: '0'
101
130
  requirements: []
102
- rubyforge_project:
103
- rubygems_version: 2.7.6
131
+ rubygems_version: 3.0.1
104
132
  signing_key:
105
133
  specification_version: 4
106
134
  summary: Provide functions for smart RSpec.