webspicy 0.8.6 → 0.9.0

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
  SHA1:
3
- metadata.gz: 907eaa3406ba8520d040fc96133faf16d5b7a357
4
- data.tar.gz: ea0d8ec2b1932f64ea4266c01e4ec31b283ded63
3
+ metadata.gz: 9ee44fbfe2ca04541a590d8d5cac3afc54e8bb92
4
+ data.tar.gz: b92cf71bf4ab3715918f544706f84a1f580ec59a
5
5
  SHA512:
6
- metadata.gz: 64de80d4499aa9fad0578111a259d903fc804ec07af1805d0c84490531f7fece535060c5ea3947a25a06e9e7833cede56404d8fb4087164c990199e1105f479c
7
- data.tar.gz: eaf0c4859bc5bbd844e0588e12620f270440b81a9acffc0211486a5a0d30a71725243b7b3febde8f63e495d0cad0150ebc54398fe9f4d40c81b83120a4a1362c
6
+ metadata.gz: 2478429f74cdf469a7182054bd6f9b110b2460bfbb7f6c8631dc3f554ff9c1c5e7dcfde9da928fd05316b5d71c3495daad6650e83802f7bc742eb582a3400586
7
+ data.tar.gz: 941daafd12fffa3d700b3bd4023ca009027fb229f9e13193582fda47bef18764f3cebb51c5995574b6436b40bf60e84294c9632257dfa475914dc365688c74bb
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- webspicy (0.8.4)
5
- finitio (~> 0.5.2)
4
+ webspicy (0.9.0)
5
+ finitio (>= 0.5.2)
6
6
  http (~> 2)
7
7
  path (~> 1.3)
8
8
  rack-robustness (~> 1.1.0)
9
9
  rack-test (~> 0.6.3)
10
- rspec (~> 3.6)
10
+ rspec (~> 3.7)
11
11
 
12
12
  GEM
13
13
  remote: https://rubygems.org/
@@ -10,12 +10,42 @@ module Webspicy
10
10
  scope.config
11
11
  end
12
12
 
13
+ def around(*args, &bl)
14
+ args << self
15
+ ls = config.listeners(:around_each)
16
+ if ls.size == 0
17
+ bl.call
18
+ elsif ls.size > 1
19
+ _around(ls.first, ls[1..-1], args, &bl)
20
+ else
21
+ ls.first.call(*args, &bl)
22
+ end
23
+ end
24
+
25
+ def _around(head, tail, args, &bl)
26
+ head.call(*args) do
27
+ if tail.empty?
28
+ bl.call
29
+ else
30
+ _around(tail.first, tail[1..-1], args, &bl)
31
+ end
32
+ end
33
+ end
34
+ private :_around
35
+
13
36
  def before(*args, &bl)
14
- config.before_listeners.each do |beach|
15
- args << self
37
+ args << self
38
+ config.listeners(:before_each).each do |beach|
16
39
  beach.call(*args, &bl)
17
40
  end
18
41
  end
19
42
 
43
+ def after(*args, &bl)
44
+ args << self
45
+ config.listeners(:after_each).each do |aeach|
46
+ aeach.call(*args, &bl)
47
+ end
48
+ end
49
+
20
50
  end
21
51
  end
@@ -1,13 +1,15 @@
1
1
  module Webspicy
2
2
  class Configuration
3
3
 
4
+ LISTENER_KINDS = [ :before_all, :before_each, :after_all, :after_each, :around_each ]
5
+
4
6
  def initialize(folder = Path.pwd, parent = nil)
5
7
  @folder = folder
6
8
  @parent = parent
7
9
  @children = []
8
10
  @preconditions = []
9
11
  @postconditions = []
10
- @before_listeners = []
12
+ @listeners = Hash.new{|h,k| h[k] = [] }
11
13
  @rspec_options = default_rspec_options
12
14
  @run_counterexamples = default_run_counterexamples
13
15
  @file_filter = default_file_filter
@@ -194,21 +196,56 @@ module Webspicy
194
196
  end
195
197
  attr_reader :client
196
198
 
