webspicy 0.15.3 → 0.15.8

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: d510f36443e5ef38eaabf4c09c6286c1e1aa556a9bb67fd5f5b67303b1faef4c
4
- data.tar.gz: bb8b064c714f10bef673d6e61fa0fe71037d8b0e0f8479a4bdb874bbce5484e6
3
+ metadata.gz: e1d234226f15d51777e61c010557ed1691660613cd87ba11ce19844b2f7cc812
4
+ data.tar.gz: 40fcd4639ce847f7f69f3471ef9676c64e8e6be489388563d5abd51ca1bf39d7
5
5
  SHA512:
6
- metadata.gz: dce79c2eba1d8fa74408280cabc8d06eee163fc4f1e8d5b8dfbfb1d4f167063dba68c54a0b1f18d4a72ac2ae88baa5f1a169f9f54b9073cce2c1174efd0b02a8
7
- data.tar.gz: b0665863864804a9977c73f25eb22d12930cf623e0db3bf67ea07a15d81162434ecf0e5cf1c12007abba6a6d1ea37f8fdb91cb99afa82893fd4e0b15c7d98ec6
6
+ metadata.gz: c4d0ec9a0567955bac41c5ee887164e783799e2baf66966fabff404147376c29192a4b28090c7d816a20fd15bc7e470b20136e253b9b1a7d663ac57de4958d99
7
+ data.tar.gz: 4ddccde82357c81066108133b0e5b63ea8b5a0b714556b56b4d4743ba26aaaf17a9187633061dc2f721b88833cdfb536f795d8256aa158723c4fa5a255957144
@@ -29,7 +29,8 @@ if ARGV.size != 1
29
29
  exit(-1)
30
30
  elsif (p = Path(ARGV.first)).exists?
31
31
  config = Webspicy::Configuration.dress(p)
32
- Webspicy::Tester.new(config).call
32
+ res = Webspicy::Tester.new(config).call
33
+ abort("Some tests failed") unless res == 0
33
34
  else
34
35
  puts "No such file or directory `#{ARGV.first}`"
35
36
  showhelp
@@ -1,5 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "rake", "~> 10"
4
- gem 'sinatra', "~> 2.0", ">= 2.0.2"
3
+ gem "rake", "~> 12"
4
+ gem 'sinatra', "~> 2"
5
5
  gem "webspicy", path: "../.."
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- webspicy (0.15.3)
4
+ webspicy (0.15.8)
5
5
  finitio (>= 0.8.0)
6
6
  http (>= 2)
7
7
  mustermann (~> 1.0)
@@ -18,48 +18,53 @@ GEM
18
18
  addressable (2.7.0)
19
19
  public_suffix (>= 2.0.2, < 5.0)
20
20
  citrus (3.0.2)
21
- diff-lcs (1.3)
21
+ diff-lcs (1.4.4)
22
22
  domain_name (0.5.20190701)
23
23
  unf (>= 0.0.5, < 1.0.0)
24
+ ffi (1.13.1)
25
+ ffi-compiler (1.0.1)
26
+ ffi (>= 1.0.0)
27
+ rake
24
28
  finitio (0.8.0)
25
29
  citrus (>= 2.4, < 4.0)
26
30
  hansi (0.2.0)
27
- http (2.2.2)
31
+ http (4.4.1)
28
32
  addressable (~> 2.3)
29
33
  http-cookie (~> 1.0)
30
- http-form_data (~> 1.0.1)
31
- http_parser.rb (~> 0.6.0)
34
+ http-form_data (~> 2.2)
35
+ http-parser (~> 1.2.0)
32
36
  http-cookie (1.0.3)
33
37
  domain_name (~> 0.5)
34
- http-form_data (1.0.3)
35
- http_parser.rb (0.6.0)
38
+ http-form_data (2.3.0)
39
+ http-parser (1.2.1)
40
+ ffi-compiler (>= 1.0, < 2.0)
36
41
  mustermann (1.1.1)
37
42
  ruby2_keywords (~> 0.0.1)
38
43
  mustermann-contrib (1.1.1)
39
44
  hansi (~> 0.2.0)
40
45
  mustermann (= 1.1.1)
