webspicy 0.20.3 → 0.20.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/bin/sandr +14 -0
  3. data/bin/search +2 -0
  4. data/bin/webspicy +3 -4
  5. data/lib/finitio/webspicy/shared.fio +10 -0
  6. data/lib/webspicy.rb +22 -53
  7. data/lib/webspicy/configuration.rb +17 -0
  8. data/lib/webspicy/configuration/scope.rb +3 -2
  9. data/lib/webspicy/configuration/single_url.rb +35 -25
  10. data/lib/webspicy/configuration/single_yml_file.rb +7 -2
  11. data/lib/webspicy/specification.rb +0 -55
  12. data/lib/webspicy/specification/post/missing_condition_impl.rb +2 -2
  13. data/lib/webspicy/specification/post/unexpected_condition_impl.rb +2 -2
  14. data/lib/webspicy/specification/service.rb +1 -5
  15. data/lib/webspicy/specification/test_case.rb +0 -49
  16. data/lib/webspicy/support/colorize.rb +7 -1
  17. data/lib/webspicy/tester.rb +16 -20
  18. data/lib/webspicy/tester/fakesmtp.rb +1 -1
  19. data/lib/webspicy/tester/fakesmtp/email.rb +13 -0
  20. data/lib/webspicy/tester/file_checker.rb +1 -1
  21. data/lib/webspicy/tester/reporter.rb +6 -1
  22. data/lib/webspicy/tester/reporter/documentation.rb +30 -8
  23. data/lib/webspicy/tester/reporter/file_progress.rb +2 -2
  24. data/lib/webspicy/tester/reporter/file_summary.rb +2 -2
  25. data/lib/webspicy/tester/reporter/progress.rb +4 -4
  26. data/lib/webspicy/tester/reporter/success_or_not.rb +14 -0
  27. data/lib/webspicy/tester/reporter/summary.rb +11 -6
  28. data/lib/webspicy/tester/result/errcondition_met.rb +1 -3
  29. data/lib/webspicy/tester/result/postcondition_met.rb +1 -3
  30. data/lib/webspicy/version.rb +1 -1
  31. data/lib/webspicy/web.rb +46 -0
  32. data/lib/webspicy/{formaldoc.fio → web/formaldoc.fio} +5 -13
  33. data/lib/webspicy/web/specification.rb +68 -0
  34. data/lib/webspicy/web/specification/file_upload.rb +39 -0
  35. data/lib/webspicy/web/specification/service.rb +13 -0
  36. data/lib/webspicy/web/specification/test_case.rb +58 -0
  37. data/spec/unit/configuration/scope/test_expand_example.rb +11 -5
  38. data/spec/unit/specification/pre/test_global_request_headers.rb +3 -3
  39. data/spec/unit/specification/service/test_dress_params.rb +2 -2
  40. data/spec/unit/test_configuration.rb +1 -0
  41. data/spec/unit/tester/fakesmtp/test_email.rb +93 -0
  42. data/spec/unit/web/specification/test_instantiate_url.rb +36 -0
  43. data/spec/unit/web/specification/test_url_placeholders.rb +23 -0
  44. data/tasks/test.rake +2 -1
  45. metadata +23 -14
  46. data/lib/webspicy/specification/file_upload.rb +0 -37
  47. data/lib/webspicy/tester/reporter/error_count.rb +0 -25
  48. data/spec/unit/specification/test_instantiate_url.rb +0 -34
  49. data/spec/unit/specification/test_url_placeholders.rb +0 -21
@@ -18,9 +18,7 @@ module Webspicy
18
18
  end
19
19
 
20
20
  def call
21
- if err = post.check!
22
- _! err
23
- end
21
+ post.check!
24
22
  end
25
23
 
26
24
  end # class ErrconditionMet
@@ -18,9 +18,7 @@ module Webspicy
18
18
  end
19
19
 
20
20
  def call
21
- if err = post.check!
22
- _! err
23
- end
21
+ post.check!
24
22
  end
25
23
 
26
24
  end # class PostconditionMet
