pact 1.1.0.rc2 → 1.1.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. data/.gitignore +0 -1
  2. data/CHANGELOG.md +46 -1
  3. data/Gemfile.lock +6 -4
  4. data/README.md +40 -186
  5. data/Rakefile +1 -1
  6. data/documentation/README.md +10 -0
  7. data/documentation/best-practices.md +33 -0
  8. data/documentation/configuration.md +166 -0
  9. data/documentation/diff_formatter_embedded.png +0 -0
  10. data/documentation/diff_formatter_list.png +0 -0
  11. data/documentation/diff_formatter_unix.png +0 -0
  12. data/documentation/faq.md +36 -6
  13. data/documentation/provider-states.md +173 -0
  14. data/documentation/raq.md +4 -4
  15. data/documentation/terminology.md +2 -2
  16. data/example/animal-service/Gemfile.lock +6 -9
  17. data/example/animal-service/Rakefile +2 -0
  18. data/example/animal-service/db/animal_db.sqlite3 +0 -0
  19. data/example/animal-service/lib/animal_service/animal_repository.rb +1 -5
  20. data/example/animal-service/lib/animal_service/api.rb +1 -1
  21. data/example/animal-service/spec/service_consumers/pact_helper.rb +7 -10
  22. data/example/animal-service/spec/service_consumers/provider_states_for_zoo_app.rb +5 -1
  23. data/example/zoo-app/Gemfile.lock +6 -9
  24. data/example/zoo-app/Rakefile +5 -0
  25. data/example/zoo-app/doc/markdown/README.md +3 -0
  26. data/example/zoo-app/doc/markdown/Zoo App - Animal Service.md +75 -0
  27. data/example/zoo-app/lib/zoo_app/animal_service_client.rb +2 -2
  28. data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +1 -1
  29. data/example/zoo-app/spec/service_providers/animal_service_client_spec.rb +29 -34
  30. data/example/zoo-app/spec/service_providers/pact_helper.rb +4 -0
  31. data/lib/pact/configuration.rb +49 -1
  32. data/lib/pact/consumer/configuration.rb +4 -172
  33. data/lib/pact/consumer/configuration/configuration_extensions.rb +15 -0
  34. data/lib/pact/consumer/configuration/dsl.rb +12 -0
  35. data/lib/pact/consumer/configuration/mock_service.rb +89 -0
  36. data/lib/pact/consumer/configuration/service_consumer.rb +51 -0
  37. data/lib/pact/consumer/configuration/service_provider.rb +40 -0
  38. data/lib/pact/consumer/mock_service/interaction_mismatch.rb +3 -3
  39. data/lib/pact/consumer/mock_service/interaction_post.rb +2 -2
  40. data/lib/pact/consumer/mock_service/interaction_replay.rb +3 -4
  41. data/lib/pact/consumer/mock_service/verification_get.rb +32 -13
  42. data/lib/pact/consumer/rspec.rb +2 -4
  43. data/lib/pact/consumer/spec_hooks.rb +3 -1
  44. data/lib/pact/consumer_contract/consumer_contract.rb +1 -1
  45. data/lib/pact/consumer_contract/interaction.rb +1 -1
  46. data/lib/pact/doc/doc_file.rb +40 -0
  47. data/lib/pact/doc/generate.rb +11 -0
  48. data/lib/pact/doc/generator.rb +81 -0
  49. data/lib/pact/doc/interaction_view_model.rb +113 -0
  50. data/lib/pact/doc/markdown/generator.rb +26 -0
  51. data/lib/pact/doc/markdown/index_renderer.rb +41 -0
  52. data/lib/pact/doc/markdown/interaction.erb +14 -0
  53. data/lib/pact/doc/markdown/interaction_renderer.rb +38 -0
  54. data/lib/pact/doc/markdown/interactions_renderer.rb +56 -0
  55. data/lib/pact/doc/sort_interactions.rb +17 -0
  56. data/lib/pact/matchers/actual_type.rb +16 -0
  57. data/lib/pact/matchers/base_difference.rb +37 -0
  58. data/lib/pact/matchers/differ.rb +150 -0
  59. data/lib/pact/matchers/difference.rb +5 -30
  60. data/lib/pact/matchers/difference_indicator.rb +26 -0
  61. data/lib/pact/matchers/embedded_diff_formatter.rb +62 -0
  62. data/lib/pact/matchers/expected_type.rb +35 -0
  63. data/lib/pact/matchers/index_not_found.rb +3 -12
  64. data/lib/pact/matchers/{diff_decorator.rb → list_diff_formatter.rb} +28 -11
  65. data/lib/pact/matchers/matchers.rb +35 -39
  66. data/lib/pact/matchers/no_diff_indicator.rb +18 -0
  67. data/lib/pact/matchers/regexp_difference.rb +13 -0
  68. data/lib/pact/matchers/type_difference.rb +16 -0
  69. data/lib/pact/matchers/unexpected_index.rb +3 -13
  70. data/lib/pact/matchers/unexpected_key.rb +3 -12
  71. data/lib/pact/matchers/{plus_minus_diff_decorator.rb → unix_diff_formatter.rb} +22 -7
  72. data/lib/pact/provider/configuration.rb +5 -178
  73. data/lib/pact/provider/configuration/configuration_extension.rb +58 -0
  74. data/lib/pact/provider/configuration/dsl.rb +13 -0
  75. data/lib/pact/provider/configuration/pact_verification.rb +46 -0
  76. data/lib/pact/provider/configuration/service_provider_config.rb +16 -0
  77. data/lib/pact/provider/configuration/service_provider_dsl.rb +54 -0
  78. data/lib/pact/provider/matchers.rb +21 -13
  79. data/lib/pact/provider/matchers/messages.rb +43 -0
  80. data/lib/pact/provider/pact_spec_runner.rb +8 -0
  81. data/lib/pact/provider/rspec.rb +1 -1
  82. data/lib/pact/provider/rspec/formatter.rb +9 -7
  83. data/lib/pact/{consumer_contract → shared}/active_support_support.rb +4 -0
  84. data/lib/pact/shared/jruby_support.rb +18 -0
  85. data/lib/pact/shared/key_not_found.rb +3 -16
  86. data/lib/pact/shared/request.rb +5 -5
  87. data/lib/pact/term.rb +2 -2
  88. data/lib/pact/version.rb +1 -1
  89. data/pact.gemspec +2 -2
  90. data/spec/integration/pact/provider_configuration_spec.rb +2 -1
  91. data/spec/lib/pact/configuration_spec.rb +73 -0
  92. data/spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb +21 -3
  93. data/spec/lib/pact/consumer/mock_service/verification_get_spec.rb +134 -0
  94. data/spec/lib/pact/consumer/request_spec.rb +1 -1
  95. data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +1 -1
  96. data/spec/lib/pact/doc/generator_spec.rb +69 -0
  97. data/spec/lib/pact/doc/interaction_view_model_spec.rb +112 -0
  98. data/spec/lib/pact/doc/markdown/index_renderer_spec.rb +29 -0
  99. data/spec/lib/pact/doc/markdown/interactions_renderer_spec.rb +29 -0
  100. data/spec/lib/pact/matchers/differ_spec.rb +214 -0
  101. data/spec/lib/pact/matchers/difference_spec.rb +2 -12
  102. data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +77 -0
  103. data/spec/lib/pact/matchers/index_not_found_spec.rb +21 -0
  104. data/spec/lib/pact/matchers/list_diff_formatter_spec.rb +114 -0
  105. data/spec/lib/pact/matchers/matchers_spec.rb +38 -22
  106. data/spec/lib/pact/matchers/regexp_difference_spec.rb +20 -0
  107. data/spec/lib/pact/matchers/type_difference_spec.rb +34 -0
  108. data/spec/lib/pact/matchers/unexpected_index_spec.rb +20 -0
  109. data/spec/lib/pact/matchers/unexpected_key_spec.rb +20 -0
  110. data/spec/lib/pact/matchers/{plus_minus_diff_decorator_spec.rb → unix_diff_formatter_spec.rb} +35 -6
  111. data/spec/lib/pact/provider/configuration/configuration_extension_spec.rb +30 -0
  112. data/spec/lib/pact/provider/configuration/pact_verification_spec.rb +43 -0
  113. data/spec/lib/pact/provider/configuration/service_provider_config_spec.rb +21 -0
  114. data/spec/lib/pact/provider/configuration/service_provider_dsl_spec.rb +92 -0
  115. data/spec/lib/pact/provider/configuration_spec.rb +7 -150
  116. data/spec/lib/pact/provider/matchers/messages_spec.rb +104 -0
  117. data/spec/lib/pact/provider/rspec/formatter_spec.rb +56 -0
  118. data/spec/lib/pact/shared/key_not_found_spec.rb +20 -0
  119. data/spec/lib/pact/shared/request_spec.rb +28 -0
  120. data/spec/spec_helper.rb +3 -0
  121. data/spec/standalone/consumer_fail_test.rb +54 -0
  122. data/spec/standalone/consumer_pass_test.rb +50 -0
  123. data/spec/support/generated_index.md +4 -0
  124. data/spec/support/generated_markdown.md +55 -0
  125. data/spec/support/interaction_view_model.json +63 -0
  126. data/spec/support/markdown_pact.json +48 -0
  127. data/spec/support/pact_helper.rb +2 -1
  128. data/spec/support/spec_support.rb +7 -0
  129. data/spec/support/test_app_fail.json +11 -2
  130. data/tasks/pact-test.rake +9 -0
  131. metadata +113 -20
  132. data/example/animal-service/db/animals_db.sqlite3 +0 -0
  133. data/lib/pact/consumer/rspec/full_example_description.rb +0 -28
  134. data/lib/pact/matchers/nested_json_diff_decorator.rb +0 -53
  135. data/spec/lib/pact/matchers/diff_decorator_spec.rb +0 -80
  136. data/spec/lib/pact/matchers/nested_json_diff_decorator_spec.rb +0 -48
