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
@@ -5,7 +5,7 @@ Could use:
5
5
  eg
6
6
  ex
7
7
 
8
- my_producer.
8
+ my_provider.
9
9
  given("a thing exists").
10
10
  upon_receiving("a request for a thing").with({:method => 'get', :path => '/thing'})
11
11
  will_respond_with({:body => {
@@ -29,8 +29,24 @@ Need a way to specify a literal empty hash, rather than a hash that matches anyt
29
29
  {:something => actual({}) }
30
30
  {:something => empty_hash }
31
31
 
32
- Slightly unintuitive behaviour: {} matches any hash, but [] only matches an empty array (or does now we've changed the code). Should [] match any array? How do we then specify an empty array?
32
+ # Slightly unintuitive behaviour: {} matches any hash, but [] only matches an empty array (or does now we've changed the code). Should [] match any array? How do we then specify an empty array?
33
33
 
34
34
  {:something => literal([]) }
35
35
  {:something => actual([]) }
36
36
  {:something => empty_array }
37
+
38
+
39
+ Pact.build do
40
+ {
41
+ status: 200,
42
+ headers: exactly({
43
+
44
+ }),
45
+ body: including({
46
+ age: literal('12'),
47
+ phoneNumber: example("0415 134 234", /\d{4} \d{3} \d{3}/),
48
+ favouriteColors:
49
+ })
50
+ }
51
+
52
+ end
@@ -1,30 +1,33 @@
1
1
  require 'net/http'
2
2
  require 'pact/consumer'
3
3
  require 'pact/consumer/rspec'
4
-
4
+ load 'pact/consumer/world.rb'
5
5
 
6
6
  describe "A service consumer side of a pact", :pact => true do
7
7
 
8
- it "goes a little something like this" do
8
+ before do
9
9
  Pact.clear_configuration
10
+ Pact.clear_consumer_world
11
+ end
10
12
 
11
- Pact.configure do | config |
12
- config.consumer do
13
- name "Consumer"
14
- end
15
- end
13
+ describe "blah" do
14
+ describe "thing" do
15
+
16
+ it "goes a little something like this" do
16
17
 
17
- Pact.with_producer "Alice Service" do
18
- mock_service :alice_service do
19
- verify true
20
- port 1234
18
+ Pact.service_consumer "Consumer" do
19
+ has_pact_with "Alice Service" do
20
+ mock_service :alice_service do
21
+ verify true
22
+ port 1234
23
+ end
21
24
  end
22
- end
23
25
 
24
- Pact.with_producer "Bob" do
25
- mock_service :bob_service do
26
- verify false
27
- port 4321
26
+ has_pact_with "Bob" do
27
+ mock_service :bob_service do
28
+ verify false
29
+ port 4321
30
+ end
28
31
  end
29
32
  end
30
33
 
@@ -44,7 +47,7 @@ describe "A service consumer side of a pact", :pact => true do
44
47
  method: :post,
45
48
  path: '/donuts',
46
49
  body: {
47
- "name" => Pact::Term.new(matcher: /Bob/)
50
+ "name" => Pact::Term.new(matcher: /Bob/, generate: 'Bob')
48
51
  },
49
52
  headers: {'Accept' => 'text/plain', "Content-Type" => 'application/json'}
50
53
  }).
@@ -61,7 +64,7 @@ describe "A service consumer side of a pact", :pact => true do
61
64
  status: 200,
62
65
  body: /deleted/
63
66
  })