@@ -2,7 +2,7 @@ module Webspicy
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 20
5
- TINY = 3
5
+ TINY = 8
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
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$/ )
@@ -0,0 +1,68 @@
1
+ module Webspicy
2
+ module Web
3
+ class Specification < Webspicy::Specification
4
+
5
+ class << self
6
+ def info(raw)
7
+ new(raw)
8
+ end
9
+
10
+ def singleservice(raw)
11
+ converted = {
12
+ name: raw[:name] || "Unamed specification",
13
+ url: raw[:url],
14
+ services: [
15
+ Webspicy::Web.service(raw.reject{|k| k==:url or k==:name }, Webspicy.current_scope)
16
+ ]
17
+ }
18
+ info(converted)
19
+ end
20
+ end
21
+
22
+ def url
23
+ @raw[:url]
24
+ end
25
+
26
+ def url_pattern
27
+ @url_pattern ||= Mustermann.new(url, type: :template)
28
+ end
29
+
30
+ def url_placeholders
31
+ url.scan(/\{([a-zA-Z]+(\.[a-zA-Z]+)*)\}/).map{|x| x.first }
32
+ end
33
+
34
+ def instantiate_url(params)
35
+ url, rest = self.url, params.dup
36
+ url_placeholders.each do |placeholder|
37
+ value, rest = extract_placeholder_value(rest, placeholder)
38
+ url = url.gsub("{#{placeholder}}", value.to_s)
39
+ end
40
+ [ url, rest ]
41
+ end
42
+
43
+ def to_singleservice
44
+ raise NotImplementedError
45
+ end
46
+
47
+ private
48
+
49
+ def extract_placeholder_value(params, placeholder, split = nil)
50
+ return extract_placeholder_value(params, placeholder, placeholder.split(".")) unless split
51
+
52
+ key = [ split.first, split.first.to_sym ].find{|k| params.has_key?(k) }
53
+ raise "Missing URL parameter `#{placeholder}`" unless key
54
+
55
+ if split.size == 1
56
+ [ params[key], params.dup.delete_if{|k| k == key } ]
57
+ else
58
+ value, rest = extract_placeholder_value(params[key], placeholder, split[1..-1])
59
+ [ value, params.merge(key => rest) ]
60
+ end
61
+ end
62
+
63
+ end # class Specification
64
+ end # module Web
65
+ end # module Webspicy
66
+ require_relative 'specification/service'
67
+ require_relative 'specification/test_case'
68
+ require_relative 'specification/file_upload'
@@ -0,0 +1,39 @@
1
+ module Webspicy
2
+ module Web
3
+ class Specification
4
+ class FileUpload
5
+
6
+ def initialize(raw)
7
+ @path = raw[:path]
8
+ @content_type = raw[:content_type]
9
+ @param_name = raw[:param_name] || "file"
10
+ end
11
+
12
+ attr_reader :path, :content_type, :param_name
13
+
14
+ def self.info(raw)
15
+ new(raw)
16
+ end
17
+
18
+ def locate(specification)
19
+ FileUpload.new({
20
+ path: specification.locate(path),
21
+ content_type: content_type
22
+ })
23
+ end
24
+
25
+ def to_info
26
+ { path: path.to_s,
27
+ content_type: content_type,
28
+ param_name: param_name }
29
+ end
30
+
31
+ def to_s
32
+ "FileUpload(#{to_info})"
33
+ end
34
+ alias :inspect :to_s
35
+
36
+ end # class FileUpload
37
+ end # class Specification
38
+ end # module Web
39
+ end # module Webspicy
@@ -0,0 +1,13 @@
1
+ module Webspicy
2
+ module Web
3
+ class Specification
4
+ class Service < Webspicy::Specification::Service
5
+
6
+ def method
7
+ @raw[:method]
8
+ end
9
+
10
+ end # class Service
11
+ end # class Specification
12
+ end # module Web
13
+ end # module Webspicy
@@ -0,0 +1,58 @@
1
+ module Webspicy
2
+ module Web
3
+ class Specification
4
+ class TestCase < Webspicy::Specification::TestCase
5
+
6
+ def headers
7
+ @raw[:headers] ||= {}
8
+ end
9
+
10
+ def dress_params
11
+ @raw.fetch(:dress_params){ true }
12
+ end
13
+ alias :dress_params? :dress_params
14
+
15
+ def params
16
+ @raw[:params] || {}
17
+ end
18
+
19
+ def body
20
+ @raw[:body]
21
+ end
22
+
23
+ def file_upload
24
+ @raw[:file_upload]
25
+ end
26
+
27
+ def located_file_upload
28
+ file_upload ? file_upload.locate(specification) : nil
29
+ end
30
+
31
+ def expected_content_type
32
+ expected[:content_type]
33
+ end
34
+
35
+ def expected_status
36
+ expected[:status]
37
+ end
38
+
39
+ def is_expected_status?(status)
40
+ expected_status === status
41
+ end
42
+
43
+ def has_expected_status?
44
+ not expected[:status].nil?
45
+ end
46
+
47
+ def expected_headers
48
+ expected[:headers] || {}
49
+ end
50
+
51
+ def has_expected_headers?
52
+ !expected_headers.empty?
53
+ end
54
+
55
+ end # class TestCase
56
+ end # class Specification
57
+ end # module Web
58
+ end # module Webspicy
@@ -3,11 +3,17 @@ module Webspicy
3
3
  class Configuration
