webspicy 0.19.0 → 0.20.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|