pact 1.3.3 → 1.4.0
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.
- data/CHANGELOG.md +37 -1
- data/lib/pact/cli.rb +0 -26
- data/lib/pact/consumer/configuration/configuration_extensions.rb +51 -0
- data/lib/pact/consumer/configuration/mock_service.rb +2 -1
- data/lib/pact/consumer/configuration.rb +0 -1
- data/lib/pact/consumer/consumer_contract_builder.rb +3 -3
- data/lib/pact/consumer/interaction_builder.rb +3 -5
- data/lib/pact/doc/interaction_view_model.rb +9 -6
- data/lib/pact/doc/sort_interactions.rb +1 -1
- data/lib/pact/provider/configuration/configuration_extension.rb +0 -9
- data/lib/pact/provider/rspec.rb +11 -9
- data/lib/pact/version.rb +1 -1
- data/lib/pact.rb +6 -5
- data/pact.gemspec +6 -2
- metadata +57 -304
- data/.gitignore +0 -29
- data/.rspec +0 -2
- data/.ruby-version +0 -1
- data/.travis.yml +0 -8
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -86
- data/README.md +0 -313
- data/Rakefile +0 -9
- data/config.ru +0 -3
- data/documentation/README.md +0 -13
- data/documentation/configuration.md +0 -166
- data/documentation/diff_formatter_embedded.png +0 -0
- data/documentation/diff_formatter_list.png +0 -0
- data/documentation/diff_formatter_unix.png +0 -0
- data/example/animal-service/Gemfile +0 -14
- data/example/animal-service/Gemfile.lock +0 -69
- data/example/animal-service/Rakefile +0 -5
- data/example/animal-service/config.ru +0 -3
- data/example/animal-service/db/animal_db.sqlite3 +0 -0
- data/example/animal-service/lib/animal_service/animal_repository.rb +0 -12
- data/example/animal-service/lib/animal_service/api.rb +0 -28
- data/example/animal-service/lib/animal_service/db.rb +0 -5
- data/example/animal-service/spec/service_consumers/pact_helper.rb +0 -11
- data/example/animal-service/spec/service_consumers/provider_states_for_zoo_app.rb +0 -26
- data/example/zoo-app/Gemfile +0 -12
- data/example/zoo-app/Gemfile.lock +0 -63
- data/example/zoo-app/Rakefile +0 -5
- data/example/zoo-app/doc/pacts/markdown/README.md +0 -3
- data/example/zoo-app/doc/pacts/markdown/Zoo App - Animal Service.md +0 -75
- data/example/zoo-app/lib/zoo_app/animal_service_client.rb +0 -40
- data/example/zoo-app/lib/zoo_app/models/alligator.rb +0 -15
- data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +0 -67
- data/example/zoo-app/spec/service_providers/animal_service_client_spec.rb +0 -71
- data/example/zoo-app/spec/service_providers/pact_helper.rb +0 -15
- data/example/zoo-app/spec/spec_helper.rb +0 -6
- data/lib/pact/configuration.rb +0 -195
- data/lib/pact/consumer/app_manager.rb +0 -158
- data/lib/pact/consumer/interactions_filter.rb +0 -48
- data/lib/pact/consumer/mock_service/app.rb +0 -82
- data/lib/pact/consumer/mock_service/interaction_delete.rb +0 -33
- data/lib/pact/consumer/mock_service/interaction_list.rb +0 -76
- data/lib/pact/consumer/mock_service/interaction_mismatch.rb +0 -73
- data/lib/pact/consumer/mock_service/interaction_post.rb +0 -31
- data/lib/pact/consumer/mock_service/interaction_replay.rb +0 -139
- data/lib/pact/consumer/mock_service/log_get.rb +0 -28
- data/lib/pact/consumer/mock_service/missing_interactions_get.rb +0 -30
- data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +0 -31
- data/lib/pact/consumer/mock_service/pact_post.rb +0 -33
- data/lib/pact/consumer/mock_service/rack_request_helper.rb +0 -51
- data/lib/pact/consumer/mock_service/verification_get.rb +0 -68
- data/lib/pact/consumer/mock_service.rb +0 -2
- data/lib/pact/consumer/mock_service_client.rb +0 -65
- data/lib/pact/consumer/mock_service_interaction_expectation.rb +0 -37
- data/lib/pact/consumer/request.rb +0 -27
- data/lib/pact/consumer/server.rb +0 -90
- data/lib/pact/consumer_contract/consumer_contract.rb +0 -115
- data/lib/pact/consumer_contract/consumer_contract_writer.rb +0 -84
- data/lib/pact/consumer_contract/file_name.rb +0 -19
- data/lib/pact/consumer_contract/headers.rb +0 -51
- data/lib/pact/consumer_contract/interaction.rb +0 -67
- data/lib/pact/consumer_contract/pact_file.rb +0 -24
- data/lib/pact/consumer_contract/request.rb +0 -73
- data/lib/pact/consumer_contract/service_consumer.rb +0 -28
- data/lib/pact/consumer_contract/service_provider.rb +0 -28
- data/lib/pact/consumer_contract.rb +0 -1
- data/lib/pact/logging.rb +0 -14
- data/lib/pact/matchers/actual_type.rb +0 -16
- data/lib/pact/matchers/base_difference.rb +0 -37
- data/lib/pact/matchers/differ.rb +0 -153
- data/lib/pact/matchers/difference.rb +0 -13
- data/lib/pact/matchers/difference_indicator.rb +0 -26
- data/lib/pact/matchers/embedded_diff_formatter.rb +0 -62
- data/lib/pact/matchers/expected_type.rb +0 -35
- data/lib/pact/matchers/index_not_found.rb +0 -15
- data/lib/pact/matchers/list_diff_formatter.rb +0 -101
- data/lib/pact/matchers/matchers.rb +0 -139
- data/lib/pact/matchers/no_diff_indicator.rb +0 -18
- data/lib/pact/matchers/regexp_difference.rb +0 -13
- data/lib/pact/matchers/type_difference.rb +0 -16
- data/lib/pact/matchers/unexpected_index.rb +0 -11
- data/lib/pact/matchers/unexpected_key.rb +0 -11
- data/lib/pact/matchers/unix_diff_formatter.rb +0 -114
- data/lib/pact/matchers.rb +0 -1
- data/lib/pact/reification.rb +0 -28
- data/lib/pact/rspec.rb +0 -53
- data/lib/pact/shared/active_support_support.rb +0 -51
- data/lib/pact/shared/dsl.rb +0 -76
- data/lib/pact/shared/jruby_support.rb +0 -18
- data/lib/pact/shared/json_differ.rb +0 -15
- data/lib/pact/shared/key_not_found.rb +0 -15
- data/lib/pact/shared/null_expectation.rb +0 -31
- data/lib/pact/shared/request.rb +0 -80
- data/lib/pact/shared/text_differ.rb +0 -14
- data/lib/pact/something_like.rb +0 -49
- data/lib/pact/symbolize_keys.rb +0 -12
- data/lib/pact/term.rb +0 -85
- data/scratchpad.rb +0 -52
- data/spec/features/consumption_spec.rb +0 -114
- data/spec/features/production_spec.rb +0 -155
- data/spec/features/provider_states/zebras.rb +0 -28
- data/spec/integration/consumer_spec.rb +0 -212
- data/spec/integration/pact/consumer_configuration_spec.rb +0 -66
- data/spec/integration/pact/provider_configuration_spec.rb +0 -25
- data/spec/lib/pact/cli_spec.rb +0 -47
- data/spec/lib/pact/configuration_spec.rb +0 -297
- data/spec/lib/pact/consumer/app_manager_spec.rb +0 -41
- data/spec/lib/pact/consumer/configuration_spec.rb +0 -57
- data/spec/lib/pact/consumer/consumer_contract_builder_spec.rb +0 -69
- data/spec/lib/pact/consumer/interaction_builder_spec.rb +0 -91
- data/spec/lib/pact/consumer/interactions_spec.rb +0 -64
- data/spec/lib/pact/consumer/mock_service/app_spec.rb +0 -52
- data/spec/lib/pact/consumer/mock_service/interaction_list_spec.rb +0 -78
- data/spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb +0 -70
- data/spec/lib/pact/consumer/mock_service/interaction_replay_spec.rb +0 -12
- data/spec/lib/pact/consumer/mock_service/rack_request_helper_spec.rb +0 -88
- data/spec/lib/pact/consumer/mock_service/verification_get_spec.rb +0 -142
- data/spec/lib/pact/consumer/mock_service_client_spec.rb +0 -88
- data/spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb +0 -54
- data/spec/lib/pact/consumer/request_spec.rb +0 -24
- data/spec/lib/pact/consumer/service_consumer_spec.rb +0 -11
- data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +0 -58
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +0 -180
- data/spec/lib/pact/consumer_contract/consumer_contract_writer_spec.rb +0 -111
- data/spec/lib/pact/consumer_contract/headers_spec.rb +0 -107
- data/spec/lib/pact/consumer_contract/interaction_spec.rb +0 -107
- data/spec/lib/pact/consumer_contract/request_spec.rb +0 -329
- data/spec/lib/pact/doc/generator_spec.rb +0 -84
- data/spec/lib/pact/doc/interaction_view_model_spec.rb +0 -132
- data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +0 -29
- data/spec/lib/pact/doc/markdown/index_renderer_spec.rb +0 -29
- data/spec/lib/pact/matchers/differ_spec.rb +0 -214
- data/spec/lib/pact/matchers/difference_spec.rb +0 -22
- data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +0 -90
- data/spec/lib/pact/matchers/index_not_found_spec.rb +0 -21
- data/spec/lib/pact/matchers/list_diff_formatter_spec.rb +0 -114
- data/spec/lib/pact/matchers/matchers_spec.rb +0 -500
- data/spec/lib/pact/matchers/regexp_difference_spec.rb +0 -20
- data/spec/lib/pact/matchers/type_difference_spec.rb +0 -34
- data/spec/lib/pact/matchers/unexpected_index_spec.rb +0 -20
- data/spec/lib/pact/matchers/unexpected_key_spec.rb +0 -20
- data/spec/lib/pact/matchers/unix_diff_formatter_spec.rb +0 -216
- data/spec/lib/pact/provider/configuration/configuration_extension_spec.rb +0 -30
- data/spec/lib/pact/provider/configuration/pact_verification_spec.rb +0 -43
- data/spec/lib/pact/provider/configuration/service_provider_config_spec.rb +0 -21
- data/spec/lib/pact/provider/configuration/service_provider_dsl_spec.rb +0 -108
- data/spec/lib/pact/provider/configuration_spec.rb +0 -50
- data/spec/lib/pact/provider/matchers/messages_spec.rb +0 -116
- data/spec/lib/pact/provider/pact_helper_locator_spec.rb +0 -54
- data/spec/lib/pact/provider/print_missing_provider_states_spec.rb +0 -19
- data/spec/lib/pact/provider/request_spec.rb +0 -78
- data/spec/lib/pact/provider/rspec/formatter_rspec_2_spec.rb +0 -68
- data/spec/lib/pact/provider/rspec/formatter_rspec_3_spec.rb +0 -72
- data/spec/lib/pact/provider/rspec_spec.rb +0 -55
- data/spec/lib/pact/provider/state/provider_state_manager_spec.rb +0 -89
- data/spec/lib/pact/provider/state/provider_state_proxy_spec.rb +0 -80
- data/spec/lib/pact/provider/state/provider_state_spec.rb +0 -213
- data/spec/lib/pact/provider/world_spec.rb +0 -41
- data/spec/lib/pact/reification_spec.rb +0 -67
- data/spec/lib/pact/shared/dsl_spec.rb +0 -86
- data/spec/lib/pact/shared/json_differ_spec.rb +0 -36
- data/spec/lib/pact/shared/key_not_found_spec.rb +0 -20
- data/spec/lib/pact/shared/request_spec.rb +0 -111
- data/spec/lib/pact/shared/text_differ_spec.rb +0 -54
- data/spec/lib/pact/something_like_spec.rb +0 -21
- data/spec/lib/pact/tasks/task_helper_spec.rb +0 -74
- data/spec/lib/pact/tasks/verification_task_spec.rb +0 -75
- data/spec/lib/pact/term_spec.rb +0 -89
- data/spec/pact_specification/compliance-1.0.0.rb +0 -47
- data/spec/spec_helper.rb +0 -22
- data/spec/standalone/consumer_fail_test.rb +0 -55
- data/spec/standalone/consumer_pass_test.rb +0 -51
- data/spec/support/a_consumer-a_producer.json +0 -32
- data/spec/support/a_consumer-a_provider.json +0 -32
- data/spec/support/active_support_if_configured.rb +0 -6
- data/spec/support/app_for_config_ru.rb +0 -4
- data/spec/support/consumer_contract_template.json +0 -24
- data/spec/support/dsl_spec_support.rb +0 -7
- data/spec/support/factories.rb +0 -82
- data/spec/support/generated_index.md +0 -4
- data/spec/support/generated_markdown.md +0 -55
- data/spec/support/interaction_view_model.json +0 -63
- data/spec/support/interaction_view_model_with_terms.json +0 -50
- data/spec/support/markdown_pact.json +0 -48
- data/spec/support/missing_provider_states_output.txt +0 -25
- data/spec/support/options.json +0 -21
- data/spec/support/options_app.rb +0 -15
- data/spec/support/pact_helper.rb +0 -57
- data/spec/support/shared_examples_for_request.rb +0 -94
- data/spec/support/spec_support.rb +0 -20
- data/spec/support/stubbing.json +0 -22
- data/spec/support/stubbing_using_allow.rb +0 -29
- data/spec/support/term.json +0 -48
- data/spec/support/test_app_fail.json +0 -61
- data/spec/support/test_app_pass.json +0 -38
- data/spec/support/test_app_with_right_content_type_differ.json +0 -23
- data/tasks/pact-test.rake +0 -109
- data/tasks/spec.rake +0 -8
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'net/http'
|
|
3
|
-
require 'pact/consumer'
|
|
4
|
-
require 'pact/consumer/rspec'
|
|
5
|
-
require 'faraday'
|
|
6
|
-
load 'pact/consumer/world.rb'
|
|
7
|
-
|
|
8
|
-
describe "A service consumer side of a pact", :pact => true do
|
|
9
|
-
|
|
10
|
-
context "with more than one matching interaction found" do
|
|
11
|
-
let(:expected_response) do
|
|
12
|
-
{"message"=>"Multiple interaction found for GET /path", "matching_interactions"=>[{"description"=>"a request", "request"=>{"method"=>"get", "path"=>"/path", "body"=>{"a"=>"some body"}, "headers"=>{"Content-Type"=>"application/json"}}}, {"description"=>"an identical request", "request"=>{"method"=>"get", "path"=>"/path", "body"=>{"a"=>"some body"}, "headers"=>{"Content-Type"=>"application/json"}}}]}
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "returns an error" do
|
|
16
|
-
Pact.clear_configuration
|
|
17
|
-
Pact.clear_consumer_world
|
|
18
|
-
|
|
19
|
-
Pact.service_consumer "Consumer" do
|
|
20
|
-
has_pact_with "Mary Service" do
|
|
21
|
-
mock_service :mary_service do
|
|
22
|
-
verify false
|
|
23
|
-
port 1237
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
mary_service
|
|
29
|
-
.given("something")
|
|
30
|
-
.upon_receiving("a request")
|
|
31
|
-
.with(method: 'get', path: '/path', body: {a: 'some body'}, headers: {'Content-Type' => 'application/json'})
|
|
32
|
-
.will_respond_with(status: 200)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
mary_service
|
|
36
|
-
.upon_receiving("an identical request")
|
|
37
|
-
.with(method: 'get', path: '/path', body: {a: 'some body'}, headers: {'Content-Type' => 'application/json'})
|
|
38
|
-
.will_respond_with(status: 200)
|
|
39
|
-
|
|
40
|
-
uri = URI('http://localhost:1237/path')
|
|
41
|
-
post_req = Net::HTTP::Get.new(uri.path)
|
|
42
|
-
post_req['Content-Type'] = "application/json"
|
|
43
|
-
post_req.body = {a: "some body"}.to_json
|
|
44
|
-
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
|
45
|
-
http.request post_req
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
expect(JSON.load(response.body)).to eq expected_response
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
context "with no matching interaction found" do
|
|
54
|
-
|
|
55
|
-
let(:expected_response) do
|
|
56
|
-
{
|
|
57
|
-
"message"=>"No interaction found for GET /path",
|
|
58
|
-
"interaction_diffs"=>[{
|
|
59
|
-
"description" => "a request that will not be properly matched",
|
|
60
|
-
"provider_state" => "something",
|
|
61
|
-
"body"=>{
|
|
62
|
-
"a"=>{
|
|
63
|
-
"EXPECTED"=>"some body",
|
|
64
|
-
"ACTUAL"=>"not matching body"
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}]
|
|
68
|
-
}
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
it "returns an error" do
|
|
72
|
-
Pact.clear_configuration
|
|
73
|
-
|
|
74
|
-
Pact.service_consumer "Consumer" do
|
|
75
|
-
has_pact_with "Mary Service" do
|
|
76
|
-
mock_service :mary_service do
|
|
77
|
-
verify false
|
|
78
|
-
port 1236
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
mary_service
|
|
84
|
-
.given("something")
|
|
85
|
-
.upon_receiving("a request that will not be properly matched")
|
|
86
|
-
.with(method: 'get', path: '/path', body: {a: 'some body'}, headers: {'Content-Type' => 'application/json'})
|
|
87
|
-
.will_respond_with(status: 200)
|
|
88
|
-
|
|
89
|
-
uri = URI('http://localhost:1236/path')
|
|
90
|
-
post_req = Net::HTTP::Get.new(uri.path)
|
|
91
|
-
post_req['Content-Type'] = "application/json"
|
|
92
|
-
post_req.body = {a: "not matching body"}.to_json
|
|
93
|
-
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
|
94
|
-
http.request post_req
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
expect(JSON.load(response.body)).to eq expected_response
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
context "with a provider state" do
|
|
102
|
-
before do
|
|
103
|
-
Pact.clear_configuration
|
|
104
|
-
|
|
105
|
-
Pact.service_consumer "Consumer" do
|
|
106
|
-
has_pact_with "Zebra Service" do
|
|
107
|
-
mock_service :zebra_service do
|
|
108
|
-
verify false
|
|
109
|
-
port 1235
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
let(:body) { 'That is some good Mallory.' }
|
|
116
|
-
|
|
117
|
-
it "goes like this" do
|
|
118
|
-
zebra_service.
|
|
119
|
-
given(:the_zebras_are_here).
|
|
120
|
-
upon_receiving("a retrieve Mallory request").with({
|
|
121
|
-
method: :get,
|
|
122
|
-
path: '/mallory',
|
|
123
|
-
headers: {'Accept' => 'text/html'}
|
|
124
|
-
}).
|
|
125
|
-
will_respond_with({
|
|
126
|
-
status: 200,
|
|
127
|
-
headers: { 'Content-Type' => 'text/html' },
|
|
128
|
-
body: Pact::Term.new(matcher: /Mallory/, generate: body)
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
response = Faraday.get(zebra_service.mock_service_base_url + "/mallory", nil, {'Accept' => 'text/html'})
|
|
132
|
-
expect(response.body).to eq body
|
|
133
|
-
|
|
134
|
-
interactions = Pact::ConsumerContract.from_json(zebra_service.write_pact).interactions
|
|
135
|
-
expect(interactions.first.provider_state).to eq("the_zebras_are_here")
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
context "with multiple headers" do
|
|
140
|
-
before do
|
|
141
|
-
Pact.clear_configuration
|
|
142
|
-
Pact.service_consumer "Consumer" do
|
|
143
|
-
has_pact_with "Multi Headers Service" do
|
|
144
|
-
mock_service :multi_headers_service do
|
|
145
|
-
verify true
|
|
146
|
-
port 1240
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
multi_headers_service.
|
|
152
|
-
given("there are multiple headers").
|
|
153
|
-
upon_receiving("a request with multiple headers").
|
|
154
|
-
with(method: :get, path: '/something', headers: {'X-Something' => "1, 2"}).
|
|
155
|
-
will_respond_with(status: 200)
|
|
156
|
-
|
|
157
|
-
uri = URI('http://localhost:1240/something')
|
|
158
|
-
post_req = Net::HTTP::Get.new(uri.path)
|
|
159
|
-
post_req.add_field('X-Something', '1')
|
|
160
|
-
post_req.add_field('X-Something', '2')
|
|
161
|
-
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
|
162
|
-
http.request post_req
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
it "handles multiple headers with the same name in a comma separated list" do
|
|
167
|
-
interactions = Pact::ConsumerContract.from_json(multi_headers_service.write_pact).interactions
|
|
168
|
-
expect(interactions.first.request.headers['X-Something']).to eq("1, 2")
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
context "with a async interaction with provider" do
|
|
174
|
-
before do
|
|
175
|
-
Pact.clear_configuration
|
|
176
|
-
|
|
177
|
-
Pact.service_consumer "Consumer" do
|
|
178
|
-
has_pact_with "Zebra Service" do
|
|
179
|
-
mock_service :zebra_service do
|
|
180
|
-
verify true
|
|
181
|
-
port 1239
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
it "goes like this" do
|
|
188
|
-
zebra_service.
|
|
189
|
-
given(:the_zebras_are_here).
|
|
190
|
-
upon_receiving("a retrieve Mallory request").
|
|
191
|
-
with({
|
|
192
|
-
method: :get,
|
|
193
|
-
path: '/mallory'
|
|
194
|
-
}).
|
|
195
|
-
will_respond_with({status: 200})
|
|
196
|
-
|
|
197
|
-
async_interaction { Net::HTTP.get_response(URI('http://localhost:1239/mallory'))}
|
|
198
|
-
|
|
199
|
-
zebra_service.wait_for_interactions wait_max_seconds: 1, poll_interval: 0.1
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
def async_interaction
|
|
203
|
-
Thread.new do
|
|
204
|
-
sleep 0.2
|
|
205
|
-
yield
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
end
|
|
212
|
-
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'pact/configuration'
|
|
3
|
-
require 'pact/consumer/configuration'
|
|
4
|
-
|
|
5
|
-
describe "consumer side" do
|
|
6
|
-
describe "configure" do
|
|
7
|
-
|
|
8
|
-
class TestHelper
|
|
9
|
-
include Pact::Consumer::ConsumerContractBuilders
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
let(:application) { double("App")}
|
|
13
|
-
let(:world) { Pact::Consumer::World.new }
|
|
14
|
-
|
|
15
|
-
before do
|
|
16
|
-
Pact.clear_configuration
|
|
17
|
-
Pact::Consumer::AppManager.instance.clear_all
|
|
18
|
-
# Don't want processes actually spawning
|
|
19
|
-
allow_any_instance_of(Pact::Consumer::AppRegistration).to receive(:spawn)
|
|
20
|
-
allow(Pact).to receive(:consumer_world).and_return(world)
|
|
21
|
-
|
|
22
|
-
my_app = application
|
|
23
|
-
|
|
24
|
-
Pact.service_consumer "My Consumer" do
|
|
25
|
-
app my_app
|
|
26
|
-
port 1111
|
|
27
|
-
|
|
28
|
-
has_pact_with "My Service" do
|
|
29
|
-
mock_service :my_service do
|
|
30
|
-
port 1234
|
|
31
|
-
standalone true
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
has_pact_with "My Other Service" do
|
|
36
|
-
mock_service :my_other_service do
|
|
37
|
-
port 1235
|
|
38
|
-
standalone false
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
describe "providers" do
|
|
46
|
-
|
|
47
|
-
subject { TestHelper.new.my_service }
|
|
48
|
-
|
|
49
|
-
it "should have defined methods in MockServices for the providers" do
|
|
50
|
-
expect(subject).to be_instance_of(Pact::Consumer::ConsumerContractBuilder)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
context "when standalone is true" do
|
|
54
|
-
it "is not registerd with the AppManager" do
|
|
55
|
-
expect(Pact::Consumer::AppManager.instance.app_registered_on?(1234)).to eq false
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
context "when standalone is false" do
|
|
60
|
-
it "should register the MockServices on their given ports if they are not" do
|
|
61
|
-
expect(Pact::Consumer::AppManager.instance.app_registered_on?(1235)).to eq true
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'pact/provider/rspec'
|
|
3
|
-
|
|
4
|
-
describe "provider side" do
|
|
5
|
-
describe "configure" do
|
|
6
|
-
|
|
7
|
-
class TestHelper
|
|
8
|
-
include Pact::Provider::RSpec::InstanceMethods
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
let(:application) { double("App")}
|
|
12
|
-
|
|
13
|
-
before do
|
|
14
|
-
app_block = ->{ application }
|
|
15
|
-
Pact.service_provider "My Provider" do
|
|
16
|
-
app &app_block
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "makes the app available to the tests" do
|
|
21
|
-
expect(TestHelper.new.app).to be(application)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
end
|
|
25
|
-
end
|
data/spec/lib/pact/cli_spec.rb
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'pact/cli'
|
|
3
|
-
|
|
4
|
-
module Pact
|
|
5
|
-
describe SpecCriteria do
|
|
6
|
-
|
|
7
|
-
describe "#spec_criteria" do
|
|
8
|
-
|
|
9
|
-
let(:env_description) { "pact description set in ENV"}
|
|
10
|
-
let(:env_provider_state) { "provider state set in ENV"}
|
|
11
|
-
let(:env_criteria){ {:description=>/#{env_description}/, :provider_state=>/#{env_provider_state}/} }
|
|
12
|
-
|
|
13
|
-
let(:defaults) { {:description => default_description, :provider_state => default_provider_state} }
|
|
14
|
-
|
|
15
|
-
let(:subject) { Pact::App.new }
|
|
16
|
-
|
|
17
|
-
context "when ENV variables are defined" do
|
|
18
|
-
before do
|
|
19
|
-
allow(ENV).to receive(:[])
|
|
20
|
-
allow(ENV).to receive(:[]).with("PACT_DESCRIPTION").and_return(env_description)
|
|
21
|
-
allow(ENV).to receive(:[]).with("PACT_PROVIDER_STATE").and_return(env_provider_state)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it "returns the env vars as regexes" do
|
|
25
|
-
expect(SpecCriteria.call).to eq(env_criteria)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
context "when ENV variables are not defined" do
|
|
30
|
-
it "returns an empty hash" do
|
|
31
|
-
expect(SpecCriteria.call).to eq({})
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
context "when provider state is an empty string" do
|
|
36
|
-
before do
|
|
37
|
-
allow(ENV).to receive(:[]).with(anything).and_return(nil)
|
|
38
|
-
allow(ENV).to receive(:[]).with("PACT_PROVIDER_STATE").and_return('')
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it "returns a nil provider state so that it matches a nil provider state on the interaction" do
|
|
42
|
-
expect(SpecCriteria.call[:provider_state]).to be_nil
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'pact/configuration'
|
|
3
|
-
|
|
4
|
-
describe Pact do
|
|
5
|
-
|
|
6
|
-
before do
|
|
7
|
-
Pact.clear_configuration
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
describe "configure" do
|
|
11
|
-
KEY_VALUE_PAIRS = {pact_dir: 'a path', log_dir: 'a dir', logger: 'a logger'}
|
|
12
|
-
|
|
13
|
-
KEY_VALUE_PAIRS.each do | key, value |
|
|
14
|
-
it "should allow configuration of #{key}" do
|
|
15
|
-
Pact.configure do | config |
|
|
16
|
-
config.send("#{key}=".to_sym, value)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
expect(Pact.configuration.send(key)).to eql(value)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
describe Pact::Configuration do
|
|
26
|
-
let(:configuration) { Pact::Configuration.new }
|
|
27
|
-
|
|
28
|
-
describe "log_dir" do
|
|
29
|
-
it "sets the location of the logs" do
|
|
30
|
-
expect(Logger).to receive(:new).with("./tmp/logs/pact.log").and_call_original
|
|
31
|
-
Pact.configure do | config |
|
|
32
|
-
config.log_dir = "./tmp/logs"
|
|
33
|
-
end
|
|
34
|
-
Pact.configuration.logger
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
describe "logger" do
|
|
39
|
-
it "sets the location of the logs to log_dir by default" do
|
|
40
|
-
expect(Logger).to receive(:new).with(File.expand_path("./log/pact.log")).and_call_original
|
|
41
|
-
Pact.configuration.logger
|
|
42
|
-
end
|
|
43
|
-
it "defaults to DEBUG" do
|
|
44
|
-
expect(Pact.configuration.logger.level).to eq Logger::DEBUG
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
describe "doc_dir" do
|
|
49
|
-
it "defaults to ./doc/pacts" do
|
|
50
|
-
expect(Pact.configuration.doc_dir).to eq File.expand_path("./doc/pacts")
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "can be changed" do
|
|
54
|
-
Pact.configuration.doc_dir = "newdir"
|
|
55
|
-
expect(Pact.configuration.doc_dir).to eq "newdir"
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
describe "doc_generator" do
|
|
60
|
-
|
|
61
|
-
context "with a symbol" do
|
|
62
|
-
it "allows configuration of a doc_generator" do
|
|
63
|
-
Pact.configuration.doc_generator = :markdown
|
|
64
|
-
expect(Pact.configuration.doc_generators).to eq [Pact::Doc::Markdown::Generator]
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
context "with anything that responds to 'call'" do
|
|
69
|
-
|
|
70
|
-
it "allows configuration of a doc_generator" do
|
|
71
|
-
Pact.configuration.doc_generator = lambda { | pact_dir, doc_dir | "doc" }
|
|
72
|
-
expect(Pact.configuration.doc_generators.size).to be 1
|
|
73
|
-
expect(Pact.configuration.doc_generators.first.call('doc','pacts')).to eq ("doc")
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
context "with something that does not respond to call and doesn't have a matching doc_generator" do
|
|
79
|
-
it "raises an error" do
|
|
80
|
-
expect { Pact.configuration.doc_generator = Object.new }.to raise_error "Pact.configuration.doc_generator needs to respond to call, or be in the preconfigured list: [:markdown]"
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
describe "#diff_formatter_for_content_type" do
|
|
87
|
-
|
|
88
|
-
let(:subject) { Pact::Configuration.new }
|
|
89
|
-
|
|
90
|
-
it "returns the Pact::Matchers::UnixDiffFormatter by default" do
|
|
91
|
-
expect(subject.diff_formatter_for_content_type 'anything').to eq(Pact::Matchers::UnixDiffFormatter)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
Pact::Configuration::DIFF_FORMATTERS.each_pair do | key, diff_formatter |
|
|
95
|
-
|
|
96
|
-
context "when set to :#{key}" do
|
|
97
|
-
|
|
98
|
-
before do
|
|
99
|
-
subject.diff_formatter = key
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
it "sets the diff_formatter to #{diff_formatter}" do
|
|
103
|
-
expect(subject.diff_formatter_for_content_type nil).to be diff_formatter
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
context "when set to an object that responds to call" do
|
|
110
|
-
|
|
111
|
-
let(:diff_formatter) { lambda{ | diff| } }
|
|
112
|
-
|
|
113
|
-
before do
|
|
114
|
-
subject.diff_formatter = diff_formatter
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
it "sets the diff_formatter to the object" do
|
|
118
|
-
expect(subject.diff_formatter_for_content_type nil).to be diff_formatter
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
context "when set to an object that does not respond to call and isn't a known default option" do
|
|
123
|
-
it "raises an error" do
|
|
124
|
-
expect { subject.diff_formatter = Object.new }.to raise_error "Pact diff_formatter needs to respond to call, or be in the preconfigured list: [:embedded, :unix, :list]"
|
|
125
|
-
expect { subject.diff_formatter = Object.new }.to raise_error "Pact diff_formatter needs to respond to call, or be in the preconfigured list: [:embedded, :unix, :list]"
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
describe "diff_formatter_for_content_type" do
|
|
132
|
-
let(:diff_formatter) { lambda { |expected, actual| }}
|
|
133
|
-
context "with the default configuration" do
|
|
134
|
-
context "when the content type is nil" do
|
|
135
|
-
it "returns the UnixDiffFormatter" do
|
|
136
|
-
expect(Pact.configuration.diff_formatter_for_content_type nil).to eq Pact::Matchers::UnixDiffFormatter
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
context "when the content type is application/json" do
|
|
140
|
-
it "returns the UnixDiffFormatter" do
|
|
141
|
-
expect(Pact.configuration.diff_formatter_for_content_type nil).to eq Pact::Matchers::UnixDiffFormatter
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
context "when the content type is text/plain" do
|
|
145
|
-
it "returns the UnixDiffFormatter" do
|
|
146
|
-
expect(Pact.configuration.diff_formatter_for_content_type nil).to eq Pact::Matchers::UnixDiffFormatter
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
context "with a custom diff_formatter registered for nil content type" do
|
|
151
|
-
context "when the content_type is nil" do
|
|
152
|
-
it "returns the custom diff_formatter" do
|
|
153
|
-
Pact.configuration.register_diff_formatter nil, diff_formatter
|
|
154
|
-
expect(Pact.configuration.diff_formatter_for_content_type nil).to eq diff_formatter
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
context "with a custom diff_formatter registered for json content type" do
|
|
159
|
-
context "when the content_type is application/json" do
|
|
160
|
-
it "returns the custom diff_formatter" do
|
|
161
|
-
Pact.configuration.register_diff_formatter /json/, diff_formatter
|
|
162
|
-
expect(Pact.configuration.diff_formatter_for_content_type 'application/json').to eq diff_formatter
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
describe "register_body_differ" do
|
|
169
|
-
|
|
170
|
-
let(:differ) { lambda{ |expected, actual| } }
|
|
171
|
-
|
|
172
|
-
context "with a string for a content type" do
|
|
173
|
-
it "configures the differ for the given content type" do
|
|
174
|
-
Pact.configure do | config |
|
|
175
|
-
config.register_body_differ 'application/xml', differ
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
expect(Pact.configuration.body_differ_for_content_type 'application/xml').to be differ
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
context "with a regexp for a content type" do
|
|
183
|
-
it "returns a matching differ" do
|
|
184
|
-
Pact.configuration.register_body_differ /application\/.*xml/, differ
|
|
185
|
-
expect(Pact.configuration.body_differ_for_content_type 'application/hal+xml').to be differ
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
context "when a non string or regexp is used to register a differ" do
|
|
190
|
-
it "raises an error" do
|
|
191
|
-
expect { Pact.configuration.register_body_differ 1, differ }.to raise_error /Invalid/
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
context "when something that does not respond to call is sumbitted as a differ" do
|
|
196
|
-
it "raises an error" do
|
|
197
|
-
expect { Pact.configuration.register_body_differ 'thing', Object.new }.to raise_error /responds to call/
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
context "when a nil content type is registered for responses without a content type header" do
|
|
202
|
-
it "returns that differ if the differ for a nil content type is requested" do
|
|
203
|
-
Pact.configuration.register_body_differ nil, differ
|
|
204
|
-
expect(Pact.configuration.body_differ_for_content_type(nil)).to be differ
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
describe "body_differ_for_content_type" do
|
|
211
|
-
|
|
212
|
-
let(:differ) { lambda { |expected, actual| }}
|
|
213
|
-
|
|
214
|
-
context "when 2 potentially matching content types have a differ registered" do
|
|
215
|
-
let(:differ_1) { lambda{ |expected, actual| } }
|
|
216
|
-
let(:differ_2) { lambda{ |expected, actual| } }
|
|
217
|
-
|
|
218
|
-
it "returns the differ that was configured first" do
|
|
219
|
-
Pact.configuration.register_body_differ /application\/.*xml/, differ_2
|
|
220
|
-
Pact.configuration.register_body_differ /application\/hal\+xml/, differ_1
|
|
221
|
-
expect(Pact.configuration.body_differ_for_content_type 'application/hal+xml').to be differ_2
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
context "when a nil content type is given" do
|
|
226
|
-
it "returns the text differ" do
|
|
227
|
-
expect(Pact.configuration.body_differ_for_content_type nil).to be Pact::TextDiffer
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
context "when no matching content type is found" do
|
|
232
|
-
it "returns the text differ" do
|
|
233
|
-
expect(Pact.configuration.body_differ_for_content_type 'blah').to be Pact::TextDiffer
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
context "when the nil content type has a custom differ configured" do
|
|
238
|
-
it "returns the custom differ" do
|
|
239
|
-
Pact.configuration.register_body_differ nil, differ
|
|
240
|
-
expect(Pact.configuration.body_differ_for_content_type(nil)).to be differ
|
|
241
|
-
end
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
context "when a custom differ is registered for a content type that has a default differ" do
|
|
245
|
-
it "returns the custom differ" do
|
|
246
|
-
Pact.configuration.register_body_differ /application\/json/, differ
|
|
247
|
-
expect(Pact.configuration.body_differ_for_content_type 'application/json').to be differ
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
describe "pactfile_write_mode" do
|
|
253
|
-
context "when @pactfile_write_mode is :overwrite" do
|
|
254
|
-
it 'returns :overwrite' do
|
|
255
|
-
configuration.pactfile_write_mode = :overwrite
|
|
256
|
-
expect(configuration.pactfile_write_mode).to eq :overwrite
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
context "when @pactfile_write_mode is :update" do
|
|
260
|
-
it 'returns :overwrite' do
|
|
261
|
-
configuration.pactfile_write_mode = :update
|
|
262
|
-
expect(configuration.pactfile_write_mode).to eq :update
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
context "when @pactfile_write_mode is :smart" do
|
|
266
|
-
before do
|
|
267
|
-
configuration.pactfile_write_mode = :smart
|
|
268
|
-
expect(configuration).to receive(:is_rake_running?).and_return(is_rake_running)
|
|
269
|
-
end
|
|
270
|
-
context "when rake is running" do
|
|
271
|
-
let(:is_rake_running) { true }
|
|
272
|
-
it "returns :overwrite" do
|
|
273
|
-
expect(configuration.pactfile_write_mode).to eq :overwrite
|
|
274
|
-
end
|
|
275
|
-
end
|
|
276
|
-
context "when rake is not running" do
|
|
277
|
-
let(:is_rake_running) { false }
|
|
278
|
-
it "returns :update" do
|
|
279
|
-
expect(configuration.pactfile_write_mode).to eq :update
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
describe "default_configuration" do
|
|
286
|
-
it "should have a default pact_dir" do
|
|
287
|
-
expect(Pact.configuration.pact_dir).to eql File.expand_path('./spec/pacts')
|
|
288
|
-
end
|
|
289
|
-
it "should have a default log_dir" do
|
|
290
|
-
expect(Pact.configuration.log_dir).to eql File.expand_path('./log')
|
|
291
|
-
end
|
|
292
|
-
it "should have a default logger configured" do
|
|
293
|
-
expect(Pact.configuration.logger).to be_instance_of Logger
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module Pact::Consumer
|
|
4
|
-
describe AppManager do
|
|
5
|
-
before do
|
|
6
|
-
AppManager.instance.clear_all
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
describe "start_service_for" do
|
|
10
|
-
before do
|
|
11
|
-
allow_any_instance_of(AppRegistration).to receive(:spawn) # Don't want process actually spawning during the tests
|
|
12
|
-
end
|
|
13
|
-
let(:name) { 'some_service'}
|
|
14
|
-
context "for http://localhost" do
|
|
15
|
-
let(:url) { 'http://localhost:1234'}
|
|
16
|
-
it "starts a mock service at the given port on localhost" do
|
|
17
|
-
expect_any_instance_of(AppRegistration).to receive(:spawn)
|
|
18
|
-
AppManager.instance.register_mock_service_for name, url
|
|
19
|
-
AppManager.instance.spawn_all
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it "registers the mock service as running on the given port" do
|
|
23
|
-
AppManager.instance.register_mock_service_for name, url
|
|
24
|
-
expect(AppManager.instance.app_registered_on?(1234)).to eq true
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
context "for https://" do
|
|
28
|
-
let(:url) { 'https://localhost:1234'}
|
|
29
|
-
it "should throw an unsupported error" do
|
|
30
|
-
expect { AppManager.instance.register_mock_service_for name, url }.to raise_error "Currently only http is supported"
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
context "for a host other than localhost" do
|
|
34
|
-
let(:url) { 'http://aserver:1234'}
|
|
35
|
-
it "should throw an unsupported error" do
|
|
36
|
-
expect { AppManager.instance.register_mock_service_for name, url }.to raise_error "Currently only services on localhost are supported"
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|