rspecz 0.1.1 → 0.1.2

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