41
- path (1.3.3)
42
- public_suffix (4.0.3)
43
- rack (2.2.2)
46
+ path (2.0.1)
47
+ public_suffix (4.0.5)
48
+ rack (2.2.3)
44
49
  rack-protection (2.0.8.1)
45
50
  rack
46
51
  rack-robustness (1.1.0)
47
52
  rack-test (0.6.3)
48
53
  rack (>= 1.0)
49
- rake (10.5.0)
54
+ rake (12.3.3)
50
55
  rspec (3.9.0)
51
56
  rspec-core (~> 3.9.0)
52
57
  rspec-expectations (~> 3.9.0)
53
58
  rspec-mocks (~> 3.9.0)
54
- rspec-core (3.9.1)
55
- rspec-support (~> 3.9.1)
56
- rspec-expectations (3.9.1)
59
+ rspec-core (3.9.2)
60
+ rspec-support (~> 3.9.3)
61
+ rspec-expectations (3.9.2)
57
62
  diff-lcs (>= 1.2.0, < 2.0)
58
63
  rspec-support (~> 3.9.0)
59
64
  rspec-mocks (3.9.1)
60
65
  diff-lcs (>= 1.2.0, < 2.0)
61
66
  rspec-support (~> 3.9.0)
62
- rspec-support (3.9.2)
67
+ rspec-support (3.9.3)
63
68
  rspec_junit_formatter (0.4.1)
64
69
  rspec-core (>= 2, < 4, != 2.12.0)
65
70
  ruby2_keywords (0.0.2)
@@ -71,14 +76,14 @@ GEM
71
76
  tilt (2.0.10)
72
77
  unf (0.1.4)
73
78
  unf_ext
74
- unf_ext (0.0.7.6)
79
+ unf_ext (0.0.7.7)
75
80
 
76
81
  PLATFORMS
77
82
  ruby
78
83
 
79
84
  DEPENDENCIES
80
- rake (~> 10)
81
- sinatra (~> 2.0, >= 2.0.2)
85
+ rake (~> 12)
86
+ sinatra (~> 2)
82
87
  webspicy!
83
88
 
84
89
  BUNDLED WITH
@@ -119,6 +119,21 @@ patch '/todo/:id', :auth => :user do |id|
119
119
  end
120
120
  end
121
121
 
122
+ put '/todo/:id', :auth => :user do |id|
123
+ content_type :json
124
+ todo = settings.todolist.find{|todo| todo[:id] == Integer(id) }
125
+ if todo.nil?
126
+ status 404
127
+ {error: "No such todo"}.to_json
128
+ else
129
+ put = SCHEMA["TodoPut"].dress(loaded_body.merge(id: Integer(id)))
130
+ updated = todo.merge(put)
131
+ settings.todolist = settings.todolist.reject{|todo| todo[:id] == Integer(id) }
132
+ settings.todolist << updated
133
+ updated.to_json
134
+ end
135
+ end
136
+
122
137
  delete '/todo/:id', :auth => :admin do |id|
123
138
  content_type :json
124
139
  todo = settings.todolist.find{|todo| todo[:id] == Integer(id) }
@@ -10,6 +10,11 @@ TodoPatch = {
10
10
  description :? String
11
11
  }
12
12
 
13
+ TodoPut = {
14
+ id : Integer
15
+ description : String
16
+ }
17
+
13
18
  ErrorSchema = {
14
19
  error: String
15
20
  }
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: |-
3
+ Todo
4
+
5
+ url: |-
6
+ /todo/{id}
7
+
8
+ services:
9
+ - method: |-
10
+ PUT
11
+
12
+ description: |-
13
+ Update a single Todo item
14
+
15
+ preconditions:
16
+ - Must be authenticated
17
+
18
+ input_schema: |-
19
+ TodoPut
20
+
21
+ output_schema: |-
22
+ Todo
23
+
24
+ error_schema: |-
25
+ ErrorSchema
26
+
27
+ default_example:
28
+ expected:
29
+ content_type: application/json
30
+ status: 200
31
+
32
+ examples:
33
+
34
+ - description: |-
35
+ when requested on an existing TODO
36
+ params:
37
+ id: 1
38
+ description: 'hello world'
39
+ assert:
40
+ - "pathFD('', description: 'hello world')"
41
+
42
+ counterexamples:
43
+
44
+ - description: |-
45
+ when requested on an unexisting TODO
46
+ params:
47
+ id: 999254654
48
+ description: 'hello world'
49
+ expected:
50
+ content_type: application/json
51
+ status: 404
52
+ assert:
53
+ - "pathFD('', error: 'No such todo')"
54
+
55
+ - description: |-
56
+ when violating the Put data type
57
+ params:
58
+ id: 1
59
+ description: 'hello world'
60
+ nosuchone: 'foobar'
61
+ dress_params:
62
+ false
63
+ expected:
64
+ content_type: application/json
65
+ status: 400
@@ -14,6 +14,7 @@ module Webspicy
14
14
  ### Load library