199
+ # Registers a listener under a given kind.
200
+ def register_listener(kind, listener)
201
+ raise "Must respond to call" unless listener.respond_to?(:call)
202
+ @listeners[kind] << listener
203
+ end
204
+ private :register_listener
205
+
206
+ # Returns the listeners of a specific kind.
207
+ #
208
+ # Recognized kinds are `before_each`, `after_each`, `before_all` and `after_all`
209
+ def listeners(kind)
210
+ @listeners[kind]
211
+ end
212
+ attr_writer :listeners
213
+ protected :listeners=
214
+
215
+ # Installs a listener that will be called before all tests
216
+ #
217
+ # The `listener` must respond to `call`.
218
+ def before_all(&listener)
219
+ register_listener(:before_all, listener)
220
+ end
221
+
197
222
  # Installs a listener that will be called before each web service invocation.
198
223
  #
199
224
  # The `listener` must respond to `call`.
200
225
  def before_each(&listener)
201
- raise "Must respond to call" unless listener.respond_to?(:call)
202
- @before_listeners << listener
226
+ register_listener(:before_each, listener)
227
+ end
228
+
229
+ # Installs a listener that will be called after all tests
230
+ #
231
+ # The `listener` must respond to `call`.
232
+ def after_all(&listener)
233
+ register_listener(:after_all, listener)
203
234
  end
204
235
 
205
- # Returns the list of listeners that must be called before each web service
206
- # invocation.
207
- def before_listeners
208
- @before_listeners
236
+ # Installs a listener that will be called after each web service invocation.
237
+ #
238
+ # The `listener` must respond to `call`.
239
+ def after_each(&listener)
240
+ register_listener(:after_each, listener)
241
+ end
242
+
243
+ # Installs a listener that will be called around each web service invocation.
244
+ #
245
+ # The `listener` must respond to `call`.
246
+ def around_each(&listener)
247
+ register_listener(:around_each, listener)
209
248
  end
210
- attr_writer :before_listeners
211
- protected :before_listeners=
212
249
 
213
250
  # Allows setting the options passed at RSpec, which is used by both the runner
214
251
  # and checker classes.
@@ -267,7 +304,9 @@ module Webspicy
267
304
  d.preconditions = self.preconditions.dup
268
305
  d.postconditions = self.postconditions.dup
269
306
  d.rspec_options = self.rspec_options.dup
270
- d.before_listeners = self.before_listeners.dup
307
+ d.listeners = LISTENER_KINDS.inject({}){|ls,kind|
308
+ ls.merge(kind => self.listeners(kind).dup)
309
+ }
271
310
  yield d if block_given?
272
311
  end
273
312
  end
@@ -25,7 +25,7 @@ module Webspicy
25
25
  def instantiate_url(params)
26
26
  url, rest = self.url, params.dup
27
27
  url_placeholders.each do |placeholder|
28
- value, rest = extract_placeholder_value(params, placeholder)
28
+ value, rest = extract_placeholder_value(rest, placeholder)
29
29
  url = url.gsub("{#{placeholder}}", value.to_s)
30
30
  end
31
31
  [ url, rest ]
@@ -3,24 +3,48 @@ module Webspicy
3
3
 
4
4
  def initialize(config)
5
5
  @config = Configuration.dress(config)
6
+ @test_suite = load
6
7
  end
7
8
  attr_reader :config
8
9
 
9
- def call
10
+ def call(err=$stderr, out=$stdout)
11
+ $_rspec_core_load_started_at = nil
12
+ options = RSpec::Core::ConfigurationOptions.new(config.rspec_options)
13
+ conf = RSpec::Core::Configuration.new
14
+ RSpec::Core::Runner.new(options, conf).run(err, out)
15
+ end
16
+
17
+ # protected
18
+
19
+ def load
20
+ tester = self
21
+ RSpec.reset
10
22
  rspec_config!
11
- config.each_scope do |scope|
12
- client = scope.get_client
13
- scope.each_resource do |resource|
14
- scope.each_service(resource) do |service|
15
- rspec_service!(service, client, scope)
23
+ RSpec.describe "Webspicy test suite" do
24
+ before(:all) do
25
+ tester.config.listeners(:before_all).each do |l|
26
+ l.call(tester.config)
27
+ end
28
+ end
29
+ after(:all) do
30
+ tester.config.listeners(:after_all).each do |l|
31
+ l.call(tester.config)
32
+ end
33
+ end
34
+ tester.config.each_scope do |scope|
35
+ client = scope.get_client
36
+ scope.each_resource do |resource|
37
+ scope.each_service(resource) do |service|
38
+ tester.rspec_service!(self, service, client, scope)
39
+ end
16
40
  end
