webspicy 0.16.3 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -3
  3. data/examples/restful/Gemfile.lock +14 -13
  4. data/examples/restful/webspicy/config.rb +1 -0
  5. data/examples/restful/webspicy/{todo/deleteTodo.yml → formaldef/todo/_one/delete.yml} +3 -0
  6. data/examples/restful/webspicy/{todo/getTodoSingleServiceFormat.yml → formaldef/todo/_one/get.simpler.yml} +0 -0
  7. data/examples/restful/webspicy/{todo/getTodo.yml → formaldef/todo/_one/get.yml} +0 -0
  8. data/examples/restful/webspicy/{todo/patchTodo.yml → formaldef/todo/_one/patch.yml} +0 -0
  9. data/examples/restful/webspicy/{todo/putTodo.yml → formaldef/todo/_one/put.yml} +0 -0
  10. data/examples/restful/webspicy/{todo/getTodos.yml → formaldef/todo/get.yml} +0 -0
  11. data/examples/restful/webspicy/{todo → formaldef/todo}/options.yml +0 -0
  12. data/examples/restful/webspicy/{todo/postCsv.yml → formaldef/todo/post.csv.yml} +0 -0
  13. data/examples/restful/webspicy/{todo/postFile.yml → formaldef/todo/post.file.yml} +0 -0
  14. data/examples/restful/webspicy/{todo/postTodos.yml → formaldef/todo/post.yml} +0 -0
  15. data/examples/restful/webspicy/{todo → formaldef/todo}/todos.csv +0 -0
  16. data/examples/restful/webspicy/support/todo_not_removed.rb +21 -0
  17. data/examples/restful/webspicy/support/todo_removed.rb +5 -3
  18. data/lib/webspicy.rb +1 -0
  19. data/lib/webspicy/checker.rb +5 -20
  20. data/lib/webspicy/configuration.rb +9 -0
  21. data/lib/webspicy/configuration/scope.rb +0 -8
  22. data/lib/webspicy/formaldoc.fio +2 -0
  23. data/lib/webspicy/rspec/checker.rb +2 -0
  24. data/lib/webspicy/rspec/checker/rspec_checker.rb +24 -0
  25. data/lib/webspicy/rspec/support/rspec_runnable.rb +27 -0
  26. data/lib/webspicy/rspec/tester.rb +4 -0
  27. data/lib/webspicy/{tester → rspec/tester}/rspec_asserter.rb +23 -10
  28. data/lib/webspicy/{tester → rspec/tester}/rspec_matchers.rb +10 -0
  29. data/lib/webspicy/rspec/tester/rspec_tester.rb +63 -0
  30. data/lib/webspicy/specification.rb +5 -7
  31. data/lib/webspicy/specification/errcondition.rb +16 -0
  32. data/lib/webspicy/specification/service.rb +27 -19
  33. data/lib/webspicy/specification/test_case.rb +3 -9
  34. data/lib/webspicy/support.rb +1 -0
  35. data/lib/webspicy/support/data_object.rb +25 -0
  36. data/lib/webspicy/tester.rb +4 -78
  37. data/lib/webspicy/tester/asserter.rb +9 -4
  38. data/lib/webspicy/tester/assertions.rb +8 -9
  39. data/lib/webspicy/tester/failure.rb +6 -0
  40. data/lib/webspicy/tester/invocation.rb +8 -156
  41. data/lib/webspicy/version.rb +2 -2
  42. data/spec/unit/configuration/scope/test_each_service.rb +2 -2
  43. data/spec/unit/configuration/scope/test_each_specification.rb +7 -7
  44. data/spec/unit/test_configuration.rb +1 -1
  45. data/spec/unit/tester/test_asserter.rb +198 -3
  46. data/spec/unit/tester/test_assertions.rb +8 -6
  47. metadata +27 -18