data/.gitignore CHANGED
@@ -6,7 +6,6 @@
6
6
  InstalledFiles
7
7
  _yardoc
8
8
  coverage
9
- doc/
10
9
  lib/bundler/man
11
10
  pkg
12
11
  rdoc
data/CHANGELOG.md CHANGED
@@ -1,6 +1,51 @@
1
1
  Do this to generate your change history
2
2
 
3
- git log --date=relative --pretty=format:' * %h - %s (%an, %ad)'
3
+ git log --pretty=format:' * %h - %s (%an, %ad)'
4
+
5
+ ### 1.1.0.rc3 (28 April 2014)
6
+
7
+ * 41fa409 - Cleaned up consumer after spec failure message (Beth, Sun Apr 27 22:18:03 2014 +1000)
8
+ * 8593fa9 - Updated zoo-app example (Beth, Sun Apr 27 20:54:51 2014 +1000)
9
+ * 716e3a8 - Added standalone consumer spec and spec for VerificationGet (Beth, Thu Apr 24 10:15:17 2014 +1000)
10
+ * c0f9bc6 - Copied RSpec::Expectations::Differ to Pact::Matchers::Differ - safer than trying to override behaviour (Beth, Thu Apr 24 09:17:58 2014 +
11
+ * 0eeb032 - Changing default diff_formatter to unix (Beth, Thu Apr 24 08:19:15 2014 +1000)
12
+ * ace5d4d - Update README.md (bethesque, Wed Apr 23 20:59:24 2014 +1000)
13
+ * 24efef6 - Update configuration.md (bethesque, Wed Apr 23 20:51:00 2014 +1000)
14
+ * 2d862b7 - Update best-practices.md (bethesque, Wed Apr 23 07:33:01 2014 +1000)
15
+ * ff8dfd2 - Updated doco (Beth, Tue Apr 22 21:45:17 2014 +1000)
16
+ * 88e4572 - Moving best practices into its own file (Beth, Tue Apr 22 21:28:36 2014 +1000)
17
+ * 5a3b92c - Moving provider state documentation out of main README into it's own file. (Beth, Tue Apr 22 19:59:48 2014 +1000)
18
+ * 1d568c4 - Updated configuration documentation (Beth, Tue Apr 22 13:06:47 2014 +1000)
19
+ * be1412e - Added configuration documentation (Beth, Tue Apr 22 13:04:33 2014 +1000)
20
+ * 9f9d178 - Added HAL raq (Beth, Tue Apr 22 12:51:42 2014 +1000)
21
+ * d9b6479 - Renamed ListOfPathsFormatter to ListDiffFormatter (Beth, Tue Apr 22 12:48:57 2014 +1000)
22
+ * 6b82402 - Renamed NestedJsonDiffFormatter to EmbeddedDiffFormatter (Beth, Tue Apr 22 12:45:50 2014 +1000)
23
+ * def8afd - Merge branch 'master' into release-1.1.0 (bethesque, Tue Apr 22 09:13:41 2014 +1000)
24
+ * 789a471 - Added generated docs to zoo-app (bethesque, Tue Apr 15 17:20:08 2014 +1000)
25
+ * f5da7ab - Improved header match failure message (bethesque, Tue Apr 15 09:39:12 2014 +1000)
26
+ * 1179489 - Stopped RSpec turning failure message lines that should be white to red (bethesque, Mon Apr 14 21:41:55 2014 +1000)
27
+ * ddad510 - Added type and regexp matching output to ListOfPathsFormatter (bethesque, Mon Apr 14 13:43:08 2014 +1000)
28
+ * b007248 - Added class based matching output to plus_and_minus diff formatter (bethesque, Sat Apr 12 21:20:43 2014 +1000)
29
+ * f7910a1 - Swapped colored for term-ansicolor, as the colored mixins clash with other gems (bethesque, Sat Apr 12 20:37:57 2014 +1000)
30
+ * 93bfbdb - Fixing failing tests caused by JRuby inserting a blank line between the braces of an empty hash. Moved ActiveSupportSupport into shared
31
+ * da16f95 - Added after hook to allow customisation of Doc::Generator (bethesque, Sat Apr 12 18:46:04 2014 +1000)
32
+ * 85a6fe3 - Breaking up configuration files into separate files (bethesque, Sat Apr 12 11:21:56 2014 +1000)
33
+ * 7515360 - Merge branch 'doc' into release-1.1.0 (bethesque, Sat Apr 12 10:37:51 2014 +1000)
34
+ * 1200481 - Removed pact_gem key from pact fixtures (bethesque, Wed Apr 9 22:19:02 2014 +1000)
35
+ * 72d791b - Ordered rendering of keys in markdown (bethesque, Wed Apr 9 22:15:01 2014 +1000)
36
+ * 000b223 - Hiding headers and body from docs when they are empty (bethesque, Wed Apr 9 21:46:02 2014 +1000)
37
+ * 7f6ed91 - Changing request key ordering so it makes more sense when reading it (bethesque, Wed Apr 9 21:45:31 2014 +1000)
38
+ * 65054a8 - Added index rendering (bethesque, Wed Apr 9 19:38:55 2014 +1000)
39
+ * 9426565 - Refactoring generation code. Fixed rendering of interaction in markdown when ActiveSupport is loaded (bethesque, Wed Apr 9 18:20:53 2014 +100
40
+ * 73d0dbf - WIP refactoring generator code (bethesque, Wed Apr 9 17:03:14 2014 +1000)
41
+ * 7d1d07b - WIP tests and refactor doc generator (bethesque, Wed Apr 9 13:36:46 2014 +1000)
42
+
43
+ ### 1.0.39 (8 April 2014)
44
+
45
+ * a034ab6 - Oh ActiveSupport, why??? Fixing to_json for difference indicators (bethesque, Mon Apr 7 17:26:10 2014 +1000)
46
+ * 1c7fa0d - Update faq.md (bethesque, Thu Apr 3 09:58:02 2014 +1100)
47
+ * 8cf5b57 - Update README.md (bethesque, Thu Mar 27 13:38:13 2014 +1100)
48
+ * 1c5fde9 - Preloading app before suite in pact:verify Ensures consistent behaviour between the first before/after each hooks (bethesque, Thu Mar 27 10:0
4
49
 
5
50
  ### 1.0.38 (24 March 2014)
6
51
 
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pact (1.1.0.rc2)
4
+ pact (1.1.0.rc3)
5
5
  awesome_print (~> 1.1)
6
- colored
7
6
  find_a_port (~> 1.0.1)
8
7
  json
9
8
  rack-test (~> 0.6.2)
10
9
  randexp (~> 0.1.7)
11
10
  rspec (~> 2.12)
11
+ term-ansicolor (~> 1.0)
12
12
  thor
13
13
  webrick
14
14
 
@@ -25,7 +25,6 @@ GEM
25
25
  atomic (1.1.14)
26
26
  awesome_print (1.2.0)
27
27
  coderay (1.0.9)
28
- colored (1.2)
29
28
  crack (0.4.1)
30
29
  safe_yaml (~> 0.9.0)
31
30
  diff-lcs (1.2.4)
@@ -58,9 +57,12 @@ GEM
58
57
  rspec-mocks (2.14.3)
59
58
  safe_yaml (0.9.5)
60
59
  slop (3.4.6)
61
- thor (0.18.1)
60
+ term-ansicolor (1.3.0)
61
+ tins (~> 1.0)
62
+ thor (0.19.1)
62
63
  thread_safe (0.1.3)
63
64
  atomic
65
+ tins (1.1.0)
64
66
  tzinfo (0.3.38)
65
67
  webmock (1.9.3)
66
68
  addressable (>= 2.2.7)
data/README.md CHANGED
@@ -14,10 +14,9 @@ Travis CI Status: [![travis-ci.org Build Status](https://travis-ci.org/realestat
14
14
  * A service is mocked using an actual process running on a specified port, so javascript clients can be tested as easily as backend clients.
15
15
  * "Provider states" (similar to fixtures) allow the same request to be made with a different expected response.
16
16
  * Consumers specify only the fields they are interested in, allowing a provider to return more fields without breaking the pact. This allows a provider to have a different pact with a different consumer, and know which fields each cares about in a given response.
17
- * Expected interactions are verified to have actually occurred in the consumer specs.
18
- * The mocked responses are verified to be valid by replaying the interactions against the provider codebase.
19
- * Rake verification tasks allow a pacts at one or more URIs to be checked against a given service provider codebase.
17
+ * Rake tasks allow pacts to be verified against a service provider codebase.
20
18
  * Different versions of a consumer/provider pairs can be easily tested against each other, allowing confidence when deploying new versions of each (see the pact_broker and pact_broker-client gems).
19
+ * Autogenerated API documentation - need we say more?
21
20
 
22
21
  ## How does it work?
23
22
 
@@ -28,14 +27,15 @@ Travis CI Status: [![travis-ci.org Build Status](https://travis-ci.org/realestat
28
27
  ## Why is developing and testing with pacts better than using integration tests?
29
28
 
30
29
  * Faster execution.
31
- * No need to manage starting and stopping multiple processes.
32
30
  * Reliable responses from mock service provider reduce likelihood of flakey tests.
33
31
  * Only one component is being tested at a time, making the causes of test failures easier to identify.
34
32
  * Design of service provider is improved by considering first how the data is actually going to be used, rather than how it is most easily retrieved and serialised.
33
+ * No need to manage starting, stopping and fixture set up for multiple applications during a test run.
35
34
 
36
- ## Google users group
35
+ ## Contact
37
36
 
38
- https://groups.google.com/forum/#!forum/pact-support
37
+ * Twitter: [@pact_up](https://twitter.com/pact_up)
38
+ * Google users group: https://groups.google.com/forum/#!forum/pact-support
39
39
 
40
40
  ## Installation
41
41
 
@@ -47,10 +47,10 @@ Put it in your Gemfile. You know how.
47
47
 
48
48
  #### 1. Start with you model
49
49
 
50
- Imagine a model class that looks something like this. The attributes for a SomethingModel live on a remote server, and will need to be retrieved by an HTTP call.
50
+ Imagine a model class that looks something like this. The attributes for a Something live on a remote server, and will need to be retrieved by an HTTP call.
51
51
 
52
52
  ```ruby
53
- class SomethingModel
53
+ class Something
54
54
  attr_reader :name
55
55
 
56
56
  def initialize name
@@ -58,7 +58,7 @@ class SomethingModel
58
58
  end
59
59
 
60
60
  def == other
61
- other.is_a?(SomethingModel) && other.name == name
61
+ other.is_a?(Something) && other.name == name
62
62
  end
63
63
  end
64
64
  ```
@@ -68,7 +68,6 @@ end
68
68
  Imagine a service provider client class that looks something like this.
69
69
 
70
70
  ```ruby
71
-
72
71
  class MyServiceProviderClient
73
72
  include HTTParty
74
73
  base_uri 'http://my-service'
@@ -77,7 +76,6 @@ class MyServiceProviderClient
77
76
  # Yet to be implemented because we're doing Test First Development...
78
77
  end
79
78
  end
80
-
81
79
  ```
82
80
  #### 3. Configure the mock server
83
81
 
@@ -114,26 +112,23 @@ describe MyServiceProviderClient, :pact => true do
114
112
  subject { MyServiceProviderClient.new }
115
113
 
116
114
  describe "get_something" do
115
+
117
116
  before do
118
- my_service_provider.
119
- .given("something exists")
120
- .upon_receiving("a request for something")
121
- .with( method: :get, path: '/something' )
122
- .will_respond_with(
117
+ my_service_provider.given("something exists").
118
+ upon_receiving("a request for something").with(method: :get, path: '/something').
119
+ will_respond_with(
123
120
  status: 200,
124
- headers: { 'Content-Type' => 'application/json' },
125
- body: {name: 'A small something'}
126
- )
121
+ headers: {'Content-Type' => 'application/json'},
122
+ body: {name: 'A small something'} )
127
123
  end
128
124
 
129
125
  it "returns a Something" do
130
- expect(subject.get_something).to eq(SomethingModel.new('A small something'))
126
+ expect(subject.get_something).to eq(Something.new('A small something'))
131
127
  end
132
128
 
133
129
  end
134
130
 
135
131
  end
136
-
137
132
  ```
138
133
 
139
134
  #### 5. Run the specs
@@ -146,39 +141,45 @@ Of course, the above specs will fail because the client method is not implemente
146
141
  #### 6. Implement the client methods
147
142
 
148
143
  ```ruby
149
-
150
144
  class MyServiceProviderClient
151
145
  include HTTParty
152
146
  base_uri 'http://my-service'
153
147
 
154
148
  def get_something
155
149
  name = JSON.parse(self.class.get("/something").body)['name']
156
- SomethingModel.new(name)
150
+ Something.new(name)
157
151
  end
158
152
  end
159
-
160
153
  ```
161
154
 
162
155
  #### 7. Run the specs again.
163
156
 
164
157
  Green! You now have a pact file that can be used to verify your expectations in the provider project.
165
- Now, rinse and repeat for ALL the likely status codes that may be returned (recommend 400, 404, 500 and 401/403 if there is authorisation.)
158
+ Now, rinse and repeat for ALL the likely status codes that may be returned (we recommend 404, 500 and 401/403 if there is authorisation.)
166
159
 
167
160
  ### Service Provider project
168
161
 
169
162
  #### 1. Create the skeleton API classes
170
163
 
171
- Create your API class using the framework of your choice (e.g. Sinatra, Grape) - leave the methods unimplemented, we're doing Test First Develoment, remember?
164
+ Create your API class using the framework of your choice - leave the methods unimplemented, we're doing Test First Develoment, remember?
172
165
 
173
166
  #### 2. Tell your provider that it needs to honour the pact file you made earlier
174
167
 
168
+ Require "pact/tasks" in your Rakefile.
169
+
170
+ ```ruby
171
+ # In Rakefile
172
+ require 'pact/tasks'
173
+ ```
174
+
175
175
  Create a `pact_helper.rb` in your service provider project. The file must be called pact_helper.rb, however there is some flexibility in where it can be stored. The recommended place is `specs/service_consumers/pact_helper.rb`.
176
176
 
177
+ See the [Provider](/documentation.md#provider) section of the Configuration documentation for more information.
178
+
177
179
  ```ruby
180
+ # In specs/service_consumers/pact_helper.rb
181
+
178
182
  require 'pact/provider/rspec'
179
- # If you wish to use the same spec_helper file as your unit tests, require it here.
180
- # Otherwise, you can set up a separate RSpec configuration in this file just for pact:verify.
181
- require './spec_helper'
182
183
 
183
184
  Pact.service_provider "My Service Provider" do
184
185
 
@@ -193,14 +194,6 @@ Pact.service_provider "My Service Provider" do
193
194
  pact_uri '../path-to-your-consumer-project/specs/pacts/my_consumer-my_provider.json'
194
195
  end
195
196
  end
196
-
197
- ```
198
- Require "pact/tasks" in your Rakefile. If the pact gem is in the test/development section of your Gemfile, you may want to put an env check around this so it doesn't load the pact tasks in prod.
199
-
200
- ```ruby
201
- # In Rakefile
202
-
203
- require 'pact/tasks'
204
197
  ```
205
198
 
206
199
  #### 3. Run your failing specs
@@ -209,11 +202,13 @@ require 'pact/tasks'
209
202
 
210
203
  Congratulations! You now have a failing spec to develop against.
211
204
 
212
- #### 4. Implement your service provider
205
+ At this stage, you'll want to be able to run your specs one at a time while you implement each feature. At the bottom of the failed pact:verify output you will see the commands to rerun each failed interaction individually. A command to run just one interaction will look like this:
206
+
207
+ $ rake pact:verify PACT_DESCRIPTION="a request for something" PACT_PROVIDER_STATE="something exists"
213
208
 
214
- At this stage, you'll probably want to be able to run your specs one at a time while you implement. Define the environment variables PACT_DESCRIPTION and/or PACT_PROVIDER_STATE as so:
209
+ #### 4. Implement enough to make your first interaction spec pass
215
210
 
216
- $ PACT_DESCRIPTION="a request for something" PACT_PROVIDER_STATE="something exists" rake pact:verify
211
+ Rinse and repeat.
217
212
 
218
213
  #### 5. Keep going til you're green
219
214
 
@@ -221,102 +216,9 @@ Yay! Your provider now honours the pact it has with your consumer. You can now h
221
216
 
222
217
  ### Using provider states
223
218
 
224
- Provider states allow different fixtures to be loaded on the provider to allow you to test the same request with different expected responses.
219
+ Provider states allow you to set up data on the provider before the interaction is run, so that it can make a response that matches what the consumer expects. It also allows the consumer to make the same request with different expected responses.
225
220
 
226
- For example, some code that creates the pact in a consumer project might look like this:
227
-
228
- ```ruby
229
- my_service.
230
- given("a thing exists").
231
- upon_receiving("a request for a thing").
232
- with(method: 'get', path: '/thing').
233
- will_respond_with(status: 200, :body => {thing: "yay!"} )
234
-
235
- ...
236
-
237
- my_service.
238
- given("a thing does not exist").
239
- upon_receiving("a request for a thing").
240
- with(method: 'get', path: '/thing').
241
- will_respond_with(status: 404)
242
-
243
- ...
244
-
245
- my_service.
246
- given("an error occurs while retrieving a thing").
247
- upon_receiving("a request for a thing").
248
- with(method: 'get', path: '/thing').
249
- will_respond_with(status: 500, :body => {message: "An error occurred"}, :headers => { 'Content-Type' => 'application/json'} )
250
- ```
251
-
252
-
253
-
254
- To define service provider states that create the right data for "a thing exists" and "a thing does not exist", write the following in the service provider project. (The consumer name here must match the name of the consumer configured in your consumer project for it to correctly find these provider states.)
255
-
256
-
257
- ```ruby
258
- # In /spec/service_consumers/provider_states_for_my_service_consumer.rb
259
-
260
- Pact.provider_states_for 'My Service Consumer' do
261
- provider_state "a thing exists" do
262
- set_up do
263
- # Create a thing here using your factory of choice
264
- end
265
-
266
- tear_down do
267
- # Any tear down steps to clean up your code (or use RSpec.after(:each))
268
- end
269
- end
270
-
271
- provider_state "a thing does not exist" do
272
- no_op # If there's nothing to do because the state name is more for documentation purposes, you can use no_op to imply this.
273
- end
274
-
275
- provider_state "an error occurs while retrieving a thing" do
276
- set_up do
277
- ThingRepository.stub(:find).and_raise("An error occurred!")
278
- end
279
- end
280
- end
281
-
282
- ```
283
-
284
- ```ruby
285
- # In /spec/service_consumers/pact_helper.rb
286
-
287
- require_relative 'provider_states_for_my_service_consumer.rb'
288
- ```
289
-
290
- To define code that should run before/after each interaction, regardless of whether a provider state is specified or not:
291
-
292
- ```ruby
293
-
294
- Pact.provider_states_for 'My Service Consumer' do
295
-
296
- set_up do
297
- # eg. create API user, start database cleaner transaction
298
- end
299
-
300
- tear_down do
301
- # eg. clean database
302
- end
303
- end
304
-
305
- ```
306
-
307
- Or for global set up/tear down for all consumers:
308
-
309
- ```ruby
310
- Pact.set_up do
311
- # eg. start database cleaner transaction
312
- # Avoid using the global set up for creating data as it will make your tests brittle.
313
- # You don't want changes to one consumer pact to affect another one.
314
- end
315
-
316
- Pact.tear_down do
317
- # eg. clean database
318
- end
319
- ```
221
+ Read more about provider states [here](/documentation/provider-states.md).
320
222
 
321
223
  ### Verifying pacts
322
224
 
@@ -338,64 +240,18 @@ Pact::VerificationTask.new(:dev) do | pact |
338
240
  end
339
241
  ```
340
242
 
341
- ### Configuration
243
+ ## Configuration
342
244
 
343
- ```ruby
344
- Pact.configure do | config |
345
- config.pact_dir = "???" # Optional, default is ./spec/pacts
346
- config.log_dir = "???" # Optional, default is ./log
347
- config.logger = "??" # Optional, defaults to a file logger to the configured log_dir.
348
- config.logger.level = Logger::DEBUG #By default this is INFO, bump this up to debug for more detailed logs
349
- config.pactfile_write_mode = :ovewrite / :update / :smart # Optional. The default pactfile_write_mode is :overwrite. See notes in Advanced section for further information.
350
- end
351
- ```
245
+ See the [Configuration](/documentation/configuration.md) section of the documentation for options relating to thing like logging, diff formatting, and documentation generation.
352
246
 
353
247
  ## Pact best practices
354
248
 
355
- ### In your consumer project
356
-
357
- #### Publish your pacts as artifacts on your CI machine
358
-
359
- This makes the pact available via URL, which your provider build can then use when it runs pact:verify.
360
-
361
- #### Ensure all calls to the provider go through your provider client class
362
-
363
- Do not hand create any HTTP requests in your consumer app or specs. Testing through your provider client class gives you the assurance that your consumer app will be creating exactly the HTTP requests that you think it should.
364
-
365
- #### Use factories to create your expected models
366
-
367
- Sure, you've checked that your client deserialises the HTTP response into the object you expect, but then you need to make sure in your other tests where you stub your client that you're stubbing it with a valid object. The best way to do this is to use factories for all your tests.
368
-
369
- ### In your provider project
370
-
371
- #### Use the pact artifact published by your consumer's CI build to verify the provider
372
-
373
- Configure the pact_uri in the Pact.service_provider block with the pact artifact URL of your last successful build. This way you're only verifying green builds. No point verifying a broken one.
374
- (Watch this space - pact-broker coming soon, so we don't have to use messy build box artifact URLs)
375
-
376
- #### Add pact:verify to your default rake task
377
-
378
- It should run with all your other tests. If an integration is broken, you want to know about it *before* you check in.
379
-
380
- #### Stub calls to downstream systems
381
-
382
- Consider making a separate pact with the downstream system and using shared fixtures.
383
-
384
- #### Consider carefully whether to use the real database or stub calls
385
-
386
- You may choose not stub your database calls for pact:verify. This can be a good time for you to test your database integration if you have a simple application, however, for a complex one, you might want to carefully choose a point at which to stub calls.
249
+ As in all things, there are good ways to implement Pacts, and there are not so good ways. Check out the [Best practices](/documentation/best-practices.md) section of the documentation to make sure you're not Pacting it Wrong.
387
250
 
388
251
  ## Gotchas
389
252
 
390
253
  * Be aware when using the app from the config.ru file is used (the default option) that the Rack::Builder.parse_file seems to require files even if they have already been required, so make sure your boot files are idempotent.
391
254
 
392
- ## Advanced
393
-
394
- ### Filtering the pact:verify specs
395
-
396
- To execute a subset of the specs when running any of the pact verification tasks, define the environment variables PACT_DESCRIPTION and/or PACT_PROVIDER_STATE.
397
-
398
- $ PACT_DESCRIPTION="a request for something" PACT_PROVIDER_STATE="something exists" rake pact:verify
399
255
 
400
256
  See [Frequently Asked Questions](https://github.com/realestate-com-au/pact/blob/master/documentation/faq.md) and [Rarely Asked Questions](https://github.com/realestate-com-au/pact/blob/master/documentation/raq.md) and [Terminology](https://github.com/realestate-com-au/pact/blob/master/documentation/terminology.md) for more information.
401
257
 
@@ -413,13 +269,11 @@ See [Frequently Asked Questions](https://github.com/realestate-com-au/pact/blob/
413
269
  ## TODO
414
270
 
415
271
  Short term:
416
- - FIX EXAMPLE!!!
417
272
  - Support hash of query params
418
273
 
419
274
  Long term:
420
275
  - Provide more flexible matching (eg the keys should match, and the classes of the values should match, but the values of each key do not need to be equal). This is to make the pact verification less brittle.
421
276
  - Add XML support
422
- - Improve display of interaction diffs
423
277
  - Decouple Rspec from Pact and make rspec-pact gem for easy integration
424
278
 
425
279
  ## Contributing