pact 0.1.28 → 1.3.3

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.
Files changed (285) hide show
  1. data/.gitignore +2 -1
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +8 -0
  4. data/CHANGELOG.md +374 -0
  5. data/Gemfile +0 -1
  6. data/Gemfile.lock +58 -55
  7. data/README.md +214 -139
  8. data/Rakefile +4 -28
  9. data/bin/pact +2 -2
  10. data/config.ru +3 -0
  11. data/documentation/README.md +13 -0
  12. data/documentation/configuration.md +166 -0
  13. data/documentation/diff_formatter_embedded.png +0 -0
  14. data/documentation/diff_formatter_list.png +0 -0
  15. data/documentation/diff_formatter_unix.png +0 -0
  16. data/example/animal-service/Gemfile +14 -0
  17. data/example/animal-service/Gemfile.lock +69 -0
  18. data/example/animal-service/Rakefile +5 -0
  19. data/example/animal-service/config.ru +3 -0
  20. data/example/animal-service/db/animal_db.sqlite3 +0 -0
  21. data/example/animal-service/lib/animal_service/animal_repository.rb +12 -0
  22. data/example/animal-service/lib/animal_service/api.rb +28 -0
  23. data/example/animal-service/lib/animal_service/db.rb +5 -0
  24. data/example/animal-service/spec/service_consumers/pact_helper.rb +11 -0
  25. data/example/animal-service/spec/service_consumers/provider_states_for_zoo_app.rb +26 -0
  26. data/example/zoo-app/Gemfile +12 -0
  27. data/example/zoo-app/Gemfile.lock +63 -0
  28. data/example/zoo-app/Rakefile +5 -0
  29. data/example/zoo-app/doc/pacts/markdown/README.md +3 -0
  30. data/example/zoo-app/doc/pacts/markdown/Zoo App - Animal Service.md +75 -0
  31. data/example/zoo-app/lib/zoo_app/animal_service_client.rb +40 -0
  32. data/example/zoo-app/lib/zoo_app/models/alligator.rb +15 -0
  33. data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +67 -0
  34. data/example/zoo-app/spec/service_providers/animal_service_client_spec.rb +71 -0
  35. data/example/zoo-app/spec/service_providers/pact_helper.rb +15 -0
  36. data/example/zoo-app/spec/spec_helper.rb +6 -0
  37. data/lib/pact/cli.rb +138 -0
  38. data/lib/pact/configuration.rb +169 -28
  39. data/lib/pact/consumer/app_manager.rb +10 -29
  40. data/lib/pact/consumer/configuration/configuration_extensions.rb +15 -0
  41. data/lib/pact/consumer/configuration/dsl.rb +12 -0
  42. data/lib/pact/consumer/configuration/mock_service.rb +91 -0
  43. data/lib/pact/consumer/configuration/service_consumer.rb +51 -0
  44. data/lib/pact/consumer/configuration/service_provider.rb +40 -0
  45. data/lib/pact/consumer/configuration.rb +11 -0
  46. data/lib/pact/consumer/consumer_contract_builder.rb +44 -47
  47. data/lib/pact/consumer/interaction_builder.rb +41 -0
  48. data/lib/pact/consumer/interactions_filter.rb +48 -0
  49. data/lib/pact/consumer/mock_service/app.rb +82 -0
  50. data/lib/pact/consumer/mock_service/interaction_delete.rb +33 -0
  51. data/lib/pact/consumer/mock_service/interaction_list.rb +76 -0
  52. data/lib/pact/consumer/mock_service/interaction_mismatch.rb +73 -0
  53. data/lib/pact/consumer/mock_service/interaction_post.rb +31 -0
  54. data/lib/pact/consumer/mock_service/interaction_replay.rb +139 -0
  55. data/lib/pact/consumer/mock_service/log_get.rb +28 -0
  56. data/lib/pact/consumer/mock_service/missing_interactions_get.rb +30 -0
  57. data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +31 -0
  58. data/lib/pact/consumer/mock_service/pact_post.rb +33 -0
  59. data/lib/pact/consumer/mock_service/rack_request_helper.rb +51 -0
  60. data/lib/pact/consumer/mock_service/verification_get.rb +68 -0
  61. data/lib/pact/consumer/mock_service.rb +1 -339
  62. data/lib/pact/consumer/mock_service_client.rb +65 -0
  63. data/lib/pact/consumer/mock_service_interaction_expectation.rb +37 -0
  64. data/lib/pact/consumer/request.rb +27 -0
  65. data/lib/pact/consumer/rspec.rb +9 -19
  66. data/lib/pact/consumer/server.rb +90 -0
  67. data/lib/pact/consumer/spec_hooks.rb +38 -0
  68. data/lib/pact/consumer/world.rb +37 -0
  69. data/lib/pact/consumer.rb +10 -7
  70. data/lib/pact/consumer_contract/consumer_contract.rb +115 -0
  71. data/lib/pact/consumer_contract/consumer_contract_writer.rb +84 -0
  72. data/lib/pact/consumer_contract/file_name.rb +19 -0
  73. data/lib/pact/consumer_contract/headers.rb +51 -0
  74. data/lib/pact/consumer_contract/interaction.rb +67 -0
  75. data/lib/pact/consumer_contract/pact_file.rb +24 -0
  76. data/lib/pact/consumer_contract/request.rb +73 -0
  77. data/lib/pact/consumer_contract/service_consumer.rb +28 -0
  78. data/lib/pact/consumer_contract/service_provider.rb +28 -0
  79. data/lib/pact/consumer_contract.rb +1 -110
  80. data/lib/pact/doc/doc_file.rb +40 -0
  81. data/lib/pact/doc/generate.rb +11 -0
  82. data/lib/pact/doc/generator.rb +82 -0
  83. data/lib/pact/doc/interaction_view_model.rb +114 -0
  84. data/lib/pact/doc/markdown/consumer_contract_renderer.rb +56 -0
  85. data/lib/pact/doc/markdown/generator.rb +26 -0
  86. data/lib/pact/doc/markdown/index_renderer.rb +41 -0
  87. data/lib/pact/doc/markdown/interaction.erb +14 -0
  88. data/lib/pact/doc/markdown/interaction_renderer.rb +38 -0
  89. data/lib/pact/doc/sort_interactions.rb +17 -0
  90. data/lib/pact/matchers/actual_type.rb +16 -0
  91. data/lib/pact/matchers/base_difference.rb +37 -0
  92. data/lib/pact/matchers/differ.rb +153 -0
  93. data/lib/pact/matchers/difference.rb +13 -0
  94. data/lib/pact/matchers/difference_indicator.rb +26 -0
  95. data/lib/pact/matchers/embedded_diff_formatter.rb +62 -0
  96. data/lib/pact/matchers/expected_type.rb +35 -0
  97. data/lib/pact/matchers/index_not_found.rb +15 -0
  98. data/lib/pact/matchers/list_diff_formatter.rb +101 -0
  99. data/lib/pact/matchers/matchers.rb +91 -37
  100. data/lib/pact/matchers/no_diff_indicator.rb +18 -0
  101. data/lib/pact/matchers/regexp_difference.rb +13 -0
  102. data/lib/pact/matchers/type_difference.rb +16 -0
  103. data/lib/pact/matchers/unexpected_index.rb +11 -0
  104. data/lib/pact/matchers/unexpected_key.rb +11 -0
  105. data/lib/pact/matchers/unix_diff_formatter.rb +114 -0
  106. data/lib/pact/project_root.rb +7 -0
  107. data/lib/pact/provider/configuration/configuration_extension.rb +58 -0
  108. data/lib/pact/provider/configuration/dsl.rb +13 -0
  109. data/lib/pact/provider/configuration/pact_verification.rb +46 -0
  110. data/lib/pact/provider/configuration/service_provider_config.rb +16 -0
  111. data/lib/pact/provider/configuration/service_provider_dsl.rb +59 -0
  112. data/lib/pact/provider/configuration.rb +7 -0
  113. data/lib/pact/provider/context.rb +0 -0
  114. data/lib/pact/provider/matchers/messages.rb +45 -0
  115. data/lib/pact/provider/pact_helper_locator.rb +22 -0
  116. data/lib/pact/provider/pact_spec_runner.rb +123 -0
  117. data/lib/pact/provider/pact_verification.rb +17 -0
  118. data/lib/pact/provider/print_missing_provider_states.rb +30 -0
  119. data/lib/pact/provider/request.rb +70 -0
  120. data/lib/pact/provider/rspec/backtrace_formatter.rb +43 -0
  121. data/lib/pact/provider/rspec/custom_options_file +0 -0
  122. data/lib/pact/provider/rspec/formatter_rspec_2.rb +65 -0
  123. data/lib/pact/provider/rspec/formatter_rspec_3.rb +96 -0
  124. data/lib/pact/provider/rspec/matchers.rb +97 -0
  125. data/lib/pact/provider/rspec.rb +181 -0
  126. data/lib/pact/provider/state/provider_state.rb +181 -0
  127. data/lib/pact/provider/state/provider_state_configured_modules.rb +13 -0
  128. data/lib/pact/provider/state/provider_state_manager.rb +42 -0
  129. data/lib/pact/provider/state/provider_state_proxy.rb +39 -0
  130. data/lib/pact/provider/test_methods.rb +47 -0
  131. data/lib/pact/provider/verification_report.rb +36 -0
  132. data/lib/pact/provider/world.rb +23 -0
  133. data/lib/pact/provider.rb +3 -0
  134. data/lib/pact/reification.rb +6 -4
  135. data/lib/pact/rspec.rb +53 -0
  136. data/lib/pact/shared/active_support_support.rb +51 -0
  137. data/lib/pact/shared/dsl.rb +76 -0
  138. data/lib/pact/shared/jruby_support.rb +18 -0
  139. data/lib/pact/shared/json_differ.rb +15 -0
  140. data/lib/pact/shared/key_not_found.rb +15 -0
  141. data/lib/pact/shared/null_expectation.rb +31 -0
  142. data/lib/pact/shared/request.rb +80 -0
  143. data/lib/pact/shared/text_differ.rb +14 -0
  144. data/lib/pact/something_like.rb +49 -0
  145. data/lib/pact/symbolize_keys.rb +12 -0
  146. data/lib/pact/tasks/task_helper.rb +36 -0
  147. data/lib/pact/tasks/verification_task.rb +87 -0
  148. data/lib/pact/tasks.rb +2 -0
  149. data/lib/pact/templates/provider_state.erb +14 -0
  150. data/lib/pact/term.rb +47 -2
  151. data/lib/pact/version.rb +1 -1
  152. data/lib/pact.rb +1 -1
  153. data/lib/tasks/pact.rake +25 -2
  154. data/pact.gemspec +13 -11
  155. data/{scratchpad.txt → scratchpad.rb} +18 -2
  156. data/spec/features/consumption_spec.rb +24 -56
  157. data/spec/features/production_spec.rb +19 -24
  158. data/spec/features/{producer_states → provider_states}/zebras.rb +3 -3
  159. data/spec/integration/consumer_spec.rb +212 -0
  160. data/spec/integration/pact/consumer_configuration_spec.rb +66 -0
  161. data/spec/integration/pact/provider_configuration_spec.rb +25 -0
  162. data/spec/lib/pact/cli_spec.rb +47 -0
  163. data/spec/lib/pact/configuration_spec.rb +269 -7
  164. data/spec/lib/pact/consumer/app_manager_spec.rb +3 -3
  165. data/spec/lib/pact/consumer/configuration_spec.rb +57 -0
  166. data/spec/lib/pact/consumer/consumer_contract_builder_spec.rb +52 -70
  167. data/spec/lib/pact/consumer/interaction_builder_spec.rb +91 -0
  168. data/spec/lib/pact/consumer/interactions_spec.rb +64 -0
  169. data/spec/lib/pact/consumer/mock_service/app_spec.rb +52 -0
  170. data/spec/lib/pact/consumer/mock_service/interaction_list_spec.rb +78 -0
  171. data/spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb +70 -0
  172. data/spec/lib/pact/consumer/mock_service/interaction_replay_spec.rb +12 -0
  173. data/spec/lib/pact/consumer/mock_service/rack_request_helper_spec.rb +88 -0
  174. data/spec/lib/pact/consumer/mock_service/verification_get_spec.rb +142 -0
  175. data/spec/lib/pact/consumer/mock_service_client_spec.rb +88 -0
  176. data/spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb +54 -0
  177. data/spec/lib/pact/consumer/request_spec.rb +24 -0
  178. data/spec/lib/pact/consumer/service_consumer_spec.rb +1 -1
  179. data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +58 -0
  180. data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +180 -0
  181. data/spec/lib/pact/consumer_contract/consumer_contract_writer_spec.rb +111 -0
  182. data/spec/lib/pact/consumer_contract/headers_spec.rb +107 -0
  183. data/spec/lib/pact/consumer_contract/interaction_spec.rb +107 -0
  184. data/spec/lib/pact/{request_spec.rb → consumer_contract/request_spec.rb} +80 -67
  185. data/spec/lib/pact/doc/generator_spec.rb +84 -0
  186. data/spec/lib/pact/doc/interaction_view_model_spec.rb +132 -0
  187. data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +29 -0
  188. data/spec/lib/pact/doc/markdown/index_renderer_spec.rb +29 -0
  189. data/spec/lib/pact/matchers/differ_spec.rb +214 -0
  190. data/spec/lib/pact/matchers/difference_spec.rb +22 -0
  191. data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +90 -0
  192. data/spec/lib/pact/matchers/index_not_found_spec.rb +21 -0
  193. data/spec/lib/pact/matchers/list_diff_formatter_spec.rb +114 -0
  194. data/spec/lib/pact/matchers/matchers_spec.rb +400 -254
  195. data/spec/lib/pact/matchers/regexp_difference_spec.rb +20 -0
  196. data/spec/lib/pact/matchers/type_difference_spec.rb +34 -0
  197. data/spec/lib/pact/matchers/unexpected_index_spec.rb +20 -0
  198. data/spec/lib/pact/matchers/unexpected_key_spec.rb +20 -0
  199. data/spec/lib/pact/matchers/unix_diff_formatter_spec.rb +216 -0
  200. data/spec/lib/pact/provider/configuration/configuration_extension_spec.rb +30 -0
  201. data/spec/lib/pact/provider/configuration/pact_verification_spec.rb +43 -0
  202. data/spec/lib/pact/provider/configuration/service_provider_config_spec.rb +21 -0
  203. data/spec/lib/pact/provider/configuration/service_provider_dsl_spec.rb +108 -0
  204. data/spec/lib/pact/provider/configuration_spec.rb +50 -0
  205. data/spec/lib/pact/provider/matchers/messages_spec.rb +116 -0
  206. data/spec/lib/pact/provider/pact_helper_locator_spec.rb +54 -0
  207. data/spec/lib/pact/provider/print_missing_provider_states_spec.rb +19 -0
  208. data/spec/lib/pact/provider/request_spec.rb +78 -0
  209. data/spec/lib/pact/provider/rspec/formatter_rspec_2_spec.rb +68 -0
  210. data/spec/lib/pact/provider/rspec/formatter_rspec_3_spec.rb +72 -0
  211. data/spec/lib/pact/provider/rspec_spec.rb +55 -0
  212. data/spec/lib/pact/provider/state/provider_state_manager_spec.rb +89 -0
  213. data/spec/lib/pact/provider/state/provider_state_proxy_spec.rb +80 -0
  214. data/spec/lib/pact/provider/state/provider_state_spec.rb +213 -0
  215. data/spec/lib/pact/provider/world_spec.rb +41 -0
  216. data/spec/lib/pact/reification_spec.rb +24 -0
  217. data/spec/lib/pact/shared/dsl_spec.rb +86 -0
  218. data/spec/lib/pact/shared/json_differ_spec.rb +36 -0
  219. data/spec/lib/pact/shared/key_not_found_spec.rb +20 -0
  220. data/spec/lib/pact/shared/request_spec.rb +111 -0
  221. data/spec/lib/pact/shared/text_differ_spec.rb +54 -0
  222. data/spec/lib/pact/something_like_spec.rb +21 -0
  223. data/spec/lib/pact/tasks/task_helper_spec.rb +74 -0
  224. data/spec/lib/pact/tasks/verification_task_spec.rb +75 -0
  225. data/spec/lib/pact/term_spec.rb +57 -4
  226. data/spec/pact_specification/compliance-1.0.0.rb +47 -0
  227. data/spec/spec_helper.rb +17 -0
  228. data/spec/standalone/consumer_fail_test.rb +55 -0
  229. data/spec/standalone/consumer_pass_test.rb +51 -0
  230. data/spec/support/a_consumer-a_producer.json +2 -4
  231. data/spec/support/a_consumer-a_provider.json +32 -0
  232. data/spec/support/active_support_if_configured.rb +6 -0
  233. data/spec/support/app_for_config_ru.rb +4 -0
  234. data/spec/support/consumer_contract_template.json +24 -0
  235. data/spec/support/dsl_spec_support.rb +7 -0
  236. data/spec/support/factories.rb +82 -0
  237. data/spec/support/generated_index.md +4 -0
  238. data/spec/support/generated_markdown.md +55 -0
  239. data/spec/support/interaction_view_model.json +63 -0
  240. data/spec/support/interaction_view_model_with_terms.json +50 -0
  241. data/spec/support/markdown_pact.json +48 -0
  242. data/spec/support/missing_provider_states_output.txt +25 -0
  243. data/spec/support/options.json +21 -0
  244. data/spec/support/options_app.rb +15 -0
  245. data/spec/support/pact_helper.rb +57 -0
  246. data/spec/support/shared_examples_for_request.rb +94 -0
  247. data/spec/support/spec_support.rb +20 -0
  248. data/spec/support/stubbing.json +22 -0
  249. data/spec/support/stubbing_using_allow.rb +29 -0
  250. data/spec/support/term.json +48 -0
  251. data/spec/support/test_app_fail.json +41 -2
  252. data/spec/support/test_app_pass.json +19 -2
  253. data/spec/support/test_app_with_right_content_type_differ.json +23 -0
  254. data/tasks/pact-test.rake +98 -8
  255. data/tasks/spec.rake +8 -0
  256. metadata +393 -95
  257. data/lib/pact/app.rb +0 -32
  258. data/lib/pact/consumer/configuration_dsl.rb +0 -71
  259. data/lib/pact/consumer/dsl.rb +0 -98
  260. data/lib/pact/consumer/interaction.rb +0 -70
  261. data/lib/pact/consumer/run_condor.rb +0 -4
  262. data/lib/pact/consumer/run_mock_contract_service.rb +0 -13
  263. data/lib/pact/consumer/service_consumer.rb +0 -22
  264. data/lib/pact/consumer/service_producer.rb +0 -23
  265. data/lib/pact/json_warning.rb +0 -23
  266. data/lib/pact/producer/configuration_dsl.rb +0 -62
  267. data/lib/pact/producer/matchers.rb +0 -22
  268. data/lib/pact/producer/pact_spec_runner.rb +0 -57
  269. data/lib/pact/producer/producer_state.rb +0 -81
  270. data/lib/pact/producer/rspec.rb +0 -127
  271. data/lib/pact/producer/test_methods.rb +0 -89
  272. data/lib/pact/producer.rb +0 -1
  273. data/lib/pact/rake_task.rb +0 -64
  274. data/lib/pact/request.rb +0 -109
  275. data/lib/pact/verification_task.rb +0 -57
  276. data/spec/integration/pact/configuration_spec.rb +0 -65
  277. data/spec/lib/pact/consumer/dsl_spec.rb +0 -52
  278. data/spec/lib/pact/consumer/interaction_spec.rb +0 -108
  279. data/spec/lib/pact/consumer/mock_service_spec.rb +0 -147
  280. data/spec/lib/pact/consumer_contract_spec.rb +0 -125
  281. data/spec/lib/pact/producer/configuration_dsl_spec.rb +0 -101
  282. data/spec/lib/pact/producer/producer_state_spec.rb +0 -103
  283. data/spec/lib/pact/producer/rspec_spec.rb +0 -48
  284. data/spec/lib/pact/verification_task_spec.rb +0 -64
  285. data/spec/support/pact_rake_support.rb +0 -41
