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