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,147 +0,0 @@
1
- require 'spec_helper'
2
- require 'pact/consumer/mock_service'
3
-
4
- module Pact::Consumer
5
-
6
- describe InteractionList do
7
- before do
8
- InteractionList.instance.clear
9
- end
10
-
11
- shared_context "unexpected requests and missed interactions" do
12
- let(:expected_call) { {request: 'blah'} }
13
- let(:unexpected_call) { {request: 'meh'} }
14
- subject {
15
- interactionList = InteractionList.instance
16
- interactionList.add expected_call
17
- interactionList.register_unexpected unexpected_call
18
- interactionList
19
- }
20
- end
21
-
22
- shared_context "no unexpected requests or missed interactions exist" do
23
- let(:expected_call) { {request: 'blah'} }
24
- let(:unexpected_call) { {request: 'meh'} }
25
- subject {
26
- interactionList = InteractionList.instance
27
- interactionList.add expected_call
28
- interactionList.register_matched expected_call
29
- interactionList
30
- }
31
- end
32
-
33
- describe "interaction_diffs" do
34
- context "when unexpected requests and missed interactions exist" do
35
- include_context "unexpected requests and missed interactions"
36
- let(:expected) {
37
- {:missing_interactions=>[{:request=>"blah"}], :unexpected_requests=>[{:request=>"meh"}]}
38
- }
39
- it "returns the unexpected requests and missed interactions" do
40
- expect(subject.interaction_diffs).to eq expected
41
- end
42
- end
43
-
44
- context "when no unexpected requests or missed interactions exist" do
45
- include_context "no unexpected requests or missed interactions exist"
46
- let(:expected) {
47
- {}
48
- }
49
- it "returns an empty hash" do
50
- expect(subject.interaction_diffs).to eq expected
51
- end
52
- end
53
- end
54
-
55
- describe "all_matched?" do
56
- context "when unexpected requests or missed interactions exist" do
57
- include_context "unexpected requests and missed interactions"
58
- it "returns false" do
59
- expect(subject.all_matched?).to be_false
60
- end
61
- end
62
- context "when unexpected requests or missed interactions do not exist" do
63
- include_context "no unexpected requests or missed interactions exist"
64
- it "returns false" do
65
- expect(subject.all_matched?).to be_true
66
- end
67
- end
68
- end
69
- end
70
-
71
- describe RequestExtractor do
72
- class TestSubject
73
- include RequestExtractor
74
- end
75
-
76
- let(:rack_env) {
77
- {
78
- "CONTENT_LENGTH" => "16",
79
- "CONTENT_TYPE" => content_type,
80
- "GATEWAY_INTERFACE" => "CGI/1.1",
81
- "PATH_INFO" => "/donuts",
82
- "QUERY_STRING" => "",
83
- "REMOTE_ADDR" => "127.0.0.1",
84
- "REMOTE_HOST" => "localhost",
85
- "REQUEST_METHOD" => "POST",
86
- "REQUEST_URI" => "http://localhost:4321/donuts",
87
- "SCRIPT_NAME" => "",
88
- "SERVER_NAME" => "localhost",
89
- "SERVER_PORT" => "4321",
90
- "SERVER_PROTOCOL" => "HTTP/1.1",
91
- "SERVER_SOFTWARE" => "WEBrick/1.3.1 (Ruby/1.9.3/2013-02-22)",
92
- "HTTP_ACCEPT" => "text/plain",
93
- "HTTP_USER_AGENT" => "Ruby",
94
- "HTTP_HOST" => "localhost:4321",
95
- "rack.version" => [1, 2 ],
96
- "rack.input" => StringIO.new(body),
97
- "rack.errors" => nil,
98
- "rack.multithread" => true,
99
- "rack.multiprocess" => false,
100
- "rack.run_once" => false,
101
- "rack.url_scheme" => "http",
102
- "HTTP_VERSION" => "HTTP/1.1",
103
- "REQUEST_PATH" => "/donuts"
104
- }
105
- }
106
-
107
- subject { TestSubject.new }
108
-
109
- let(:expected_request) {
110
- {
111
- "query" => "",
112
- "method" => "post",
113
- "body" => expected_body,
114
- "path" => "/donuts",
115
- "headers" => {
116
- "Content-Type" => content_type,
117
- "Accept" => "text/plain",
118
- "User-Agent" => "Ruby",
119
- "Host" => "localhost:4321",
120
- "Version" => "HTTP/1.1"
121
- }
122
- }
123
- }
124
-
125
- context "with a text body" do
126
- let(:content_type) { "application/x-www-form-urlencoded" }
127
- let(:body) { 'this is the body' }
128
- let(:expected_body) { body }
129
-
130
- it "extracts the body" do
131
- expect(subject.request_from(rack_env)).to eq expected_request
132
- end
133
- end
134
-
135
- context "with a json body" do
136
- let(:content_type) { "application/json" }
137
- let(:body) { '{"a" : "body" }' }
138
- let(:expected_body) { {"a" => "body"} }
139
-
140
- it "extracts the body" do
141
- expect(subject.request_from(rack_env)).to eq expected_request
142
- end
143
- end
144
-
145
-
146
- end
147
- end
@@ -1,125 +0,0 @@
1
- require 'spec_helper'
2
- require 'pact/consumer_contract'
3
-
4
- module Pact
5
- describe ConsumerContract do
6
- describe "as_json" do
7
-
8
- class MockInteraction
9
- def as_json(options ={})
10
- {:mock => "interaction"}
11
- end
12
- end
13
-
14
- before do
15
- @backup_version = Pact::VERSION
16
- Pact::VERSION = "1.0"
17
- DateTime.stub(:now).and_return(DateTime.strptime("2013-08-15T13:27:13+10:00"))
18
- end
19
-
20
- let(:service_consumer) { double('ServiceConsumer', :as_json => {:a => 'consumer'}) }
21
- let(:service_producer) { double('ServiceProducer', :as_json => {:a => 'producer'}) }
22
- let(:pact) { ConsumerContract.new({:interactions => [MockInteraction.new], :consumer => service_consumer, :producer => service_producer }) }
23
- let(:expected_as_json) { {:producer=>{:a=>"producer"}, :consumer=>{:a=>"consumer"}, :interactions=>[{:mock=>"interaction"}], :metadata=>{:pact_gem=>{:version=>"1.0"}}} }
24
-
25
- it "should return a hash representation of the Pact" do
26
- pact.as_json.should eq expected_as_json
27
- end
28
-
29
- after do
30
- Pact::VERSION = @backup_version
31
- end
32
- end
33
-
34
- describe ".from_json" do
35
- let(:loaded_pact) { ConsumerContract.from_json(string) }
36
- context "when the top level object is a ConsumerContract" do
37
- let(:string) { '{"interactions":[{"request": {"path":"/path", "method" : "get"}}], "consumer": {"name" : "Bob"} }' }
38
-
39
- it "should create a Pact" do
40
- loaded_pact.should be_instance_of ConsumerContract
41
- end
42
-
43
- it "should have interactions" do
44
- loaded_pact.interactions.should be_instance_of Array
45
- end
46
-
47
- it "should have a consumer" do
48
- loaded_pact.consumer.should be_instance_of Pact::Consumer::ServiceConsumer
49
- end
50
-
51
- it "should have a producer" do
52
- loaded_pact.producer.should be_instance_of Pact::Consumer::ServiceProducer
53
- end
54
- end
55
- end
56
-
57
- describe "find_interactions" do
58
- let(:consumer) { double('ServiceConsumer', :name => 'Consumer')}
59
- let(:producer) { double('ServiceProducer', :name => 'Producer')}
60
- let(:interaction1) { {'description' => 'a request for food'} }
61
- let(:interaction2) { {'description' => 'a request for drink'} }
62
- subject { ConsumerContract.new(:interactions => [interaction1, interaction2], :consumer => consumer, :producer => producer) }
63
- context "by description" do
64
- context "when no interactions are found" do
65
- it "returns an empty array" do
66
- expect(subject.find_interactions(:description => /blah/)).to eql []
67
- end
68
- end
69
- context "when interactions are found" do
70
- it "returns an array of the matching interactions" do
71
- expect(subject.find_interactions(:description => /request/)).to eql [interaction1, interaction2]
72
- end
73
- end
74
- end
75
- end
76
- describe "find_interaction" do
77
- let(:consumer) { double('ServiceConsumer', :name => 'Consumer')}
78
- let(:producer) { double('ServiceProducer', :name => 'Producer')}
79
- let(:interaction1) { {'description' => 'a request for food'} }
80
- let(:interaction2) { {'description' => 'a request for drink'} }
81
- subject { ConsumerContract.new(:interactions => [interaction1, interaction2], :consumer => consumer, :producer => producer) }
82
- context "by description" do
83
- context "when a match is found" do
84
- it "returns the interaction" do
85
- expect(subject.find_interaction :description => /request.*food/).to eql interaction1
86
- end
87
- end
88
- context "when more than one match is found" do
89
- it "raises an error" do
90
- expect{ subject.find_interaction(:description => /request/) }.to raise_error "Found more than 1 interaction matching {:description=>/request/} in pact file between Consumer and Producer."
91
- end
92
- end
93
- context "when a match is not found" do
94
- it "raises an error" do
95
- expect{ subject.find_interaction(:description => /blah/) }.to raise_error "Could not find interaction matching {:description=>/blah/} in pact file between Consumer and Producer."
96
- end
97
- end
98
- end
99
- end
100
- describe "update_pactfile" do
101
- let(:pacts_dir) { Pathname.new("./tmp/pactfiles") }
102
- let(:expected_pact_path) { pacts_dir + "test_consumer-test_service.json" }
103
- let(:expected_pact_string) { 'the_json' }
104
- let(:consumer) { Pact::Consumer::ServiceConsumer.new(:name => 'test_consumer')}
105
- let(:producer) { Pact::Consumer::ServiceProducer.new(:name => 'test_service')}
106
- let(:interactions) { [double("interaction", as_json: "something")]}
107
- subject { ConsumerContract.new(:consumer => consumer, :producer => producer, :interactions => interactions) }
108
- before do
109
- Pact.configuration.stub(:pact_dir).and_return(Pathname.new("./tmp/pactfiles"))
110
- FileUtils.rm_rf pacts_dir
111
- FileUtils.mkdir_p pacts_dir
112
- JSON.should_receive(:pretty_generate).with(instance_of(Pact::ConsumerContract)).and_return(expected_pact_string)
113
- subject.update_pactfile
114
- end
115
-
116
- it "should write to a file specified by the consumer and producer name" do
117
- File.exist?(expected_pact_path).should be_true
118
- end
119
-
120
- it "should write the interactions to the file" do
121
- File.read(expected_pact_path).should eql expected_pact_string
122
- end
123
- end
124
- end
125
- end
@@ -1,101 +0,0 @@
1
- require 'spec_helper'
2
- require 'pact/producer/configuration_dsl'
3
-
4
- module Pact::Producer
5
- describe ConfigurationDSL do
6
-
7
- class MockConfig
8
- include ConfigurationDSL
9
- end
10
-
11
- describe "producer" do
12
- let(:mock_config) { MockConfig.new }
13
- context "when a producer is configured" do
14
- before do
15
- mock_config.producer do
16
- name "Fred"
17
- app { "An app" }
18
- end
19
- end
20
- it "should allow configuration of the name" do
21
- expect(mock_config.producer.name).to eql "Fred"
22
- end
23
- it "should allow configuration of the test app" do
24
- expect(mock_config.producer.app).to eql "An app"
25
- end
26
- end
27
- context "when a producer is not configured" do
28
- it "raises an error" do
29
- expect{ mock_config.producer }.to raise_error(/Please configure your producer/)
30
- end
31
- end
32
- end
33
-
34
-
35
- module ConfigurationDSL
36
-
37
- describe ProducerDSL do
38
-
39
- describe "initialize" do
40
-
41
- context "with an object instead of a block" do
42
- subject do
43
- ProducerDSL.new do
44
- name nil
45
- app 'blah'
46
- end
47
- end
48
- it "raises an error" do
49
- expect{ subject }.to raise_error
50
- end
51
- end
52
-
53
-
54
- end
55
- describe "validate" do
56
- context "when no name is provided" do
57
- subject do
58
- ProducerDSL.new do
59
- app { Object.new }
60
- end
61
- end
62
- it "raises an error" do
63
- expect{ subject.validate}.to raise_error("Please provide a name for the Producer")
64
- end
65
- end
66
- context "when nil name is provided" do
67
- subject do
68
- ProducerDSL.new do
69
- name nil
70
- app { Object.new }
71
- end
72
- end
73
- it "raises an error" do
74
- expect{ subject.validate}.to raise_error("Please provide a name for the Producer")
75
- end
76
- end
77
- context "when no app is provided" do
78
- subject do
79
- ProducerDSL.new do
80
- name 'Blah'
81
- end
82
- end
83
- it "raises an error" do
84
- expect{ subject.validate }.to raise_error("Please configure an app for the Producer")
85
- end
86
- end
87
- end
88
- end
89
-
90
- describe ProducerConfig do
91
- describe "app" do
92
- subject { ProducerConfig.new("blah") { Object.new } }
93
- it "should execute the app_block each time" do
94
- expect(subject.app.object_id).to_not equal(subject.app.object_id)
95
- end
96
- end
97
- end
98
-
99
- end
100
- end
101
- end
@@ -1,103 +0,0 @@
1
- require 'spec_helper'
2
- require 'pact/producer/producer_state'
3
-
4
- module Pact
5
- module Producer
6
-
7
- describe 'global ProducerState' do
8
-
9
- MESSAGES = []
10
-
11
- Pact.producer_state :no_alligators do
12
- set_up do
13
- MESSAGES << 'set_up'
14
- end
15
- tear_down do
16
- MESSAGES << 'tear_down'
17
- end
18
- end
19
-
20
- Pact.producer_state 'some alligators' do
21
- end
22
-
23
- before do
24
- MESSAGES.clear
25
- end
26
-
27
- subject { ProducerState.get('no_alligators') }
28
-
29
- describe 'set_up' do
30
- it 'should call the block passed to set_up' do
31
- subject.set_up
32
- MESSAGES.should eq ['set_up']
33
- end
34
- end
35
-
36
- describe 'tear_down' do
37
- it 'should call the block passed to set_up' do
38
- subject.tear_down
39
- MESSAGES.should eq ['tear_down']
40
- end
41
- end
42
-
43
- describe '.get' do
44
- context 'when the name is a matching symbol' do
45
- it 'will return the ProducerState' do
46
- ProducerState.get('no_alligators').should_not be_nil
47
- end
48
- end
49
- context 'when the name is a matching string' do
50
- it 'will return the ProducerState' do
51
- ProducerState.get('some alligators').should_not be_nil
52
- end
53
- end
54
- end
55
- end
56
-
57
-
58
- describe 'namespaced ProducerStates' do
59
-
60
- NAMESPACED_MESSAGES = []
61
-
62
- Pact.with_consumer 'a consumer' do
63
- producer_state 'the weather is sunny' do
64
- set_up do
65
- NAMESPACED_MESSAGES << 'sunny!'
66
- end
67
- end
68
- end
69
-
70
- Pact.producer_state 'the weather is cloudy' do
71
- set_up do
72
- NAMESPACED_MESSAGES << 'cloudy :('
73
- end
74
- end
75
-
76
- before do
77
- NAMESPACED_MESSAGES.clear
78
- end
79
-
80
- describe '.get' do
81
- context 'for a consumer' do
82
- it 'has a namespaced name' do
83
- ProducerState.get('the weather is sunny', :for => 'a consumer').should_not be_nil
84
- end
85
-
86
- it 'falls back to a global state of the same name if one is not found for the specified consumer' do
87
- ProducerState.get('the weather is cloudy', :for => 'a consumer').should_not be_nil
88
- end
89
- end
90
-
91
- end
92
-
93
- describe 'set_up' do
94
- context 'for a consumer' do
95
- it 'runs its own setup' do
96
- ProducerState.get('the weather is sunny', :for => 'a consumer').set_up
97
- NAMESPACED_MESSAGES.should eq ['sunny!']
98
- end
99
- end
100
- end
101
- end
102
- end
103
- end
@@ -1,48 +0,0 @@
1
- require 'pact/producer/rspec'
2
-
3
- describe "the match_term matcher" do
4
-
5
- it 'does not match a hash to an array' do
6
- expect({}).to_not match_term([])
7
- end
8
-
9
- it 'does not match an array to a hash' do
10
- expect([]).to_not match_term({})
11
- end
12
-
13
- it 'matches regular expressions' do
14
- expect('blah').to match_term(/[a-z]*/)
15
- end
16
-
17
- it 'matches pact terms' do
18
- expect('wootle').to match_term Pact::Term.new(generate:'wootle', matcher:/woot../)
19
- end
20
-
21
- it 'matches all elements of arrays' do
22
- expect(['one', 'two', ['three']]).to match_term [/one/, 'two', [Pact::Term.new(generate:'three', matcher:/thr../)]]
23
- end
24
-
25
- it 'matches all values of hashes' do
26
- expect({1 => 'one', 2 => 2, 3 => 'three'}).to match_term({1 => /one/, 2 => 2, 3 => Pact::Term.new(generate:'three', matcher:/thr../)})
27
- end
28
-
29
- it 'matches all other objects using ==' do
30
- expect('wootle').to match_term 'wootle'
31
- end
32
-
33
- # Note: because a consumer specifies only the keys it cares about, the pact ignores keys that are returned
34
- # by the producer, but not are not specified in the pact. This means that any hash will match an
35
- # expected empty hash, because there is currently no way for a consumer to expect an absence of keys.
36
- it 'is confused by an empty hash' do
37
- expect({:hello => 'everyone'}).to match_term({})
38
- end
39
-
40
- it 'should not be confused by an empty array' do
41
- expect(['blah']).to_not match_term([])
42
- end
43
-
44
- it "should allow matches on an array where each item in the array only contains a subset of the actual" do
45
- expect([{name: 'Fred', age: 12}, {name: 'John', age: 13}]).to match_term([{name: 'Fred'}, {name: 'John'}])
46
- end
47
-
48
- end
@@ -1,64 +0,0 @@
1
- require 'spec_helper'
2
- require 'pact/verification_task'
3
-
4
- module Pact
5
- describe VerificationTask do
6
- before :all do
7
- @support_file = 'some_file.rb'
8
- @pact_uri = 'http://example.org/pact.json'
9
- @task_name = 'pact:verify:pact_rake_spec'
10
- @consumer = 'some-consumer'
11
-
12
- VerificationTask.new(:pact_rake_spec) do | pact |
13
- pact.uri @pact_uri, support_file: @support_file, consumer: @consumer
14
- end
15
- end
16
-
17
- describe '.initialize' do
18
-
19
- it 'creates the tasks' do
20
- Rake::Task.tasks.should include_task @task_name
21
- end
22
-
23
- end
24
-
25
- describe 'execute' do
26
-
27
- let(:consumer_contract) { [ uri: @pact_uri, support_file: @support_file, consumer: @consumer] }
28
-
29
- it 'verifies the pacts using PactSpecRunner' do
30
- Producer::PactSpecRunner.should_receive(:run).with(consumer_contract).and_return(0)
31
- Rake::Task[@task_name].execute
32
- end
33
-
34
- context 'when all specs pass' do
35
-
36
- before do
37
- Producer::PactSpecRunner.stub(:run).and_return(0)
38
- end
39
-
40
- it 'does not raise an exception' do
41
- Rake::Task[@task_name].execute
42
- end
43
- end
44
-
45
- context 'when one or more specs fail' do
46
-
47
- before do
48
- Producer::PactSpecRunner.stub(:run).and_return(1)
49
- end
50
-
51
- it 'raises an exception' do
52
- expect { Rake::Task[@task_name].execute }.to raise_error RuntimeError
53
- end
54
-
55
- end
56
- end
57
- end
58
- end
59
-
60
- RSpec::Matchers.define :include_task do |expected|
61
- match do |actual|
62
- actual.any? { |task| task.name == expected }
63
- end
64
- end
@@ -1,41 +0,0 @@
1
- require 'json'
2
-
3
- module Pact
4
- module Test
5
- class TestApp
6
- def call env
7
- if env['PATH_INFO'] == '/weather'
8
- [200, {'Content-Type' => 'application/json'}, [{message: WEATHER[:current_state]}.to_json]]
9
- else
10
- raise "unexpected path #{env['PATH_INFO']}!!!"
11
- end
12
- end
13
- end
14
-
15
- Pact.configure do | config |
16
- config.producer do
17
- name "Some Producer"
18
- app { TestApp.new }
19
- end
20
- end
21
-
22
-
23
- #one with a top level consumer
24
- Pact.with_consumer 'some-test-consumer' do
25
- producer_state "the weather is sunny" do
26
- set_up do
27
- WEATHER ||= {}
28
- WEATHER[:current_state] = 'sunny'
29
- end
30
- end
31
- end
32
-
33
- #one without a top level consumer
34
- Pact.producer_state "the weather is cloudy" do
35
- set_up do
36
- WEATHER ||= {}
37
- WEATHER[:current_state] = 'cloudy'
38
- end
39
- end
40
- end
41
- end