webspicy 0.20.4 → 0.20.9
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 +2 -2
- data/lib/finitio/webspicy/shared.fio +10 -0
- data/lib/webspicy.rb +22 -53
- data/lib/webspicy/configuration.rb +3 -1
- data/lib/webspicy/configuration/scope.rb +2 -2
- data/lib/webspicy/configuration/single_url.rb +35 -25
- data/lib/webspicy/configuration/single_yml_file.rb +7 -2
- data/lib/webspicy/specification.rb +5 -56
- data/lib/webspicy/specification/service.rb +1 -5
- data/lib/webspicy/specification/test_case.rb +0 -49
- data/lib/webspicy/support/colorize.rb +1 -1
- data/lib/webspicy/tester.rb +5 -3
- data/lib/webspicy/tester/fakesmtp.rb +1 -1
- data/lib/webspicy/tester/fakesmtp/email.rb +13 -0
- data/lib/webspicy/tester/file_checker.rb +1 -1
- data/lib/webspicy/tester/reporter.rb +2 -1
- data/lib/webspicy/tester/reporter/documentation.rb +11 -5
- data/lib/webspicy/tester/reporter/exceptions.rb +3 -1
- data/lib/webspicy/tester/reporter/junit_xml_file.rb +151 -0
- data/lib/webspicy/tester/reporter/progress.rb +1 -1
- data/lib/webspicy/tester/reporter/success_or_not.rb +14 -0
- data/lib/webspicy/tester/reporter/summary.rb +6 -2
- data/lib/webspicy/tester/result.rb +1 -0
- data/lib/webspicy/version.rb +1 -1
- data/lib/webspicy/web.rb +46 -0
- data/lib/webspicy/{formaldoc.fio → web/formaldoc.fio} +5 -13
- data/lib/webspicy/web/specification.rb +68 -0
- data/lib/webspicy/web/specification/file_upload.rb +39 -0
- data/lib/webspicy/web/specification/service.rb +13 -0
- data/lib/webspicy/web/specification/test_case.rb +58 -0
- data/spec/unit/configuration/scope/test_expand_example.rb +11 -5
- data/spec/unit/specification/pre/test_global_request_headers.rb +3 -3
- data/spec/unit/specification/service/test_dress_params.rb +2 -2
- data/spec/unit/test_configuration.rb +1 -0
- data/spec/unit/tester/fakesmtp/test_email.rb +93 -0
- data/spec/unit/web/specification/test_instantiate_url.rb +36 -0
- data/spec/unit/web/specification/test_url_placeholders.rb +23 -0
- data/tasks/test.rake +5 -1
- metadata +40 -23
- data/lib/webspicy/specification/file_upload.rb +0 -37
- data/lib/webspicy/tester/reporter/error_count.rb +0 -29
- data/spec/blackbox/commandline.yml +0 -24
- data/spec/blackbox/fixtures/passing/config.rb +0 -9
- data/spec/blackbox/fixtures/passing/formaldef/get.yml +0 -30
- data/spec/unit/specification/test_instantiate_url.rb +0 -34
- data/spec/unit/specification/test_url_placeholders.rb +0 -21
data/lib/webspicy/tester.rb
CHANGED
@@ -38,12 +38,12 @@ module Webspicy
|
|
38
38
|
rescue FailFast
|
39
39
|
end
|
40
40
|
reporter.report
|
41
|
-
reporter.find(Reporter::
|
41
|
+
reporter.find(Reporter::SuccessOrNot).report
|
42
42
|
end
|
43
43
|
|
44
44
|
def call!
|
45
45
|
res = call
|
46
|
-
abort("KO") unless
|
46
|
+
abort("KO") unless reporter.find(Reporter::SuccessOrNot).success?
|
47
47
|
end
|
48
48
|
|
49
49
|
def find_and_call(method, url, mutation)
|
@@ -98,7 +98,7 @@ module Webspicy
|
|
98
98
|
def load_specification(spec_file)
|
99
99
|
@spec_file = spec_file
|
100
100
|
reporter.before_spec_file
|
101
|
-
|
101
|
+
config.factory.specification(spec_file.load, spec_file, scope)
|
102
102
|
rescue *PASSTHROUGH_EXCEPTIONS
|
103
103
|
raise
|
104
104
|
rescue Exception => e
|
@@ -149,6 +149,8 @@ module Webspicy
|
|
149
149
|
end
|
150
150
|
|
151
151
|
def call_test_case_target
|
152
|
+
@invocation = nil
|
153
|
+
@invocation_error = nil
|
152
154
|
reporter.before_invocation
|
153
155
|
@invocation = client.call(test_case)
|
154
156
|
reporter.invocation_done
|
@@ -21,6 +21,19 @@ module Webspicy
|
|
21
21
|
.map{|h| h["line"][/To:\s*(.*)$/, 1] }
|
22
22
|
end
|
23
23
|
|
24
|
+
def reply_to
|
25
|
+
@reply_to ||= data["headerLines"]
|
26
|
+
.select{|h| h["key"] == "reply-to" }
|
27
|
+
.map{|h| h["line"][/Reply-To:\s*(.*)$/, 1] }
|
28
|
+
end
|
29
|
+
|
30
|
+
def subject
|
31
|
+
@subject ||= data["headerLines"]
|
32
|
+
.select{|h| h["key"] == "subject" }
|
33
|
+
.map{|h| h["line"][/Subject:\s*(.*)$/, 1] }
|
34
|
+
.first
|
35
|
+
end
|
36
|
+
|
24
37
|
end # class Email
|
25
38
|
end # class Fakesmtp
|
26
39
|
end # class Tester
|
@@ -80,7 +80,6 @@ module Webspicy
|
|
80
80
|
end # class Reporter
|
81
81
|
end # class Tester
|
82
82
|
end # module Webspicy
|
83
|
-
require_relative 'reporter/error_count'
|
84
83
|
require_relative 'reporter/progress'
|
85
84
|
require_relative 'reporter/summary'
|
86
85
|
require_relative 'reporter/documentation'
|
@@ -88,3 +87,5 @@ require_relative 'reporter/exceptions'
|
|
88
87
|
require_relative 'reporter/composite'
|
89
88
|
require_relative 'reporter/file_progress'
|
90
89
|
require_relative 'reporter/file_summary'
|
90
|
+
require_relative 'reporter/success_or_not'
|
91
|
+
require_relative 'reporter/junit_xml_file'
|
@@ -7,8 +7,10 @@ module Webspicy
|
|
7
7
|
INDENT = " ".freeze
|
8
8
|
|
9
9
|
def spec_file_line(spec_file)
|
10
|
-
|
11
|
-
|
10
|
+
path = Path(spec_file).expand_path
|
11
|
+
path = path.relative_to(config.folder)
|
12
|
+
path = spec_file if path.to_s.start_with?(".")
|
13
|
+
colorize_section(">> #{path}", config)
|
12
14
|
end
|
13
15
|
|
14
16
|
def spec_file_error_line(spec_file, ex)
|
@@ -49,12 +51,16 @@ module Webspicy
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def before_service
|
52
|
-
|
53
|
-
io.puts
|
54
|
-
io.flush
|
54
|
+
@spec_file_line_printed = false
|
55
55
|
end
|
56
56
|
|
57
57
|
def before_test_case
|
58
|
+
unless @spec_file_line_printed
|
59
|
+
io.puts spec_file_line(spec_file)
|
60
|
+
io.puts
|
61
|
+
io.flush
|
62
|
+
@spec_file_line_printed = true
|
63
|
+
end
|
58
64
|
io.puts service_line(service, test_case)
|
59
65
|
io.flush
|
60
66
|
end
|
@@ -15,7 +15,7 @@ module Webspicy
|
|
15
15
|
@spec_file_errors << spec_file_error_line(spec_file, e)
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def test_case_done
|
19
19
|
@failed_results << result unless result.success?
|
20
20
|
end
|
21
21
|
|
@@ -24,6 +24,8 @@ module Webspicy
|
|
24
24
|
report_failed_results
|
25
25
|
end
|
26
26
|
|
27
|
+
private
|
28
|
+
|
27
29
|
def report_spec_file_errors
|
28
30
|
return if spec_file_errors.empty?
|
29
31
|
io.puts
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module Webspicy
|
2
|
+
class Tester
|
3
|
+
class Reporter
|
4
|
+
class JunitXmlFile < Reporter
|
5
|
+
|
6
|
+
TPL = <<~XML
|
7
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
8
|
+
<testsuites
|
9
|
+
disabled="{{counts.disabled}}"
|
10
|
+
errors="{{counts.errors}}"
|
11
|
+
failures="{{counts.failures}}"
|
12
|
+
tests="{{counts.total}}"
|
13
|
+
time="{{time}}s"
|
14
|
+
>
|
15
|
+
{{#testsuites}}
|
16
|
+
<testsuite
|
17
|
+
name="{{name}}"
|
18
|
+
tests="{{counts.total}}"
|
19
|
+
errors="{{counts.errors}}"
|
20
|
+
failures="{{counts.failures}}"
|
21
|
+
time="{{time}}s"
|
22
|
+
>
|
23
|
+
{{#testcases}}
|
24
|
+
<testcase
|
25
|
+
name="{{name}}"
|
26
|
+
assertions="{{assert}}"
|
27
|
+
classname="{{classname}}"
|
28
|
+
status=""
|
29
|
+
time="{{time}}s"
|
30
|
+
>
|
31
|
+
{{#errors}}
|
32
|
+
<error
|
33
|
+
message="{{message}}"
|
34
|
+
type="{{type}}"
|
35
|
+
></error>
|
36
|
+
{{/errors}}
|
37
|
+
{{#failures}}
|
38
|
+
<failure
|
39
|
+
message="{{message}}"
|
40
|
+
type="{{type}}"
|
41
|
+
></failure>
|
42
|
+
{{/failures}}
|
43
|
+
</testcase>
|
44
|
+
{{/testcases}}
|
45
|
+
</testsuite>
|
46
|
+
{{/testsuites}}
|
47
|
+
</testsuites>
|
48
|
+
XML
|
49
|
+
|
50
|
+
def initialize(path_or_io = STDOUT)
|
51
|
+
@path_or_io = path_or_io
|
52
|
+
path_or_io.parent.mkdir_p if path_or_io.is_a?(Path)
|
53
|
+
end
|
54
|
+
|
55
|
+
attr_reader :template_data, :timer_all, :timer_specification, :timer_testcase
|
56
|
+
|
57
|
+
def before_all
|
58
|
+
@timer_all = Time.now
|
59
|
+
@template_data = OpenStruct.new({
|
60
|
+
counts: Hash.new{|h,k| h[k] = 0 },
|
61
|
+
testsuites: []
|
62
|
+
})
|
63
|
+
end
|
64
|
+
|
65
|
+
def after_all
|
66
|
+
template_data.time = Time.now - timer_all
|
67
|
+
end
|
68
|
+
|
69
|
+
def before_specification
|
70
|
+
@timer_specification = Time.now
|
71
|
+
template_data.testsuites << OpenStruct.new({
|
72
|
+
:name => specification.name,
|
73
|
+
:counts => Hash.new{|h,k| h[k] = 0 },
|
74
|
+
:testcases => []
|
75
|
+
})
|
76
|
+
end
|
77
|
+
|
78
|
+
def specification_done
|
79
|
+
template_data.testsuites[-1].time = Time.now - timer_specification
|
80
|
+
end
|
81
|
+
|
82
|
+
def spec_file_error(e)
|
83
|
+
template_data.testsuites[-1].testcases << OpenStruct.new({
|
84
|
+
:name => "Specification can be loaded",
|
85
|
+
:assert => 1,
|
86
|
+
:classname => "Webspicy.Specification",
|
87
|
+
:failures => [],
|
88
|
+
:errors => [OpenStruct.new({
|
89
|
+
:type => e.class,
|
90
|
+
:message => e.message
|
91
|
+
})]
|
92
|
+
})
|
93
|
+
end
|
94
|
+
|
95
|
+
def before_test_case
|
96
|
+
@timer_testcase = Time.now
|
97
|
+
template_data.testsuites[-1].testcases << OpenStruct.new({
|
98
|
+
:name => test_case.description,
|
99
|
+
:assert => test_case.assert.length,
|
100
|
+
:classname => test_case.class.name.to_s.gsub(/::/, "."),
|
101
|
+
:failures => [],
|
102
|
+
:errors => [],
|
103
|
+
})
|
104
|
+
template_data.counts[:total] += 1
|
105
|
+
template_data.testsuites[-1].counts[:total] += 1
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_case_done
|
109
|
+
template_data.testsuites[-1].testcases[-1].time = Time.now - timer_testcase
|
110
|
+
end
|
111
|
+
|
112
|
+
def check_failure(check, ex)
|
113
|
+
template_data.testsuites[-1].testcases[-1].failures << OpenStruct.new({
|
114
|
+
:type => check.class.name,
|
115
|
+
:message => ex.message
|
116
|
+
})
|
117
|
+
template_data.counts[:failures] += 1
|
118
|
+
template_data.testsuites[-1].counts[:failures] += 1
|
119
|
+
end
|
120
|
+
|
121
|
+
def check_error(check, ex)
|
122
|
+
template_data.testsuites[-1].testcases[-1].errors << OpenStruct.new({
|
123
|
+
:type => check.class.name,
|
124
|
+
:message => ex.message
|
125
|
+
})
|
126
|
+
template_data.counts[:errors] += 1
|
127
|
+
template_data.testsuites[-1].counts[:errors] += 1
|
128
|
+
end
|
129
|
+
|
130
|
+
def report
|
131
|
+
require 'mustache'
|
132
|
+
with_io do |io|
|
133
|
+
io << Mustache.render(TPL, template_data)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def with_io(&bl)
|
140
|
+
case io = @path_or_io
|
141
|
+
when IO, StringIO
|
142
|
+
bl.call(io)
|
143
|
+
else
|
144
|
+
Path(io).open('w', &bl)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end # class JunitXmlFile
|
149
|
+
end # class Reporter
|
150
|
+
end # class Tester
|
151
|
+
end # module Webspicy
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Webspicy
|
2
|
+
class Tester
|
3
|
+
class Reporter
|
4
|
+
class SuccessOrNot < Summary
|
5
|
+
|
6
|
+
def report
|
7
|
+
total_error_count
|
8
|
+
end
|
9
|
+
|
10
|
+
end # class SuccessOrNot
|
11
|
+
ErrorCount = SuccessOrNot # for backward compatibility
|
12
|
+
end # class Reporter
|
13
|
+
end # class Tester
|
14
|
+
end # module Webspicy
|
@@ -26,7 +26,7 @@ module Webspicy
|
|
26
26
|
@spec_file_errors_count += 1
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
29
|
+
def test_case_done
|
30
30
|
if tester.test_case.counterexample?
|
31
31
|
@counterexamples_count += 1
|
32
32
|
else
|
@@ -54,8 +54,12 @@ module Webspicy
|
|
54
54
|
io.flush
|
55
55
|
end
|
56
56
|
|
57
|
+
def total_error_count
|
58
|
+
@spec_file_errors_count + @errors_count + @failures_count
|
59
|
+
end
|
60
|
+
|
57
61
|
def success?
|
58
|
-
|
62
|
+
total_error_count == 0
|
59
63
|
end
|
60
64
|
|
61
65
|
end # class Summary
|
data/lib/webspicy/version.rb
CHANGED
data/lib/webspicy/web.rb
CHANGED
@@ -1,3 +1,49 @@
|
|
1
|
+
module Webspicy
|
2
|
+
module Web
|
3
|
+
|
4
|
+
require_relative 'web/specification'
|
5
|
+
|
6
|
+
FORMALDOC = Finitio.system(Path.dir/("web/formaldoc.fio"))
|
7
|
+
|
8
|
+
def specification(raw, file = nil, scope = Webspicy.default_scope)
|
9
|
+
raw = YAML.load(raw) if raw.is_a?(String)
|
10
|
+
Webspicy.with_scope(scope) do
|
11
|
+
r = FORMALDOC["Specification"].dress(raw)
|
12
|
+
r.config = scope.config
|
13
|
+
r.located_at!(file) if file
|
14
|
+
r
|
15
|
+
end
|
16
|
+
rescue Finitio::Error => ex
|
17
|
+
handle_finitio_error(ex)
|
18
|
+
end
|
19
|
+
module_function :specification
|
20
|
+
|
21
|
+
def service(raw, scope = Webspicy.default_scope)
|
22
|
+
Webspicy.with_scope(scope) do
|
23
|
+
FORMALDOC["Service"].dress(raw)
|
24
|
+
end
|
25
|
+
rescue Finitio::Error => ex
|
26
|
+
handle_finitio_error(ex)
|
27
|
+
end
|
28
|
+
module_function :service
|
29
|
+
|
30
|
+
def test_case(raw, scope = Webspicy.default_scope)
|
31
|
+
Webspicy.with_scope(scope) do
|
32
|
+
FORMALDOC["TestCase"].dress(raw)
|
33
|
+
end
|
34
|
+
rescue Finitio::Error => ex
|
35
|
+
handle_finitio_error(ex)
|
36
|
+
end
|
37
|
+
module_function :test_case
|
38
|
+
|
39
|
+
def handle_finitio_error(ex)
|
40
|
+
puts ex.root_cause.message
|
41
|
+
raise ex
|
42
|
+
end
|
43
|
+
module_function :handle_finitio_error
|
44
|
+
|
45
|
+
end # module Web
|
46
|
+
end # module Webspicy
|
1
47
|
require_relative 'web/client'
|
2
48
|
require_relative 'web/invocation'
|
3
49
|
require_relative 'web/mocker'
|
@@ -1,23 +1,17 @@
|
|
1
1
|
@import finitio/data
|
2
|
+
@import webspicy/shared
|
2
3
|
|
3
4
|
Method =
|
4
5
|
String( s | s =~ /^(GET|POST|POST_FORM|PUT|DELETE|PATCH|PUT|OPTIONS)$/ )
|
5
6
|
|
6
|
-
Tag = String( s | s.length > 0 )
|
7
|
-
|
8
|
-
Schema =
|
9
|
-
.Finitio::System <fio> String
|
10
|
-
\( s | ::Webspicy.schema(s) )
|
11
|
-
\( s | raise "Unsupported" )
|
12
|
-
|
13
7
|
FileUpload =
|
14
|
-
.Webspicy::FileUpload <info> {
|
8
|
+
.Webspicy::Web::Specification::FileUpload <info> {
|
15
9
|
path : String
|
16
10
|
content_type : String
|
17
11
|
param_name :? String
|
18
12
|
}
|
19
13
|
|
20
|
-
Specification = .Webspicy::Specification
|
14
|
+
Specification = .Webspicy::Web::Specification
|
21
15
|
<info> {
|
22
16
|
name: String
|
23
17
|
url: String
|
@@ -41,7 +35,7 @@ Specification = .Webspicy::Specification
|
|
41
35
|
}
|
42
36
|
|
43
37
|
Service =
|
44
|
-
.Webspicy::Specification::Service <info> {
|
38
|
+
.Webspicy::Web::Specification::Service <info> {
|
45
39
|
method : Method
|
46
40
|
description : String
|
47
41
|
preconditions :? [String]|String
|
@@ -57,7 +51,7 @@ Service =
|
|
57
51
|
}
|
58
52
|
|
59
53
|
TestCase =
|
60
|
-
.Webspicy::Specification::TestCase <info> {
|
54
|
+
.Webspicy::Web::Specification::TestCase <info> {
|
61
55
|
description :? String
|
62
56
|
dress_params :? Boolean
|
63
57
|
params :? Params
|
@@ -77,8 +71,6 @@ TestCase =
|
|
77
71
|
tags :? [Tag]
|
78
72
|
}
|
79
73
|
|
80
|
-
Params = .Array|.Hash
|
81
|
-
|
82
74
|
StatusRange = .Webspicy::Support::StatusRange
|
83
75
|
<int> Integer
|
84
76
|
<str> String(s | s =~ /^\dxx$/ )
|