@@ -1,70 +1,61 @@
1
1
  require 'spec_helper'
2
- require 'pact/request'
2
+ require 'pact/consumer_contract/request'
3
+ require 'pact/consumer/request'
4
+ require 'support/shared_examples_for_request'
3
5
 
4
- shared_examples "a request" do
5
- describe "building from a hash" do
6
+ module Pact
7
+
8
+ describe Request::Expected do
9
+ it_behaves_like "a request"
6
10
 
7
11
  let(:raw_request) do
8
12
  {
9
13
  'method' => 'get',
10
- 'path' => '/mallory',
11
- 'headers' => {
12
- 'Content-Type' => 'application/json'
13
- },
14
- 'body' => 'hello mallory'
14
+ 'path' => '/mallory'
15
15
  }
16
16
  end
17
17
 
18
- subject { described_class.from_hash(raw_request) }
19
-
20
- its(:method) { should == 'get' }
21
- its(:path) { should == '/mallory' }
22
- its(:body) { should == 'hello mallory' }
23
- its(:query) { should eq Pact::Request::NullExpectation.new }
24
-
25
- it "blows up if method is absent" do
26
- raw_request.delete 'method'
27
- expect { described_class.from_hash(raw_request) }.to raise_error
28
- end
29
-
30
- it "blows up if path is absent" do
31
- raw_request.delete 'path'
32
- expect { described_class.from_hash(raw_request) }.to raise_error
18
+ describe "from_hash" do
19
+ context "when optional field are not defined" do
20
+ subject { described_class.from_hash(raw_request) }
21
+ it "sets their values to NullExpectation" do
22
+ expect(subject.body).to be_instance_of(Pact::NullExpectation)
23
+ expect(subject.query).to be_instance_of(Pact::NullExpectation)
24
+ expect(subject.headers).to be_instance_of(Pact::NullExpectation)
25
+ end
26
+ end
33
27
  end