@@ -0,0 +1,63 @@
1
+ module Webspicy
2
+ class Tester
3
+ class RSpecTester
4
+ include Webspicy::Support::RSpecRunnable
5
+
6
+ protected
7
+
8
+ def load_rspec_examples
9
+ tester = self
10
+ RSpec.describe "Webspicy test suite" do
11
+ before(:all) do
12
+ tester.config.listeners(:before_all).each do |l|
13
+ l.call(tester.config)
14
+ end
15
+ end
16
+ after(:all) do
17
+ tester.config.listeners(:after_all).each do |l|
18
+ l.call(tester.config)
19
+ end
20
+ end
21
+ tester.config.each_scope do |scope|
22
+ client = scope.get_client
23
+ scope.each_specification do |specification|
24
+ scope.each_service(specification) do |service|
25
+ scope.each_testcase(service) do |test_case|
26
+ str = "#{service} #{test_case}"
27
+ str = Webspicy::Support::Colorize.colorize_highlight(str, tester.config)
28
+ describe(str) do
29
+
30
+ around(:each) do |example|
31
+ client.around(test_case) do
32
+ client.before(test_case)
33
+ test_case.instrument(client)
34
+ client.instrument(test_case)
35
+ @response = client.call(test_case)
36
+ @invocation = Tester::Invocation.new(test_case, @response, client)
37
+ example.run
38
+ client.after(test_case, @invocation)
39
+ @invocation
40
+ end
41
+ end
42
+
43
+ let(:invocation) do
44
+ @invocation
45
+ end
46
+
47
+ it "meets its specification" do
48
+ raise "Test not ran" unless invocation.done?
49
+ RSpecAsserter.call(self, invocation)
50
+ end
51
+
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ self
59
+ end
60
+
61
+ end # class RSpecTester
62
+ end # class Tester
63
+ end # module Webspicy
@@ -1,11 +1,13 @@
1
1
  module Webspicy
2
2
  class Specification
3
+ include Support::DataObject
3
4
 
4
5
  def initialize(raw, location = nil)
5
- @raw = raw
6
+ super(raw)
6
7
  @location = location
7
8
  bind_services
8
9
  end
10
+ attr_accessor :config
9
11
  attr_reader :location
10
12
 
11
13
  def self.info(raw)
@@ -46,7 +48,7 @@ module Webspicy
46
48
  end
47
49
 
48
50
  def services
49
- @raw[:services]
51
+ @raw[:services] || []
50
52
  end
51
53
 
52
54
  def url_placeholders
@@ -62,10 +64,6 @@ module Webspicy
62
64
  [ url, rest ]
63
65
  end
64
66
 
65
- def to_info
66
- @raw
67
- end
68
-
69
67
  def to_singleservice
70
68
  raise NotImplementedError
71
69
  end
@@ -87,7 +85,7 @@ module Webspicy
87
85
  end
88
86
 
89
87
  def bind_services
90
- (@raw[:services] ||= []).each do |s|
88
+ services.each do |s|
91
89
  s.specification = self
92
90
  end
93
91
  end
@@ -0,0 +1,16 @@
1
+ module Webspicy
2
+ class Specification
3
+ module Errcondition
4
+
5
+ def self.match(service, descr)
6
+ end
7
+
8
+ def instrument(test_case, client)
9
+ end
10
+
11
+ def check(invocation)
12
+ end
13
+
14
+ end # module Errcondition
15
+ end # module Specification
16
+ end # module Webspicy
@@ -1,13 +1,12 @@
1
1
  module Webspicy
2
2
  class Specification
3
3
  class Service
4
+ include Support::DataObject
4
5
 
5
6
  def initialize(raw)
6
- @raw = raw
7
+ super(raw)
7
8
  bind_examples
8
9
  bind_counterexamples
9
- @preconditions = compile_preconditions
10
- @postconditions = compile_postconditions
11
10
  end
12
11
  attr_accessor :specification
13
12
 
@@ -15,6 +14,10 @@ module Webspicy
15
14
  new(raw)
16
15
  end
17
16
 
17
+ def config
18
+ specification.config
19
+ end
20
+
18
21
  def method
19
22
  @raw[:method]
20
23
  end
@@ -24,7 +27,7 @@ module Webspicy
24
27
  end
25
28
 
26
29
  def preconditions
27
- @preconditions
30
+ @preconditions ||= compile_preconditions
28
31
  end
29
32
 
30
33
  def has_preconditions?
@@ -32,23 +35,31 @@ module Webspicy
32
35
  end
33
36
 
34
37
  def postconditions
35
- @postconditions
38
+ @postconditions ||= compile_postconditions
36
39
  end
37
40
 
38
41
  def has_postconditions?
39
42
  !postconditions.empty?
40
43
  end
41
44
 
45
+ def errconditions
46
+ @errconditions ||= compile_errconditions
47
+ end
48
+
49
+ def has_errconditions?
50
+ !errconditions.empty?
51
+ end
52
+
42
53
  def default_example
43
54
  @raw[:default_example]
44
55
  end
45
56
 
46
57
  def examples
47
- @raw[:examples]
58
+ @raw[:examples] || []
48
59
  end
49
60
 
50
61
  def counterexamples