15
15
  ###
16
16
 
17
+ require 'webspicy/support'
17
18
  require 'webspicy/configuration'
18
19
  require 'webspicy/file_upload'
19
20
  require 'webspicy/scope'
@@ -107,6 +107,18 @@ module Webspicy
107
107
  @last_response
108
108
  end
109
109
 
110
+ def put(url, params = {}, headers = nil, body = nil)
111
+ info_request("PUT", url, params, headers, body)
112
+
113
+ headers ||= {}
114
+ headers['Content-Type'] ||= 'application/json'
115
+ @last_response = HTTP[headers].put(url, body: params.to_json)
116
+
117
+ debug_response(@last_response)
118
+
119
+ @last_response
120
+ end
121
+
110
122
  def post_form(url, params = {}, headers = nil, body = nil)
111
123
  info_request("POST", url, params, headers, body)
112
124
 
@@ -126,6 +126,19 @@ module Webspicy
126
126
  @last_response
127
127
  end
128
128
 
129
+ def put(url, params = {}, headers = nil, body = nil)
130
+ handler = get_handler(headers)
131
+
132
+ info_request("PUT", url, params, headers, body)
133
+
134
+ handler.put(url, params.to_json, {"CONTENT_TYPE" => "application/json"})
135
+ @last_response = handler.last_response
136
+
137
+ debug_response(@last_response)
138
+
139
+ @last_response
140
+ end
141
+
129
142
  def post_form(url, params = {}, headers = nil, body = nil)
130
143
  handler = get_handler(headers)
131
144
 
@@ -11,6 +11,7 @@ module Webspicy
11
11
  @postconditions = []
12
12
  @listeners = Hash.new{|h,k| h[k] = [] }
13
13
  @rspec_options = default_rspec_options
14
+ @run_examples = default_run_examples
14
15
  @run_counterexamples = default_run_counterexamples
15
16
  @file_filter = default_file_filter
16
17
  @service_filter = default_service_filter
@@ -94,6 +95,23 @@ module Webspicy
94
95
  !children.empty?
95
96
  end
96
97
 
98
+ # Sets whether examples have to be ran or not.
99
+ def run_examples=(run_examples)
100
+ @run_examples = run_examples
101
+ end
102
+ attr_reader :run_examples
103
+
104
+ # Whether counter examples must be ran or not.
105
+ def run_examples?
106
+ @run_examples
107
+ end
108
+
109
+ # Returns the defaut value for run_examples
110
+ def default_run_examples
111
+ ENV['ROBUST'].nil? || (ENV['ROBUST'] != 'only')
112
+ end
113
+ private :default_run_examples
114
+
97
115
  # Sets whether counter examples have to be ran or not.
98
116
  def run_counterexamples=(run_counterexamples)
99
117
  @run_counterexamples = run_counterexamples
@@ -1,7 +1,7 @@
1
1
  @import finitio/data
2
2
 
3
3
  Method =
4
- String( s | s =~ /^(GET|POST|POST_FORM|PUT|DELETE|PATCH|OPTIONS)$/ )
4
+ String( s | s =~ /^(GET|POST|POST_FORM|PUT|DELETE|PATCH|PUT|OPTIONS)$/ )
5
5
 
6
6
  Tag = String( s | s.length > 0 )
7
7
 
@@ -51,7 +51,7 @@ TestCase =
51
51
  requester :? String
52
52
  metadata :? { ...: .Object }