34
28
 
35
- it "does not blow up if body is missing" do
36
- raw_request.delete 'body'
37
- expect { described_class.from_hash(raw_request) }.to_not raise_error
29
+ describe "as_json" do
30
+ subject { Request::Expected.new(:get, '/path', {:header => 'value'}, {:body => 'yeah'}, "query", {some: 'options'}) }
31
+ context "with options" do
32
+ it "does not include the options because they are a temporary hack and should leave no trace of themselves in the pact file" do
33
+ expect(subject.as_json.key?(:options)).to be false
34
+ end
35
+ end
38
36
  end
39
37
 
40
- end
41
- end
42
-
43
- module Pact
44
-
45
- describe Request::Expected do
46
- it_behaves_like "a request"
47
-
48
38
  describe "matching to actual requests" do
49
39
 
50
- subject { Request::Expected.new(expected_method, expected_path, expected_headers, expected_body, expected_query) }
40
+ subject { Request::Expected.new(expected_method, expected_path, expected_headers, expected_body, expected_query, options) }
41
+ let(:options) { {} }
51
42
 
52
43
  let(:expected_method) { 'get' }
53
44
  let(:expected_path) { '/foo' }
54
- let(:expected_headers) { nil }
55
- let(:expected_body) { nil }
45
+ let(:expected_headers) { Pact::NullExpectation.new }
46
+ let(:expected_body) { Pact::NullExpectation.new }
56
47
  let(:expected_query) { '' }