51
- @raw[:counterexamples]
62
+ @raw[:counterexamples] || []
52
63
  end
53
64
 
54
65
  def generated_counterexamples
@@ -76,28 +87,25 @@ module Webspicy
76
87
  input_schema.dress(params)
77
88
  end
78
89
 
79
- def to_info
80
- @raw
81
- end
82
-
83
90
  def to_s
84
91
  "#{method} #{specification.url}"
85
92
  end
86
93
 
87
94
  private
88
95
 
89
- def scope
90
- Webspicy.current_scope
91
- end
92
-
93
96
  def compile_preconditions
94
97
  @raw[:preconditions] = [@raw[:preconditions]] if @raw[:preconditions].is_a?(String)
95
- compile_conditions(@raw[:preconditions] ||= [], scope.preconditions)
98
+ compile_conditions(@raw[:preconditions] ||= [], config.preconditions)
96
99
  end
97
100
 
98
101
  def compile_postconditions
99
102
  @raw[:postconditions] = [@raw[:postconditions]] if @raw[:postconditions].is_a?(String)
100
- compile_conditions(@raw[:postconditions] ||= [], scope.postconditions)
103
+ compile_conditions(@raw[:postconditions] ||= [], config.postconditions)
104
+ end
105
+
106
+ def compile_errconditions
107
+ @raw[:errconditions] = [@raw[:errconditions]] if @raw[:errconditions].is_a?(String)
108
+ compile_conditions(@raw[:errconditions] ||= [], config.errconditions)
101
109
  end
102
110
 
103
111
  def compile_conditions(descriptions, conditions)
@@ -112,13 +120,13 @@ module Webspicy
112
120
  end
113
121
 
114
122
  def bind_examples
115
- (@raw[:examples] ||= []).each do |ex|
123
+ examples.each do |ex|
116
124
  ex.bind(self, false)
117
125
  end
118
126
  end
119
127
 
120
128
  def bind_counterexamples
121
- (@raw[:counterexamples] ||= []).each do |ex|
129
+ counterexamples.each do |ex|
122
130
  ex.bind(self, true)
123
131
  end
124
132
  end
@@ -1,17 +1,15 @@
1
1
  module Webspicy
2
2
  class Specification
3
3
  class TestCase
4
+ include Support::DataObject
4
5
 
5
6
  def initialize(raw)
6
- @raw = raw
7
+ super(raw)
7
8
  @counterexample = nil
8
9
  end
9
10
  attr_reader :service
10
11
  attr_reader :counterexample
11
12
 
12
- attr_accessor :raw
13
- protected :raw, :raw=
14
-
15
13
  def bind(service, counterexample)
16
14
  @service = service
17
15
  @counterexample = counterexample
@@ -111,13 +109,9 @@ module Webspicy
111
109
  !assert.empty?
112
110
  end
113
111
 
114
- def to_info
115
- @raw
116
- end
117
-
118
112
  def instrument(client)
119
113
  service.preconditions.each do |pre|
120
- pre.instrument(self, client)
114
+ pre.instrument(self, client) if pre.respond_to?(:instrument)
121
115
  end
122
116
  service.postconditions.each do |post|
123
117
  post.instrument(self, client) if post.respond_to?(:instrument)
@@ -1,2 +1,3 @@
1
+ require_relative 'support/data_object'
1
2
  require_relative 'support/status_range'
2
3
  require_relative 'support/colorize'
@@ -0,0 +1,25 @@
1
+ module Webspicy
2
+ module Support
3
+ module DataObject
4
+
5
+ def initialize(raw)
6
+ @raw = raw
7
+ end
8
+ attr_accessor :raw
9
+ protected :raw, :raw=
10
+
11
+ def method_missing(name, *args, &bl)
12
+ if @raw.has_key?(name) && args.empty? && bl.nil?
13
+ @raw[name]
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ def to_info
20
+ @raw
21
+ end
22
+
23
+ end # module DataObject
24
+ end # module Support
25
+ end # module Webspicy
@@ -1,89 +1,15 @@
1
1
  module Webspicy
2
2
  class Tester
3
- include Webspicy::Support::Colorize
4
3
 