17
41
  end
18
42
  end
19
- RSpec::Core::Runner.run config.rspec_options
43
+ self
20
44
  end
21
45
 
22
- def rspec_service!(service, client, scope)
23
- RSpec.describe service do
46
+ def rspec_service!(on, service, client, scope)
47
+ on.describe service do
24
48
  scope.each_testcase(service) do |test_case, counterexample|
25
49
  describe test_case do
26
50
  include_examples 'a successful test case invocation', client, test_case, counterexample
@@ -30,14 +54,15 @@ module Webspicy
30
54
  end
31
55
 
32
56
  def rspec_config!
33
- return if @rspec_config
34
57
  RSpec.shared_examples "a successful test case invocation" do |client, test_case, counterexample|
35
58
 
36
- before(:all) do
37
- @invocation ||= begin
59
+ around(:each) do |example|
60
+ client.around(test_case) do
38
61
  client.before(test_case)
39
62
  test_case.instrument(client)
40
- client.call(test_case)
63
+ @invocation = client.call(test_case)
64
+ example.run
65
+ client.after(test_case)
41
66
  end
42
67
  end
43
68
 
@@ -45,27 +70,17 @@ module Webspicy
45
70
  @invocation
46
71
  end
47
72
 
48
- it 'meets the HTTP specification' do
73
+ it 'meets its specification' do
49
74
  expect(invocation.done?).to eq(true)
50
75
  expect(invocation.expected_status_unmet).to(be_nil)
51
76
  expect(invocation.expected_content_type_unmet).to(be_nil)
52
77
  expect(invocation.expected_headers_unmet).to(be_nil) if test_case.has_expected_headers?
53
78
  expect(invocation.expected_schema_unmet).to(be_nil)
79
+ expect(invocation.assertions_unmet).to(be_nil) if test_case.has_assertions?
80
+ expect(invocation.postconditions_unmet).to(be_nil) if test_case.service.has_postconditions? and not(counterexample)
81
+ expect(invocation.expected_error_unmet).to(be_nil) if test_case.has_expected_error?
54
82
  end
55
-
56
- it 'meets all specific assertions' do
57
- expect(invocation.assertions_unmet).to(be_nil)
58
- end if test_case.has_assertions?
59
-
60
- it 'meets declarative postconditions' do
61
- expect(invocation.postconditions_unmet).to(be_nil)
62
- end if test_case.service.has_postconditions? and not(counterexample)
63
-
64
- it 'meets the specific error messages, if any (backward compatibility)' do
65
- expect(@invocation.expected_error_unmet).to(be_nil)
66
- end if test_case.has_expected_error?
67
83
  end
68
- @rspec_config = true
69
84
  end
70
85
 
71
86
  end # class Tester
@@ -1,8 +1,8 @@
1
1
  module Webspicy
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 8
5
- TINY = 6
4
+ MINOR = 9
5
+ TINY = 0
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ module Webspicy
3
+ describe Client, "around" do
4
+
5
+ it 'work with no around at all' do
6
+ config = Configuration.new
7
+
8
+ seen = false
9
+ block = ->(){ seen = true }
10
+
11
+ scope = Scope.new(config)
12
+ Client.new(scope).around(1, 2, 3, &block)
13
+ expect(seen).to be(true)
14
+ end
15
+
16
+ it 'work with one around' do
17
+ config = Configuration.new
18
+
19
+ seen = false
20
+ seen_args = nil
21
+ config.around_each do |*args, &bl|
22
+ seen_args = args
23
+ bl.call
24
+ end
25
+
26
+ scope = Scope.new(config)
27
+ block = ->(){ seen = true }
28
+ Client.new(scope).around(1, 2, 3, &block)
29
+
30
+ expect(seen_args[0...-1]).to eql([1, 2, 3])
31
+ expect(seen).to be(true)
32
+ end
33
+
34
+ it 'works with two arounds' do
35
+ config = Configuration.new
36
+
37
+ seen = false
38
+
39
+ seen_args = []
40
+ config.around_each do |*args, &bl|
41
+ seen_args << args
42
+ bl.call
43
+ end
44
+ config.around_each do |*args, &bl|
45
+ seen_args << args
46
+ bl.call
47
+ end
48
+
49
+ scope = Scope.new(config)
50
+ block = ->(){ seen = true }
51
+ Client.new(scope).around(1, 2, 3, &block)
52
+
53
+ expect(seen_args.size).to eql(2)
54
+ expect(seen_args.all?{|sa| sa[0...-1] == [1,2,3] }).to be(true)
55
+ expect(seen).to be(true)
56
+ end
57
+
58
+ end
59
+ end
@@ -16,6 +16,13 @@ module Webspicy
16
16
  expect(params).to eq(baz: "coz")