57
48
 
58
- let(:actual_request) { Request::Actual.new(actual_method, actual_path, actual_headers, actual_body, actual_query) }
49
+ let(:actual_request) { Consumer::Request::Actual.new(actual_method, actual_path, actual_headers, actual_body, actual_query) }
59
50
 
60
51
  let(:actual_method) { 'get' }
61
52
  let(:actual_path) { '/foo' }
62
- let(:actual_headers) { nil }
63
- let(:actual_body) { nil }
53
+ let(:actual_headers) { {} }
54
+ let(:actual_body) { '' }
64
55
  let(:actual_query) { '' }
65
56
 
66
57
  it "matches identical requests" do
67
- expect(subject.match actual_request).to be_true
58
+ expect(subject.matches? actual_request).to be true
68
59
  end
69
60
 
70
61
  context "when the methods are the same but one is symbolized" do
@@ -72,7 +63,7 @@ module Pact
72
63
  let(:actual_method) { 'get' }
73
64
 
74
65
  it "matches" do
75
- expect(subject.match actual_request).to be_true
66
+ expect(subject.matches? actual_request).to be true
76
67
  end
77
68
  end
78
69
 
@@ -81,7 +72,16 @@ module Pact
81
72
  let(:actual_method) { 'post' }
82
73
 