64
- bob_service.
67
+ bob_service.
65
68
  upon_receiving('an update alligators request').with({
66
69
  method: :put,
67
70
  path: '/alligators',
@@ -101,46 +104,11 @@ describe "A service consumer side of a pact", :pact => true do
101
104
 
102
105
  expect(bob_post_response.code).to eql '200'
103
106
  expect(bob_post_response.body).to eql([{"name" => "Roger", "age" => 20}].to_json)
104
- expect{ bob_service.verify('goes a little something like this') }.to raise_error /do not match/
105
- end
106
107
 
107
- context "with a producer state" do
108
- before do
109
- Pact.clear_configuration
110
-
111
- Pact.configure do | config |
112
- config.consumer do
113
- name "Consumer"
114
- end
115
- end
116
-
117
- Pact.with_producer "Zebra Service" do
118
- mock_service :zebra_service do
119
- verify false
120
- port 1235
121
- end
122
- end
123
- end
124
-
125
- it "goes like this" do
126
- zebra_service.
127
- given(:the_zebras_are_here).
128
- upon_receiving("a retrieve Mallory request").with({
129
- method: :get,
130
- path: '/mallory',
131
- headers: {'Accept' => 'text/html'}
132
- }).
133
- will_respond_with({
134
- status: 200,
135
- headers: { 'Content-Type' => 'text/html' },
136
- body: Pact::Term.new(matcher: /Mallory/, generate: 'That is some good Mallory.')
137
- })
138
-
139
- interactions = Pact::ConsumerContract.from_json(File.read(zebra_service.consumer_contract.pactfile_path)).interactions
140
- interactions.first.producer_state.should eq("the_zebras_are_here")
141
- sleep 1
142
- end
108
+ expect{ bob_service.verify('goes a little something like this') }.to raise_error /do not match/
143
109
  end
144
110
 
145
111
  end
112
+ end
113
+ end
146
114
 
@@ -1,9 +1,10 @@
1
- require 'pact/producer/rspec'
1
+ require 'spec_helper'
2
+ require 'pact/provider/rspec'
2
3
  require 'pact/consumer_contract'
3
- require 'features/producer_states/zebras'
4
+ require 'features/provider_states/zebras'
4
5
 
5
6
 
6
- module Pact::Producer
7
+ module Pact::Provider
7
8
 
8
9
  describe "A service production side of a pact" do
9
10
 
@@ -40,6 +41,7 @@ module Pact::Producer
40
41
  pact = Pact::ConsumerContract.from_json <<-EOS
41
42
  {
42
43
  "consumer" : { "name" : "a consumer"},
44
+ "provider" : { "name" : "a provider"},
43
45
  "interactions" : [
44
46
  {
45
47
  "description": "donut creation request",
@@ -73,12 +75,9 @@ module Pact::Producer
73
75
  }
74
76
  EOS
75
77
 
76
- before do
77
- Pact.configure do |config|
78
- config.producer do
79
- name "My Producer"
80
- app { ServiceUnderTest.new }
81
- end
78
+ before :all do
79
+ Pact.service_provider "My Provider" do
80
+ app { ServiceUnderTest.new }
82
81
  end
83
82
  end
84
83
 
@@ -86,12 +85,13 @@ module Pact::Producer
86
85
 
87
86
  end
88
87
 
89
- describe "with a producer_state" do
88
+ describe "with a provider_state" do
90
89
 
91
90
  context "that is a symbol" do
92
91
  consumer_contract = Pact::ConsumerContract.from_json <<-EOS
93
92
  {
94
93
  "consumer" : { "name" : "the-wild-beast-store"},
94
+ "provider" : { "name" : "provider"},
95
95
  "interactions" : [
96
96
  {
97
97
  "description": "donut creation request",
@@ -103,18 +103,15 @@ module Pact::Producer
103
103
  "body": {"names": ["Jason", "Sarah"]},
104
104
  "status": 200
105
105
  },
106
- "producer_state" : "the_zebras_are_here"
106
+ "provider_state" : "the_zebras_are_here"
107
107
  }
108
108
  ]
109
109
  }
110
110
  EOS
111
111
 
112
- before do
113
- Pact.configure do |config|
114
- config.producer do
115
- name "My Producer"
116
- app { ServiceUnderTestWithFixture.new }
117
- end
112
+ before :all do
113
+ Pact.service_provider "My Provider" do
114
+ app { ServiceUnderTestWithFixture.new }
118
115
  end
119
116
  end
120
117
 
@@ -126,6 +123,7 @@ module Pact::Producer
126
123
  consumer_contract = Pact::ConsumerContract.from_json <<-EOS
127
124
  {
128
125
  "consumer" : { "name" : "some consumer"},
126
+ "provider" : { "name" : "provider"},
129
127
  "interactions" : [
130
128
  {
131
129
  "description": "donut creation request",
@@ -137,18 +135,15 @@ module Pact::Producer
137
135
  "body": {"names": ["Mark", "Gertrude"]},
138
136
  "status": 200
139
137
  },
140
- "producer_state" : "some other zebras are here"
138
+ "provider_state" : "some other zebras are here"
141
139
  }
142
140
  ]
143
141
  }
144
142
  EOS
145
143
 
146
- before do
147
- Pact.configure do |config|
148
- config.producer do
149
- name "ServiceUnderTestWithFixture"
150
- app { ServiceUnderTestWithFixture.new }
151
- end
144
+ before :all do
145
+ Pact.service_provider "ServiceUnderTestWithFixture" do
146
+ app { ServiceUnderTestWithFixture.new }
152
147
  end
153
148
  end
154
149
 
@@ -1,9 +1,9 @@
1
1
  require 'json'
2
2
  require 'fileutils'
3
3
 
4
- Pact.with_consumer 'the-wild-beast-store' do
4
+ Pact.provider_states_for 'the-wild-beast-store' do
5
5
 
6
- producer_state :the_zebras_are_here do
6
+ provider_state :the_zebras_are_here do
7
7
  set_up do
8
8
  FileUtils.mkdir_p 'tmp'
9
9
  some_data = [{'name' => 'Jason'},{'name' => 'Sarah'}]
@@ -16,7 +16,7 @@ Pact.with_consumer 'the-wild-beast-store' do
16
16
  end
17
17
  end
18
18
 
19
- Pact.producer_state "some other zebras are here" do
19
+ Pact.provider_state "some other zebras are here" do
20
20
  set_up do
21
21
  some_data = [{'name' => 'Mark'},{'name' => 'Gertrude'}]
22
22
  File.open("tmp/a_mock_database.json", "w") { |file| file << some_data.to_json }
@@ -0,0 +1,212 @@
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
+
@@ -0,0 +1,66 @@
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
@@ -0,0 +1,25 @@
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
@@ -0,0 +1,47 @@
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