53
53
  expected :? {
54
- status :? Integer
54
+ status :? StatusRange
55
55
  content_type :? String|Nil
56
56
  error :? String
57
57
  headers :? .Hash
@@ -61,3 +61,7 @@ TestCase =
61
61
  }
62
62
 
63
63
  Params = .Array|.Hash
64
+
65
+ StatusRange = .Webspicy::Support::StatusRange
66
+ <int> Integer
67
+ <str> String(s | s =~ /^\dxx$/ )
@@ -57,7 +57,7 @@ module Webspicy
57
57
 
58
58
  def best_status_code(service)
59
59
  if ex = service.examples.first
60
- ex.expected_status || 200
60
+ (ex.expected_status && ex.expected_status.to_i) || 200
61
61
  else
62
62
  200
63
63
  end
@@ -53,7 +53,7 @@ module Webspicy
53
53
  end
54
54
 
55
55
  def is_expected_success?
56
- test_case.expected_status >= 200 && test_case.expected_status < 300
56
+ test_case.expected_status.to_i >= 200 && test_case.expected_status.to_i < 300
57
57
  end
58
58
 
59
59
  def is_success?
@@ -73,7 +73,7 @@ module Webspicy
73
73
  def expected_status_unmet
74
74
  expected = test_case.expected_status
75
75
  got = response.status
76
- expected == got ? nil : "#{expected} != #{got}"
76
+ expected === got ? nil : "#{expected} !== #{got}"
77
77
  end
78
78
 
79
79
  def meets_expected_status?
@@ -89,7 +89,7 @@ module Webspicy
89
89
  if ect.nil?
90
90
  got.nil? ? nil : "#{ect} != #{got}"
91
91
  else
92
- ect.to_s == got.to_s ? nil : "#{ect} != #{got}"
92
+ got.to_s.start_with?(ect.to_s) ? nil : "#{ect} != #{got}"
93
93
  end
94
94
  end
95
95
 
@@ -82,7 +82,7 @@ module Webspicy
82
82
  end
83
83
 
84
84
  def is_expected_status?(status)
85
- expected_status == status
85
+ expected_status === status
86
86
  end
87
87
 
88
88
  def expected_error
@@ -46,23 +46,26 @@ module Webspicy
46
46
  resource.services.select(&to_filter_proc(config.service_filter)).each(&bl)
47
47
  end
48
48
 
49
- def each_example(service)
50
- service.examples.select(&to_filter_proc(config.test_case_filter)).each{|e|
51
- yield(expand_example(service, e))
52
- }
49
+ def each_example(service, &bl)
50
+ service.examples
51
+ .map{|e| expand_example(service, e) }
52
+ .select(&to_filter_proc(config.test_case_filter))
53
+ .each(&bl) if config.run_examples?
53
54
  end
54
55
 
55
56
  def each_counterexamples(service, &bl)
56
- service.counterexamples.select(&to_filter_proc(config.test_case_filter)).each{|e|
57
- yield(expand_example(service, e))
58
- } if config.run_counterexamples?
57
+ service.counterexamples
58
+ .map{|e| expand_example(service, e) }
59
+ .select(&to_filter_proc(config.test_case_filter))
60
+ .each(&bl) if config.run_counterexamples?
59
61
  end
60
62
 
61
63
  def each_generated_counterexamples(service, &bl)
62
64
  Webspicy.with_scope(self) do
63
- service.generated_counterexamples.select(&to_filter_proc(config.test_case_filter)).each{|e|
64
- yield(expand_example(service, e))
65
- }
65
+ service.generated_counterexamples
66
+ .map{|e| expand_example(service, e) }
67
+ .select(&to_filter_proc(config.test_case_filter))
68
+ .each(&bl) if config.run_counterexamples?
66
69
  end if config.run_counterexamples?
67
70
  end
68
71
 