83
74
  it "does not match" do
84
- expect(subject.match actual_request).to be_false
75
+ expect(subject.matches? actual_request).to be false
76
+ end
77
+ end
78
+
79
+ context "when the methods are the same but different case" do
80
+ let(:expected_method) { 'get' }
81
+ let(:actual_method) { 'GET' }
82
+
83
+ it "matches" do
84
+ expect(subject.matches? actual_request).to be true
85
85
  end
86
86
  end
87
87
 
@@ -90,7 +90,7 @@ module Pact
90
90
  let(:actual_path) { '/bar' }
91
91
 
92
92
  it "does not match" do
93
- expect(subject.match actual_request).to be_false
93
+ expect(subject.matches? actual_request).to be false
94
94
  end
95
95
  end
96
96
 
@@ -99,7 +99,7 @@ module Pact
99
99
  let(:actual_path) { '/foo/' }
100
100
 
101
101
  it "matches" do
102
- expect(subject.match actual_request).to be_true
102
+ expect(subject.matches? actual_request).to be true
103
103
  end
104
104
  end
105
105
 
@@ -108,16 +108,16 @@ module Pact
108
108
  let(:actual_body) { '' }
109
109
 
110
110
  it "does not match" do
111
- expect(subject.match actual_request).to be_false
111
+ expect(subject.matches? actual_request).to be false
112
112
  end