5
- def initialize(config)
6
- @config = Configuration.dress(config)
7
- @test_suite = load
8
- end
9
- attr_reader :config
10
-
11
- def call(err=$stderr, out=$stdout)
12
- $_rspec_core_load_started_at = nil
13
- options = RSpec::Core::ConfigurationOptions.new(config.rspec_options)
14
- conf = RSpec::Core::Configuration.new
15
- RSpec::Core::Runner.new(options, conf).run(err, out)
16
- end
17
-
18
- # protected
19
-
20
- def load
21
- tester = self
22
- RSpec.reset
23
- rspec_config!
24
- RSpec.describe "" do
25
- before(:all) do
26
- tester.config.listeners(:before_all).each do |l|
27
- l.call(tester.config)
28
- end
29
- end
30
- after(:all) do
31
- tester.config.listeners(:after_all).each do |l|
32
- l.call(tester.config)
33
- end
34
- end
35
- tester.config.each_scope do |scope|
36
- client = scope.get_client
37
- scope.each_specification do |specification|
38
- scope.each_service(specification) do |service|
39
- tester.rspec_service!(self, service, client, scope)
40
- end
41
- end
42
- end
43
- end
44
- self
45
- end
46
-
47
- def rspec_service!(on, service, client, scope)
48
- scope.each_testcase(service) do |test_case|
49
- str = "#{service} #{test_case}"
50
- str = colorize_highlight(str)
51
- on.describe(str) do
52
- include_examples 'a successful test case invocation', client, test_case
53
- end
54
- end
55
- end
56
-
57
- def rspec_config!
58
- RSpec.shared_examples "a successful test case invocation" do |client, test_case|
59
-
60
- around(:each) do |example|
61
- client.around(test_case) do
62
- client.before(test_case)
63
- test_case.instrument(client)
64
- client.instrument(test_case)
65
- @response = client.call(test_case)
66
- @invocation = Tester::Invocation.new(test_case, @response, client)
67
- example.run
68
- client.after(test_case, @invocation)
69
- @invocation
70
- end
71
- end
72
-
73
- let(:invocation) do
74
- @invocation
75
- end
76
-
77
- it "meets its specification" do
78
- raise "Test not ran" unless invocation.done?
79
- invocation.rspec_assert!(self)
80
- end
81
- end
4
+ def self.new(*args, &bl)
5
+ require_relative 'rspec/tester'
6
+ RSpecTester.new(*args, &bl)
82
7
  end
83
8
 
84
9
  end # class Tester
85
10
  end # module Webspicy
86
11
  require_relative 'tester/client'
87
12
  require_relative 'tester/invocation'
13
+ require_relative 'tester/failure'
88
14
  require_relative 'tester/assertions'
89
15
  require_relative 'tester/asserter'
@@ -78,14 +78,19 @@ module Webspicy
78
78
  expected = id
79
79
  id, path = path, ''
80
80
  end
81
- unless @assertions.idFD(@target, path, id, expected)
82
- _! "Expected #{_s(@target, path)} to meet FD #{expected.inspect}"
81
+ element = @assertions.element_with_id(@target, path, id)
82
+ unless element
83
+ _! "Expected an element with id #{id} to contain the key(s) and value(s) #{expected}, but there is no element with that id"
84
+ end
85
+
86
+ unless @assertions.idFD(element, expected)
87
+ _! "Expected #{_s(@target, path)} to contain the key(s) and value(s) #{expected}"
83
88
  end
84
89
  end
85
90
 
86
91
  def pathFD(path, expected)
87
92
  unless @assertions.pathFD(@target, path, expected)
88
- _! "#{expected.inspect} vs. #{_s(@target, path)}"
93
+ _! "Expected #{_s(@target, path)} to contain the key(s) and value(s) #{expected}"
89
94
  end
90
95
  end
91
96
 
@@ -121,7 +126,7 @@ module Webspicy
121
126
  end
122
127
 
123
128
  def _!(msg)
124
- raise msg
129
+ raise Failure, msg
125
130
  end
126
131
 
127
132
  end # class Asserter
@@ -63,16 +63,15 @@ module Webspicy
63
63
  (ids.to_set & expected.to_set).empty?
64
64
  end
65
65
 
66
- def idFD(target, path, id, expected = NO_ARG)
67
- if expected == NO_ARG
68
- expected = id
69
- id, path = path, ''
70
- end
66
+ def element_with_id(target, path, id)
71
67
  target = extract_path(target, path)
72
- found = an_array(target).find{|t| t[:id] == id }
73
- expected.keys.all?{|k|
74
- value_equal(expected[k], found[k])
75
- }
68
+ an_array(target).find { |t| t[:id] == id }
69
+ end
70
+
71
+ def idFD(element, expected)
72
+ expected.keys.all? do |k|
73
+ value_equal(expected[k], element[k])
74
+ end
76
75
  end
77
76
 
78
77
  def pathFD(target, path, expected)