4
4
  describe Scope, "expand_example" do
5
5
 
6
- subject{ Scope.new({}).send(:expand_example, service, example) }
6
+ let(:config){
7
+ Configuration.new(Path.dir)
8
+ }
9
+
10
+ subject{
11
+ Scope.new(config).send(:expand_example, service, example)
12
+ }
7
13
 
8
14
  context 'when the service has no default example' do
9
15
  let(:service) {
10
- Webspicy.service({
16
+ Webspicy::Web.service({
11
17
  method: "GET",
12
18
  description: "Test service",
13
19
  preconditions: "Foo",
@@ -18,7 +24,7 @@ module Webspicy
18
24
  }
19
25
 
20
26
  let(:example) {
21
- Webspicy.test_case({
27
+ Webspicy::Web.test_case({
22
28
  description: "Hello world"
23
29
  })
24
30
  }
@@ -30,7 +36,7 @@ module Webspicy
30
36
 
31
37
  context 'when the service has a default example' do
32
38
  let(:service) {
33
- Webspicy.service({
39
+ Webspicy::Web.service({
34
40
  method: "GET",
35
41
  description: "Test service",
36
42
  preconditions: "Foo",
@@ -44,7 +50,7 @@ module Webspicy
44
50
  }
45
51
 
46
52
  let(:example) {
47
- Webspicy.test_case({
53
+ Webspicy::Web.test_case({
48
54
  description: "Hello world",
49
55
  expected: { content_type: "application/json" }
50
56
  })
@@ -15,13 +15,13 @@ module Webspicy
15
15
 
16
16
  describe "instrument" do
17
17
  it 'injects the headers' do
18
- tc = TestCase.new({})
18
+ tc = Web::Specification::TestCase.new({})
19
19
  instrument(tc)
20
20
  expect(tc.headers['Accept']).to eql("application/json")
21
21
  end
22
22
 
23
23
  it 'keeps original headers unchanged' do
24
- tc = TestCase.new({
24
+ tc = Web::Specification::TestCase.new({
25
25
  headers: {
26
26
  'Content-Type' => 'text/plain'
27
27
  }
@@ -32,7 +32,7 @@ module Webspicy
32
32
  end
33
33
 
34
34
  it 'has low precedence' do
35
- tc = TestCase.new({
35
+ tc = Web::Specification::TestCase.new({
36
36
  headers: {
37
37
  'Accept' => 'text/plain'
38
38
  }
@@ -4,7 +4,7 @@ module Webspicy
4
4
  describe Service, "dress_params" do
5
5
 
6
6
  it 'symbolizes keys' do
7
- service = Webspicy.service({
7
+ service = Webspicy::Web.service({
8
8
  method: "GET",
9
9
  description: "Test service",
10
10
  preconditions: "Foo",
@@ -17,7 +17,7 @@ module Webspicy
17
17
  end
18
18
 
19
19
  it 'supports an array' do
20
- service = Webspicy.service({
20
+ service = Webspicy::Web.service({
21
21
  method: "GET",
22
22
  description: "Test service",
23
23
  preconditions: "Foo",
@@ -36,6 +36,7 @@ module Webspicy
36
36
  expect(c).to be_a(Configuration)
37
37
  expect(c.folder).to eq(Path.pwd)
38
38
  expect(c.each_scope.to_a.size).to eql(1)
39
+ expect(c.each_scope.to_a.first.each_specification_file.to_a.size).to eql(1)
39
40
  expect(c.each_scope.to_a.first.each_specification.to_a.size).to eql(1)
40
41
  end
41
42
 
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+ require 'webspicy/tester/fakesmtp'
3
+ module Webspicy
4
+ class Tester
5
+ class Fakesmtp
6
+ describe Email do
7
+
8
+ DATA = JSON.parse <<~J
9
+ {
10
+ "attachments": [],
11
+ "headerLines": [
12
+ {
13
+ "key": "date",
14
+ "line": "Date: Tue, 20 Apr 2021 14:06:13 +0000"
15
+ },
16
+ {
17
+ "key": "from",
18
+ "line": "From: info@mydomain.be"
19
+ },
20
+ {
21
+ "key": "reply-to",
22
+ "line": "Reply-To: test@email.be"
23
+ },
24
+ {
25
+ "key": "to",
26
+ "line": "To: support@mydomain.fr"
27
+ },
28
+ {
29
+ "key": "message-id",
30
+ "line": "Message-ID: <607edfd56836e_1b0492af@1d3356d02030.mail>"
31
+ },
32
+ {
33
+ "key": "subject",
34
+ "line": "Subject: Hello World"
35
+ },
36
+ {
37
+ "key": "mime-version",
38
+ "line": "Mime-Version: 1.0"
39
+ }
40
+ ],
41
+ "html": "<p>Hello World!!</p>",
42
+ "text": "Hello World!!",
43
+ "textAsHtml": "Hello World!!",
44
+ "subject": "Hello World",
45
+ "date": "2021-04-20T14:06:13.000Z",
46
+ "to": {
47
+ "value": [
48
+ {
49
+ "address": "support@mydomain.fr",
50
+ "name": ""
51
+ }
52
+ ],
53
+ "html": "<span class=\\"mp_address_group\\"><a href=\\"mailto:support@mydomain.fr\\" class=\\"mp_address_email\\">support@mydomain.fr</a></span>",
54
+ "text": "support@mydomain.fr"
55
+ },
56
+ "from": {
57
+ "value": [
58
+ {
59
+ "address": "info@mydomain.be",
60
+ "name": ""
61
+ }
62
+ ],
63
+ "html": "<span class=\\"mp_address_group\\"><a href=\\"mailto:info@mydomain.be\\" class=\\"mp_address_email\\">info@mydomain.be</a></span>",
64
+ "text": "info@mydomain.be"
65
+ },
66
+ "messageId": "<607edfd56836e_1b0492af@1d3356d02030.mail>",
67
+ "replyTo": {
68
+ "value": [
69
+ {
70
+ "address": "test@email.be",
71
+ "name": ""
72
+ }
73
+ ],
74
+ "html": "<span class=\\"mp_address_group\\"><a href=\\"mailto:test@email.be\\" class=\\"mp_address_email\\">test@email.be</a></span>",
75
+ "text": "test@email.be"
76
+ }
77
+ }
78
+ J
79
+
80
+ subject{
81
+ Email.new(DATA)
82
+ }
83
+
84
+ it 'works as expected' do
85
+ expect(subject.from).to eql("info@mydomain.be")
86
+ expect(subject.to).to eql(["support@mydomain.fr"])
87
+ expect(subject.subject).to eql("Hello World")
88
+ end
89
+
90
+ end
91
+ end
92
+ end
93
+ end