113
113
  end
114
114
 
115
115
  context "when the expected body has no expectation and the actual body is empty" do
116
- let(:expected_body) { Request::NullExpectation.new }
116
+ let(:expected_body) { Pact::NullExpectation.new }
117
117
  let(:actual_body) { '' }
118
118
 
119
119
  it "matches" do
120
- expect(subject.match actual_request).to be_true
120
+ expect(subject.matches? actual_request).to be true
121
121
  end
122
122
  end
123
123
 
@@ -131,7 +131,7 @@ module Pact
131
131
  let(:actual_body) { nil }
132
132
 
133
133
  it "does not match" do
134
- expect(subject.match actual_request).to be_false
134
+ expect(subject.matches? actual_request).to be false
135
135
  end
136
136
  end
137
137
 
@@ -140,7 +140,7 @@ module Pact
140
140
  let(:actual_body) { 'bar' }
141
141
 
142
142
  it "does not match" do
143
- expect(subject.match actual_request).to be_false
143
+ expect(subject.matches? actual_request).to be false
144
144
  end
145
145
  end
146
146
 
@@ -160,7 +160,7 @@ module Pact
160
160
  end
161
161
 
162
162
  it "matches" do
163
- expect(subject.match actual_request).to be_true
163
+ expect(subject.matches? actual_request).to be true
164
164
  end
165
165
  end
166
166
 
@@ -180,7 +180,7 @@ module Pact
180
180
  end
181
181
 
182
182
  it "does not match" do
183
- expect(subject.match actual_request).to be_false
183
+ expect(subject.matches? actual_request).to be false
184
184
  end
185
185
  end
186
186
 
@@ -188,7 +188,7 @@ module Pact
188
188
  let(:expected_body) do
189
189
  {
190
190
  name: 'Bob',
191
- customer_id: Term.new(matcher: /CN.*/)
191
+ customer_id: Term.new(matcher: /CN.*/, generate: 'CN789')
192
192
  }
193
193
  end
194
194
 
@@ -200,7 +200,7 @@ module Pact
200
200
  end
201
201
 
202
202
  it "matches" do
203
- expect(subject.match actual_request).to be_true
203
+ expect(subject.matches? actual_request).to be true
204
204
  end
205
205
  end
206
206
 
@@ -208,7 +208,7 @@ module Pact
208
208
  let(:expected_body) do
209
209
  {
210
210
  name: 'Bob',
211
- customer_id: Term.new(matcher: /foo/)
211
+ customer_id: Term.new(matcher: /foo/, generate: 'fooool')
212
212
  }
213
213
  end
214
214
 
@@ -220,7 +220,7 @@ module Pact
220
220
  end
221
221
 
222
222
  it "does not match" do
223
- expect(subject.match actual_request).to be_false
223
+ expect(subject.matches? actual_request).to be false
224
224
  end
225
225
  end
226
226
 
@@ -240,7 +240,7 @@ module Pact
240
240
  end
241
241
 
242
242
  it "does not match" do
243
- expect(subject.match actual_request).to be_false
243
+ expect(subject.matches? actual_request).to be false
244
244
  end
245
245
  end
246
246
  context "when the expected body contains non-matching hash where one field contains a substring of the other" do
@@ -257,7 +257,7 @@ module Pact
257
257
  end
258
258
 
259
259
  it "does not match" do
260
- expect(subject.match actual_request).to be_false
260
+ expect(subject.matches? actual_request).to be false
261
261
  end
262
262
  end
263
263
 
@@ -277,7 +277,7 @@ module Pact
277
277
  end
278
278
 
279
279
  it "does not match" do
280
- expect(subject.match actual_request).to be_true
280
+ expect(subject.matches? actual_request).to be true
281
281
  end
282
282
  end
283
283
 
@@ -286,16 +286,16 @@ module Pact
286
286
  let(:actual_query) { 'bar' }
287
287
 
288
288
  it "does not match" do
289
- expect(subject.match actual_request).to be_false
289
+ expect(subject.matches? actual_request).to be false
290
290
  end
291
291
  end
292
292
 
293
293
  context 'when there is no query expectation' do
294
- let(:expected_query) { Request::NullExpectation.new }
294
+ let(:expected_query) { Pact::NullExpectation.new }
295
295
  let(:actual_query) { 'bar' }
296
296
 
297
297
  it 'matches' do
298
- expect(subject.match actual_request).to be_true
298
+ expect(subject.matches? actual_request).to be true
299
299
  end
300
300
  end
301
301
 
@@ -304,13 +304,26 @@ module Pact
304
304
  let(:expected_body) { { thing: "123" } }
305
305
 
306
306
  it 'does not match' do
307
- expect(subject.match actual_request).to be_false
307
+ expect(subject.matches? actual_request).to be false
308
308
  end