17
17
  end
18
18
 
19
+ it 'instantiates placeholders and strips corresponding params even when multiple' do
20
+ r = Resource.new(url: "/test/{foo}/url/{bar}")
21
+ url, params = r.instantiate_url(foo: "bar", bar: "baz", baz: "coz")
22
+ expect(url).to eq("/test/bar/url/baz")
23
+ expect(params).to eq(baz: "coz")
24
+ end
25
+
19
26
  it 'supports placeholders corresponding to subentities' do
20
27
  r = Resource.new(url: "/test/{foo.id}/url")
21
28
  url, params = r.instantiate_url(foo: {id: "bar"}, baz: "coz")
@@ -144,6 +144,30 @@ module Webspicy
144
144
  end
145
145
  end
146
146
 
147
+ describe 'before/after/listeners' do
148
+
149
+ let(:before_eacher) { ->(){} }
150
+ let(:after_eacher) { ->(){} }
151
+ let(:before_aller) { ->(){} }
152
+ let(:after_aller) { ->(){} }
153
+ let(:config) do
154
+ Configuration.new(Path.dir/'resource') do |c|
155
+ c.before_all(&before_aller)
156
+ c.before_each(&before_eacher)
157
+ c.after_each(&after_eacher)
158
+ c.after_all(&after_aller)
159
+ end
160
+ end
161
+
162
+ it 'correctly classifies and returns them on listeners' do
163
+ expect(config.listeners(:before_each)).to eql([before_eacher])
164
+ expect(config.listeners(:after_each)).to eql([after_eacher])
165
+ expect(config.listeners(:before_all)).to eql([before_aller])
166
+ expect(config.listeners(:after_all)).to eql([after_aller])
167
+ end
168
+
169
+ end
170
+
147
171
  describe 'dup' do
148
172
 
149
173
  let(:original) do
@@ -166,6 +190,7 @@ module Webspicy
166
190
  duped = original.dup do |d|
167
191
  d.rspec_options << "--hello"
168
192
  d.before_each do end
193
+ d.after_each do end
169
194
  d.precondition Class.new
170
195
  d.postcondition Class.new
171
196
  end
@@ -174,8 +199,9 @@ module Webspicy
174
199
  expect(duped.preconditions.size).to eq(1)
175
200
  expect(duped.postconditions.size).to eq(1)
176
201
 
177
- expect(duped.before_listeners.size).to eq(1)
178
- expect(original.before_listeners.size).to eq(0)
202
+ expect(duped.listeners(:before_each).size).to eq(1)
203
+ expect(original.listeners(:before_each).size).to eq(0)
204
+
179
205
  expect(original.preconditions.size).to eq(0)
180
206
  expect(original.postconditions.size).to eq(0)
181
207
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webspicy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.6
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.6'
47
+ version: '3.7'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.6'
54
+ version: '3.7'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rack-test
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -163,6 +163,7 @@ files:
163
163
  - lib/webspicy/tester/asserter.rb
164
164
  - lib/webspicy/tester/assertions.rb
165
165
  - lib/webspicy/version.rb
166
+ - spec/unit/client/test_around.rb
166
167
  - spec/unit/configuration/config.rb
167
168
  - spec/unit/resource/service/test_dress_params.rb
168
169
  - spec/unit/resource/test_instantiate_url.rb