webspicy 0.19.0 → 0.20.4
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 +4 -4
- data/bin/webspicy +1 -2
- data/lib/webspicy.rb +0 -2
- data/lib/webspicy/configuration.rb +15 -0
- data/lib/webspicy/configuration/scope.rb +1 -0
- data/lib/webspicy/specification.rb +4 -3
- data/lib/webspicy/specification/condition.rb +29 -4
- data/lib/webspicy/specification/err.rb +18 -0
- data/lib/webspicy/specification/oldies.rb +4 -0
- data/lib/webspicy/specification/oldies/bridge.rb +32 -0
- data/lib/webspicy/specification/{errcondition.rb → oldies/errcondition.rb} +5 -0
- data/lib/webspicy/specification/{postcondition.rb → oldies/postcondition.rb} +5 -0
- data/lib/webspicy/specification/{precondition.rb → oldies/precondition.rb} +5 -2
- data/lib/webspicy/specification/post.rb +20 -0
- data/lib/webspicy/specification/post/missing_condition_impl.rb +15 -0
- data/lib/webspicy/specification/post/unexpected_condition_impl.rb +15 -0
- data/lib/webspicy/specification/pre.rb +19 -0
- data/lib/webspicy/specification/{precondition → pre}/global_request_headers.rb +4 -4
- data/lib/webspicy/specification/{precondition → pre}/robust_to_invalid_input.rb +4 -4
- data/lib/webspicy/specification/service.rb +29 -5
- data/lib/webspicy/specification/test_case.rb +3 -0
- data/lib/webspicy/support.rb +12 -2
- data/lib/webspicy/support/colorize.rb +6 -0
- data/lib/webspicy/tester.rb +89 -27
- data/lib/webspicy/tester/assertions.rb +2 -2
- data/lib/webspicy/tester/client.rb +0 -26
- data/lib/webspicy/tester/fakeses.rb +41 -0
- data/lib/webspicy/tester/fakeses/email.rb +38 -0
- data/lib/webspicy/tester/fakesmtp.rb +39 -0
- data/lib/webspicy/tester/fakesmtp/email.rb +27 -0
- data/lib/webspicy/tester/reporter.rb +5 -0
- data/lib/webspicy/tester/reporter/documentation.rb +31 -8
- data/lib/webspicy/tester/reporter/error_count.rb +11 -7
- data/lib/webspicy/tester/reporter/exceptions.rb +2 -0
- data/lib/webspicy/tester/reporter/file_progress.rb +5 -2
- data/lib/webspicy/tester/reporter/file_summary.rb +3 -2
- data/lib/webspicy/tester/reporter/progress.rb +6 -4
- data/lib/webspicy/tester/reporter/summary.rb +9 -7
- data/lib/webspicy/tester/result.rb +16 -13
- data/lib/webspicy/tester/result/errcondition_met.rb +1 -3
- data/lib/webspicy/tester/result/error_schema_met.rb +1 -0
- data/lib/webspicy/tester/result/invocation_succeeded.rb +13 -0
- data/lib/webspicy/tester/result/output_schema_met.rb +1 -0
- data/lib/webspicy/tester/result/postcondition_met.rb +1 -3
- data/lib/webspicy/version.rb +2 -2
- data/lib/webspicy/web/invocation.rb +7 -3
- data/spec/blackbox/commandline.yml +24 -0
- data/spec/blackbox/fixtures/passing/config.rb +9 -0
- data/spec/blackbox/fixtures/passing/formaldef/get.yml +30 -0
- data/spec/unit/specification/{precondition → pre}/test_global_request_headers.rb +9 -4
- data/spec/unit/specification/test_condition.rb +18 -0
- data/spec/unit/tester/fakeses/test_email.rb +40 -0
- data/tasks/test.rake +2 -1
- metadata +34 -18
@@ -4,61 +4,84 @@ module Webspicy
|
|
4
4
|
class Documentation < Reporter
|
5
5
|
|
6
6
|
module Helpers
|
7
|
+
INDENT = " ".freeze
|
8
|
+
|
9
|
+
def spec_file_line(spec_file)
|
10
|
+
relative_path = Path(spec_file).relative_to(config.folder)
|
11
|
+
colorize_section(">> #{relative_path}", config)
|
12
|
+
end
|
13
|
+
|
7
14
|
def spec_file_error_line(spec_file, ex)
|
8
|
-
str =
|
9
|
-
str +=
|
15
|
+
str = ""
|
16
|
+
str += colorize_error(INDENT + "X #{ex.message}", config)
|
10
17
|
if ex.root_cause && ex.root_cause != ex
|
11
|
-
str += "\n
|
18
|
+
str += "\n"
|
19
|
+
str += INDENT + colorize_error("#{ex.root_cause.message}", config)
|
12
20
|
end
|
13
21
|
str
|
14
22
|
end
|
15
23
|
|
16
24
|
def service_line(service, test_case)
|
17
|
-
str = service
|
18
|
-
str = colorize_highlight(str)
|
25
|
+
str = "#{service}, #{test_case}"
|
26
|
+
str = colorize_highlight(str, config)
|
19
27
|
end
|
20
28
|
|
21
29
|
def check_success_line(check)
|
22
|
-
|
30
|
+
INDENT + colorize_success("v " + check.behavior, config)
|
23
31
|
end
|
24
32
|
|
25
33
|
def check_failure_line(check, ex)
|
26
|
-
|
34
|
+
INDENT + colorize_error("F " + ex.message, config)
|
27
35
|
end
|
28
36
|
|
29
37
|
def check_error_line(check, ex)
|
30
|
-
|
38
|
+
INDENT + colorize_error("E " + ex.message, config)
|
31
39
|
end
|
32
40
|
end
|
33
41
|
include Helpers
|
34
42
|
|
35
43
|
def spec_file_error(e)
|
44
|
+
io.puts spec_file_line(spec_file)
|
45
|
+
io.puts
|
36
46
|
io.puts spec_file_error_line(spec_file, e)
|
37
47
|
io.puts
|
48
|
+
io.flush
|
49
|
+
end
|
50
|
+
|
51
|
+
def before_service
|
52
|
+
io.puts spec_file_line(spec_file)
|
53
|
+
io.puts
|
54
|
+
io.flush
|
38
55
|
end
|
39
56
|
|
40
57
|
def before_test_case
|
41
58
|
io.puts service_line(service, test_case)
|
59
|
+
io.flush
|
42
60
|
end
|
43
61
|
|
44
62
|
def check_success(check)
|
45
63
|
io.puts check_success_line(check)
|
64
|
+
io.flush
|
46
65
|
end
|
47
66
|
|
48
67
|
def check_failure(check, ex)
|
49
68
|
io.puts check_failure_line(check, ex)
|
69
|
+
io.flush
|
50
70
|
end
|
51
71
|
|
52
72
|
def check_error(check, ex)
|
53
73
|
io.puts check_error_line(check, ex)
|
74
|
+
io.flush
|
54
75
|
end
|
55
76
|
|
56
77
|
def test_case_done
|
57
78
|
io.puts
|
79
|
+
io.flush
|
58
80
|
end
|
59
81
|
|
60
82
|
def service_done
|
61
83
|
io.puts
|
84
|
+
io.flush
|
62
85
|
end
|
63
86
|
|
64
87
|
end # class Documentation
|
@@ -5,18 +5,22 @@ module Webspicy
|
|
5
5
|
|
6
6
|
def initialize(*args, &bl)
|
7
7
|
super
|
8
|
-
@
|
8
|
+
@errors = Hash.new{|h,k| 0 }
|
9
9
|
end
|
10
|
+
attr_reader :errors
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
[
|
13
|
+
:spec_file_error,
|
14
|
+
:check_error,
|
15
|
+
:check_failure
|
16
|
+
].each do |meth|
|
17
|
+
define_method(meth) do |*args, &bl|
|
18
|
+
@errors[meth] += 1
|
19
|
+
end
|
13
20
|
end
|
14
|
-
alias :spec_file_error :on_error
|
15
|
-
alias :check_failure :on_error
|
16
|
-
alias :check_error :on_error
|
17
21
|
|
18
22
|
def report
|
19
|
-
@
|
23
|
+
@errors.values.inject(0){|memo,x| memo+x }
|
20
24
|
end
|
21
25
|
|
22
26
|
end # class ErrorCount
|
@@ -4,16 +4,19 @@ module Webspicy
|
|
4
4
|
class FileProgress < Reporter
|
5
5
|
|
6
6
|
def spec_file_error(e)
|
7
|
-
io.print colorize_error("X")
|
7
|
+
io.print colorize_error("X", config)
|
8
|
+
io.flush
|
8
9
|
end
|
9
10
|
|
10
11
|
def spec_file_done
|
11
|
-
io.print colorize_success(".")
|
12
|
+
io.print colorize_success(".", config)
|
13
|
+
io.flush
|
12
14
|
end
|
13
15
|
|
14
16
|
def report
|
15
17
|
io.puts
|
16
18
|
io.puts
|
19
|
+
io.flush
|
17
20
|
end
|
18
21
|
|
19
22
|
end # class FileProgress
|
@@ -22,12 +22,13 @@ module Webspicy
|
|
22
22
|
msg = "#{plural('spec file', spec_files_count)}, "\
|
23
23
|
"#{plural('error', errors_count)}"
|
24
24
|
if success?
|
25
|
-
msg = colorize_success(msg)
|
25
|
+
msg = colorize_success(msg, config)
|
26
26
|
else
|
27
|
-
msg = colorize_error(msg)
|
27
|
+
msg = colorize_error(msg, config)
|
28
28
|
end
|
29
29
|
io.puts(msg)
|
30
30
|
io.puts
|
31
|
+
io.flush
|
31
32
|
end
|
32
33
|
|
33
34
|
private
|
@@ -4,22 +4,24 @@ module Webspicy
|
|
4
4
|
class Progress < Reporter
|
5
5
|
|
6
6
|
def spec_file_error(e)
|
7
|
-
io.print colorize_error("X")
|
7
|
+
io.print colorize_error("X", config)
|
8
8
|
end
|
9
9
|
|
10
10
|
def after_each_done
|
11
11
|
if result.success?
|
12
|
-
io.print colorize_success(".")
|
12
|
+
io.print colorize_success(".", config)
|
13
13
|
elsif result.failure?
|
14
|
-
io.print colorize_error("F")
|
14
|
+
io.print colorize_error("F", config)
|
15
15
|
elsif result.error?
|
16
|
-
io.print colorize_error("E")
|
16
|
+
io.print colorize_error("E", config)
|
17
17
|
end
|
18
|
+
io.flush
|
18
19
|
end
|
19
20
|
|
20
21
|
def report
|
21
22
|
io.puts
|
22
23
|
io.puts
|
24
|
+
io.flush
|
23
25
|
end
|
24
26
|
|
25
27
|
end # class Progress
|
@@ -9,18 +9,21 @@ module Webspicy
|
|
9
9
|
@examples_count = 0
|
10
10
|
@counterexamples_count = 0
|
11
11
|
@assertions_count = 0
|
12
|
+
#
|
13
|
+
@spec_file_errors_count = 0
|
12
14
|
@errors_count = 0
|
13
15
|
@failures_count = 0
|
14
16
|
end
|
15
17
|
attr_reader :spec_files_count, :examples_count, :counterexamples_count
|
16
|
-
attr_reader :assertions_count
|
18
|
+
attr_reader :assertions_count
|
19
|
+
attr_reader :spec_file_errors_count, :errors_count, :failures_count
|
17
20
|
|
18
21
|
def before_spec_file
|
19
22
|
@spec_files_count += 1
|
20
23
|
end
|
21
24
|
|
22
25
|
def spec_file_error(e)
|
23
|
-
@
|
26
|
+
@spec_file_errors_count += 1
|
24
27
|
end
|
25
28
|
|
26
29
|
def after_each_done
|
@@ -42,18 +45,17 @@ module Webspicy
|
|
42
45
|
"#{plural('error', errors_count)}, "\
|
43
46
|
"#{plural('failure', failures_count)}"
|
44
47
|
if success?
|
45
|
-
msg = colorize_success(msg)
|
48
|
+
msg = colorize_success(msg, config)
|
46
49
|
else
|
47
|
-
msg = colorize_error(msg)
|
50
|
+
msg = colorize_error(msg, config)
|
48
51
|
end
|
49
52
|
io.puts(msg)
|
50
53
|
io.puts
|
54
|
+
io.flush
|
51
55
|
end
|
52
56
|
|
53
|
-
private
|
54
|
-
|
55
57
|
def success?
|
56
|
-
@errors_count == 0 && @failures_count == 0
|
58
|
+
@spec_file_errors_count == 0 && @errors_count == 0 && @failures_count == 0
|
57
59
|
end
|
58
60
|
|
59
61
|
end # class Summary
|
@@ -5,26 +5,28 @@ module Webspicy
|
|
5
5
|
|
6
6
|
def initialize(tester)
|
7
7
|
@tester = tester
|
8
|
+
@scope = tester.scope
|
9
|
+
@client = tester.client
|
10
|
+
@specification = tester.specification
|
11
|
+
@service = tester.service
|
12
|
+
@test_case = tester.test_case
|
8
13
|
@invocation = tester.invocation
|
9
14
|
@assertions = []
|
10
15
|
@failures = []
|
11
16
|
@errors = []
|
12
|
-
|
17
|
+
if @invocation
|
18
|
+
check!
|
19
|
+
else
|
20
|
+
@errors << [InvocationSuceeded.new(self), tester.invocation_error]
|
21
|
+
end
|
13
22
|
end
|
14
|
-
attr_reader :tester, :
|
23
|
+
attr_reader :tester, :scope, :client
|
24
|
+
attr_reader :specification, :service, :test_case, :invocation
|
15
25
|
attr_reader :assertions, :failures, :errors
|
16
26
|
|
17
27
|
def_delegators :@tester, *[
|
18
|
-
:reporter
|
19
|
-
]
|
20
|
-
|
21
|
-
def_delegators :@invocation, *[
|
22
28
|
:config,
|
23
|
-
:
|
24
|
-
:client,
|
25
|
-
:specification,
|
26
|
-
:service,
|
27
|
-
:test_case
|
29
|
+
:reporter
|
28
30
|
]
|
29
31
|
|
30
32
|
def self.from(tester)
|
@@ -94,13 +96,13 @@ module Webspicy
|
|
94
96
|
|
95
97
|
def check_postconditions!
|
96
98
|
service.postconditions.each do |c|
|
97
|
-
check_one! Result::PostconditionMet.new(self, c)
|
99
|
+
check_one! Result::PostconditionMet.new(self, tester.bind_condition(c))
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
101
103
|
def check_errconditions!
|
102
104
|
service.errconditions.each do |c|
|
103
|
-
check_one! Result::ErrconditionMet.new(self, c)
|
105
|
+
check_one! Result::ErrconditionMet.new(self, tester.bind_condition(c))
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
@@ -130,6 +132,7 @@ module Webspicy
|
|
130
132
|
end # class Tester
|
131
133
|
end # module Webspicy
|
132
134
|
require_relative "result/check"
|
135
|
+
require_relative "result/invocation_succeeded"
|
133
136
|
require_relative "result/response_status_met"
|
134
137
|
require_relative "result/response_header_met"
|
135
138
|
require_relative "result/output_schema_met"
|
data/lib/webspicy/version.rb
CHANGED
@@ -36,11 +36,14 @@ module Webspicy
|
|
36
36
|
response.body.to_s
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
39
|
+
def is_structured_output?
|
40
40
|
ct = response.content_type || test_case.expected_content_type
|
41
41
|
ct = ct.mime_type if ct.respond_to?(:mime_type)
|
42
|
-
|
43
|
-
|
42
|
+
ct =~ /json/
|
43
|
+
end
|
44
|
+
|
45
|
+
def loaded_output
|
46
|
+
if is_structured_output?
|
44
47
|
raise "Body empty while expected" if raw_output.empty?
|
45
48
|
@loaded_output ||= ::JSON.parse(response.body)
|
46
49
|
else
|
@@ -50,6 +53,7 @@ module Webspicy
|
|
50
53
|
alias :loaded_body :loaded_output
|
51
54
|
|
52
55
|
def output
|
56
|
+
return loaded_output unless is_structured_output?
|
53
57
|
schema = is_expected_success? ? service.output_schema : service.error_schema
|
54
58
|
begin
|
55
59
|
schema.dress(loaded_output)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
command:
|
3
|
+
webspicy {options} {args}
|
4
|
+
|
5
|
+
examples:
|
6
|
+
|
7
|
+
- description: |-
|
8
|
+
when called on a passing path
|
9
|
+
args:
|
10
|
+
- ./fixtures/passing/config.rb
|
11
|
+
assert:
|
12
|
+
exit_code:
|
13
|
+
0
|
14
|
+
stdout: |-
|
15
|
+
GET /, when requested
|
16
|
+
v It has a 200 response status
|
17
|
+
v It has a `Content-Type: application/json` response header
|
18
|
+
v Its output meets the expected data schema
|
19
|
+
v Assert notEmpty
|
20
|
+
v Assert pathFD('', :hello => "World" )
|
21
|
+
|
22
|
+
|
23
|
+
1 spec file, 1 example, 0 counterexample
|
24
|
+
5 assertions, 0 error, 0 failure
|