309
309
  end
310
- end
311
- end
312
310
 
313
- describe Request::Actual do
314
- it_behaves_like "a request"
311
+ context "when unexpected keys are found in the body" do
312
+ let(:expected_body) { {a: 1} }
313
+ let(:actual_body) { {a: 1, b: 2} }
314
+ context "when allowing unexpected keys" do
315
+ let(:options) { {'allow_unexpected_keys_in_body' => true} } #From json, these will be strings
316
+ it "matches" do
317
+ expect(subject.matches? actual_request).to be true
318
+ end
319
+ end
320
+ context "when not allowing unexpected keys" do
321
+ let(:options) { {'allow_unexpected_keys_in_body' => false} }
322
+ it "does not match" do
323
+ expect(subject.matches? actual_request).to be false
324
+ end
325
+ end
326
+ end
327
+ end
315
328
  end
316
329
  end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+ require 'pact/doc/generator'
3
+ require 'fileutils'
4
+
5
+ module Pact
6
+ module Doc
7
+ describe Generator do
8
+
9
+ let(:doc_dir) { './tmp/doc' }
10
+ let(:pact_dir) { './tmp/pacts' }
11
+ let(:file_name) { "Some Consumer - Some Provider#{file_extension}" }
12
+ let(:consumer_contract_renderer) { double("ConsumerContractRenderer", :call => doc_content) }
13
+ let(:doc_content) { "doc_content" }
14
+ let(:index_content) { "index_content" }
15
+ let(:expected_doc_path) { "#{doc_dir}/#{doc_type}/#{file_name}" }
16
+ let(:expected_index_path) { "#{doc_dir}/#{doc_type}/#{index_name}#{file_extension}" }
17
+ let(:doc_type) { 'markdown' }
18
+ let(:file_extension) { ".md" }
19
+ let(:actual_file_contents) { File.read(expected_doc_path) }
20
+ let(:actual_index_contents) { File.read(expected_index_path)}
21
+ let(:index_renderer) { double("IndexRenderer", :call => index_content)}
22
+ let(:index_name) { 'README' }
23
+ let(:after_hook) { double("hook", :call => nil)}
24
+
25
+ before do
26
+ FileUtils.rm_rf doc_dir
27
+ FileUtils.rm_rf pact_dir
28
+ FileUtils.mkdir_p doc_dir
29
+ FileUtils.mkdir_p pact_dir
30
+ FileUtils.cp './spec/support/markdown_pact.json', pact_dir
31
+ end
32
+
33
+ let(:options) { { consumer_contract_renderer: consumer_contract_renderer, doc_type: doc_type, file_extension: file_extension, index_renderer: index_renderer, index_name: index_name } }
34
+
35
+ subject { Generator.new(pact_dir, doc_dir, options) }
36
+
37
+ context "when there are existing files" do
38
+ let(:existing_doc_file_path) { File.join(doc_dir, doc_type, "leftover") }
39
+
40
+ before do
41
+ FileUtils.mkdir_p File.dirname(existing_doc_file_path)
42
+ FileUtils.touch existing_doc_file_path
43
+ end
44
+
45
+ it "clears the existing files" do
46
+ expect(File.exist?(existing_doc_file_path)).to be true
47
+ subject.call
48
+ expect(File.exist?(existing_doc_file_path)).to be false
49
+ end
50
+ end
51
+
52
+
53
+ it "creates an index" do
54
+ expect(index_renderer).to receive(:call).with("Some Consumer", {"Some Provider"=>"Some Consumer - Some Provider.md"})
55
+ subject.call
56
+ expect(actual_index_contents).to eq(index_content)
57
+ end
58
+
59
+ it "creates documentation" do
60
+ subject.call
61
+ expect(actual_file_contents).to eq(doc_content)
62
+ end
63
+
64
+ context "with an after hook specified" do
65
+
66
+ subject { Generator.new(pact_dir, doc_dir, options.merge(:after => after_hook)) }
67
+
68
+ it "executes the hook" do
69
+ expect(after_hook).to receive(:call).with(pact_dir, "#{doc_dir}/#{doc_type}", instance_of(Array))
70
+ subject.call
71
+ end
72
+
73
+ it "passes in the consumer_contracts" do
74
+ expect(after_hook).to receive(:call) do | _, _, consumer_contracts |
75
+ expect(consumer_contracts.first).to be_instance_of(Pact::ConsumerContract)
76
+ end
77
+ subject.call
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+ require 'pact/doc/interaction_view_model'
3
+
4
+ module Pact
5
+ module Doc
6
+ describe InteractionViewModel do
7
+
8
+ let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/interaction_view_model.json'}
9
+
10
+ let(:interaction_with_request_with_body_and_headers) { consumer_contract.find_interaction description: "a request with a body and headers" }
11
+ let(:interaction_with_request_without_body_and_headers) { consumer_contract.find_interaction description: "a request with an empty body and empty headers" }
12
+ let(:interaction_with_response_with_body_and_headers) { consumer_contract.find_interaction description: "a response with a body and headers" }
13
+ let(:interaction_with_response_without_body_and_headers) { consumer_contract.find_interaction description: "a response with an empty body and empty headers" }
14
+
15
+
16
+ subject { InteractionViewModel.new interaction, consumer_contract}
17
+
18
+ describe "request" do
19
+
20
+ let(:interaction) { interaction_with_request_with_body_and_headers }
21
+
22
+ it "includes the method" do
23
+ expect(subject.request).to include('"method"')
24
+ expect(subject.request).to include('"get"')
25
+ end
26
+
27
+ it "includes the body" do
28
+ expect(subject.request).to include('"body"')
29
+ expect(subject.request).to include('"a body"')
30
+ end
31
+
32
+ it "includes the headers" do
33
+ expect(subject.request).to include('"headers"')
34
+ expect(subject.request).to include('"a header"')
35
+ end
36
+
37
+ it "includes the query" do
38
+ expect(subject.request).to include('"query"')
39
+ expect(subject.request).to include('"some=thing"')
40
+ end
41
+
42
+ it "includes the path" do
43
+ expect(subject.request).to include('"path"')
44
+ expect(subject.request).to include('"/path"')
45
+ end
46
+
47
+ it "renders the keys in a meaningful order" do
48
+ expect(subject.request).to match /"method".*"path".*"query".*"headers".*"body"/m
49
+ end
50
+
51
+ context "when the body hash is empty" do
52
+
53
+ let(:interaction) { interaction_with_request_without_body_and_headers }
54
+
55
+ it "includes the body" do
56
+ expect(subject.request).to include("body")
57
+ end
58
+ end
59
+ context "when the headers hash is empty" do
60
+
61
+ let(:interaction) { interaction_with_request_without_body_and_headers }
62
+
63
+ it "does not include the headers" do
64
+ expect(subject.request).to_not include("headers")
65
+ end
66
+ end
67
+
68
+ context "when a Pact::Term is present" do
69
+ let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/interaction_view_model_with_terms.json'}
70
+ let(:interaction) { consumer_contract.interactions.first }
71
+
72
+ it "uses the generated value" do
73
+ expect(subject.request).to_not include("Term")
74
+ expect(subject.request).to include("sunny")
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "response" do
80
+
81
+ let(:interaction) { interaction_with_response_with_body_and_headers }
82
+
83
+ it "includes the status" do
84
+ expect(subject.response).to include('"status"')
85
+ end
86
+
87
+ it "includes the body" do
88
+ expect(subject.response).to include('"body"')
89
+ expect(subject.response).to include('"a body"')
90
+ end
91
+ it "includes the headers" do
92
+ expect(subject.response).to include('"headers"')
93
+ expect(subject.response).to include('"a header"')
94
+ end
95
+
96
+ it "renders the keys in a meaningful order" do
97
+ expect(subject.response).to match /"status".*"headers".*"body"/m
98
+ end
99
+
100
+ context "when the body hash is empty" do
101
+
102
+ let(:interaction) { interaction_with_response_without_body_and_headers }
103
+
104
+ it "does not include the body" do
105
+ expect(subject.response).to_not include("body")
106
+ end
107
+ end
108
+
109
+ context "when the headers hash is empty" do
110
+
111
+ let(:interaction) { interaction_with_response_without_body_and_headers }
112
+
113
+ it "does not include the headers" do
114
+ expect(subject.response).to_not include("headers")
115
+ end
116
+ end
117
+
118
+ context "when a Pact::Term is present" do
119
+ let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/interaction_view_model_with_terms.json'}
120
+ let(:interaction) { consumer_contract.interactions.first }
121
+
122
+ it "uses the generated value" do
123
+ expect(subject.response).to_not include("Term")
124
+ expect(subject.response).to include("rainy")
125
+ end
126
+ end
127
+ end
128
+
129
+
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'pact/doc/markdown/consumer_contract_renderer'
3
+
4
+ module Pact
5
+ module Doc
6
+ module Markdown
7
+ describe ConsumerContractRenderer do
8
+
9
+ subject { ConsumerContractRenderer.new(consumer_contract) }
10
+ let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/markdown_pact.json' }
11
+
12
+ let(:expected_output) { File.read("./spec/support/generated_markdown.md") }
13
+
14
+ describe "#call" do
15
+ it "renders an interaction" do
16
+ expect(subject.call).to eq(expected_output)
17
+ end
18
+ end
19
+
20
+ describe ".call" do
21
+ it "renders an interaction" do
22
+ expect(ConsumerContractRenderer.call consumer_contract).to eq(expected_output)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'pact/doc/markdown/index_renderer'
3
+
4
+ module Pact
5
+ module Doc
6
+ module Markdown
7
+ describe IndexRenderer do
8
+
9
+ let(:consumer_name) { "Some Consumer" }
10
+ let(:docs) { {"Some Provider" => "Some Provider.md", "Some other provider" => "Some other provider.md"} }
11
+ let(:subject) { IndexRenderer.new(consumer_name, docs) }
12
+ let(:expected_content) { File.read('./spec/support/generated_index.md')}
13
+
14
+ describe "#call" do
15
+ it "renders the index" do
16
+ expect(subject.call).to eq expected_content
17
+ end
18
+ end
19
+
20
+ describe ".call" do
21
+ it "renders the index" do
22
+ expect(IndexRenderer.call(consumer_name, docs) ).to eq expected_content
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end