@@ -0,0 +1 @@
1
+ require_relative 'support/status_range'
@@ -0,0 +1,50 @@
1
+ module Webspicy
2
+ module Support
3
+ class StatusRange
4
+
5
+ def initialize(range)
6
+ @range = range
7
+ end
8
+ attr_reader :range
9
+
10
+ def self.int(i)
11
+ new(i..i)
12
+ end
13
+
14
+ def to_int
15
+ @range.first
16
+ end
17
+
18
+ def self.str(s)
19
+ from = s[/^(\d)/,1].to_i * 100
20
+ new(from...from+100)
21
+ end
22
+
23
+ def to_str
24
+ "#{@range.first/100}xx"
25
+ end
26
+
27
+ def to_i
28
+ @range.first
29
+ end
30
+
31
+ def ===(status)
32
+ range === status
33
+ end
34
+
35
+ def ==(other)
36
+ other.is_a?(StatusRange) && self.range == other.range
37
+ end
38
+ alias :eql? :==
39
+
40
+ def hash
41
+ @range.hash
42
+ end
43
+
44
+ def to_s
45
+ @range.to_s
46
+ end
47
+
48
+ end # class StatusRange
49
+ end # module Support
50
+ end # module Webspicy
@@ -2,7 +2,7 @@ module Webspicy
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 15
5
- TINY = 3
5
+ TINY = 8
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
@@ -53,7 +53,7 @@ module Webspicy
53
53
  expect(subject).to be_a(Resource::Service::TestCase)
54
54
  expect(subject.description).to eql("Hello world")
55
55
  expect(subject.expected).to eql({
56
- status: 200,
56
+ status: Support::StatusRange.int(200),
57
57
  content_type: "application/json"
58
58
  })
59
59
  end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+ module Webspicy
3
+ module Support
4
+ describe StatusRange do
5
+
6
+ it 'has a int information contract' do
7
+ expect(StatusRange.int(100).range).to eql(100..100)
8
+ expect(StatusRange.int(100).to_int).to eql(100)
9
+ end
10
+
11
+ it 'has a str information contract' do
12
+ expect(StatusRange.str("3xx").range).to eql(300...400)
13
+ expect(StatusRange.str("3xx").to_str).to eql("3xx")
14
+ end
15
+
16
+ it 'has a to_i that returns the first status of the range' do
17
+ expect(StatusRange.int(300).to_i).to eql(300)
18
+ expect(StatusRange.str("3xx").to_i).to eql(300)
19
+ end
20
+
21
+ it 'has a matching method' do
22
+ expect(StatusRange.str("3xx") === 300).to eql(true)
23
+ expect(StatusRange.str("3xx") === 302).to eql(true)
24
+ expect(StatusRange.str("3xx") === 400).to eql(false)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webspicy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.3
4
+ version: 0.15.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-05 00:00:00.000000000 Z
11
+ date: 2020-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -16,34 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '10'
19
+ version: '12'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '10'
26
+ version: '12'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sinatra
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.0'
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 2.0.2
33
+ version: '2'
37
34
  type: :development
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
38
  - - "~>"
42
39
  - !ruby/object:Gem::Version
43
- version: '2.0'
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 2.0.2
40
+ version: '2'
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: rspec
49
43
  requirement: !ruby/object:Gem::Requirement
@@ -206,6 +200,7 @@ files:
206
200
  - examples/restful/webspicy/todo/postCsv.yml
207
201
  - examples/restful/webspicy/todo/postFile.yml
208
202
  - examples/restful/webspicy/todo/postTodos.yml
203
+ - examples/restful/webspicy/todo/putTodo.yml
209
204
  - examples/restful/webspicy/todo/todos.csv
210
205
  - lib/webspicy.rb
211
206
  - lib/webspicy/checker.rb
@@ -224,6 +219,8 @@ files:
224
219
  - lib/webspicy/resource/service/invocation.rb
225
220
  - lib/webspicy/resource/service/test_case.rb
226
221
  - lib/webspicy/scope.rb
222
+ - lib/webspicy/support.rb
223
+ - lib/webspicy/support/status_range.rb
227
224
  - lib/webspicy/tester.rb
228
225
  - lib/webspicy/tester/asserter.rb
229
226
  - lib/webspicy/tester/assertions.rb
@@ -239,6 +236,7 @@ files:
239
236
  - spec/unit/scope/test_expand_example.rb
240
237
  - spec/unit/scope/test_to_real_url.rb
241
238
  - spec/unit/spec_helper.rb
239
+ - spec/unit/support/test_status_range.rb
242
240
  - spec/unit/test_configuration.rb
243
241
  - spec/unit/tester/test_assertions.rb
244
242
  - tasks/gem.rake