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/documentation/raq.md CHANGED
@@ -19,6 +19,10 @@ end
19
19
  The service prints messages it recieves to stdout which can be really useful
20
20
  when diagnosing issues with pacts.
21
21
 
22
+ ### Doesn't this break HAL?
23
+
24
+ Yes.
25
+
22
26
  ### How can I specify multiple headers with the same name?
23
27
 
24
28
  RFC 2616 states that two headers with the same name can interpreted as a single header with two comma-separated values. This is the safest way to specify multiple headers with the same name, as Rack will only pass the last value through when they are defined separately (see https://github.com/rack/rack/issues/436).
@@ -33,7 +37,3 @@ my_service_provider.
33
37
  )
34
38
 
35
39
  ```
36
-
37
- ### What is this pact file write mode?
38
-
39
- By default, the pact file will be overwritten (started from scratch) every time any rspec runs any spec using pacts. This means that if there are interactions that haven't been executed in the most recent rspec run, they are effectively removed from the pact file. If you have long running pact specs (e.g. they are generated using the browser with Capybara) and you are developing both consumer and provider in parallel, or trying to fix a broken interaction, it can be tedius to run all the specs at once. In this scenario, you can set the pactfile_write_mode to :update. This will keep all existing interactions, and update only the changed ones, identified by description and provider state. The down side of this is that if either of those fields change, the old interactions will not be removed from the pact file. As a middle path, you can set pactfile_write_mode to :smart. This will use :overwrite mode when running rake (as determined by a call to system using 'ps') and :update when running an individual spec.
@@ -20,6 +20,6 @@ A file containing the JSON serialised requests and responses that were defined i
20
20
 
21
21
  To verify a pact, the requests contained in a pact file are replayed against the provider code, and the responses returned are checked to ensure they match those expected in the pact file.
22
22
 
23
- ## Provider state
23
+ ### Provider state
24
24
 
25
- A name describing a "state" (like a fixture) that the provider should be in when a given request is replayed against it. Eg. "there is an alligator called Mary" or "there are no alligators". A provider state name is specified when writing the consumer specs, then, when the pact verification is set up in the provider, the same name will be used to identify the set up code block that should be run before the request is executed.
25
+ A name describing a "state" (like a fixture) that the provider should be in when a given request is replayed against it. Eg. "there is an alligator called Mary" or "there are no alligators". A provider state name is specified when writing the consumer specs, then, when the pact verification is set up in the provider, the same name will be used to identify the set up code block that should be run before the request is executed.
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: ../../
3
3
  specs:
4
- pact (1.0.30)
4
+ pact (1.1.0.rc2)
5
5
  awesome_print (~> 1.1)
6
6
  find_a_port (~> 1.0.1)
7
7
  json
8
8
  rack-test (~> 0.6.2)
9
9
  randexp (~> 0.1.7)
10
10
  rspec (~> 2.12)
11
- thin
11
+ term-ansicolor (~> 1.0)
12
12
  thor
13
13
  webrick
14
14
 
@@ -17,9 +17,7 @@ GEM
17
17
  specs:
18
18
  awesome_print (1.2.0)
19
19
  coderay (1.0.9)
20
- daemons (1.1.9)
21
20
  diff-lcs (1.2.4)
22
- eventmachine (1.0.3)
23
21
  find_a_port (1.0.1)
24
22
  json (1.6.8)
25
23
  method_source (0.8.2)
@@ -49,12 +47,11 @@ GEM
49
47
  tilt (~> 1.3, >= 1.3.4)
50
48
  slop (3.4.6)
51
49
  sqlite3 (1.3.8)
52
- thin (1.6.1)
53
- daemons (>= 1.0.9)
54
- eventmachine (>= 1.0.0)
55
- rack (>= 1.0.0)
56
- thor (0.18.1)
50
+ term-ansicolor (1.3.0)
51
+ tins (~> 1.0)
52
+ thor (0.19.1)
57
53
  tilt (1.4.1)
54
+ tins (1.1.0)
58
55
  webrick (1.3.1)
59
56
 
60
57
  PLATFORMS
@@ -1,3 +1,5 @@
1
+ $: << File.join(File.dirname(__FILE__), "lib")
2
+
1
3
  require 'pact/tasks'
2
4
 
3
5
  task :default => 'pact:verify'
@@ -4,13 +4,9 @@ require_relative 'db'
4
4
  module AnimalService
5
5
  class AnimalRepository
6
6
 
7
-
8
- def self.find_alligators
9
- DATABASE[:animals].find_all
10
- end
11
-
12
7
  def self.find_alligator_by_name name
13
8
  DATABASE[:animals].where(name: name).single_record
14
9
  end
10
+
15
11
  end
16
12
  end
@@ -12,7 +12,7 @@ module AnimalService
12
12
  e = env['sinatra.error']
13
13
  content_type :json
14
14
  status 500
15
- {:error => e.message, :backtrace => e.backtrace}.to_json
15
+ {error: e.message, backtrace: e.backtrace}.to_json
16
16
  end
17
17
 
18
18
  get '/alligators/:name' do
@@ -1,18 +1,15 @@
1
- $: << File.expand_path("../../../lib", __FILE__)
2
-
3
1
  require 'pact/provider/rspec'
4
- require 'animal_service/db'
5
2
 
6
- require_relative "provider_states_for_zoo_app"
3
+ require "./spec/service_consumers/provider_states_for_zoo_app"
4
+
5
+ Pact.configure do | config |
6
+ config.include RSpec::Mocks::ExampleMethods
7
+ end
7
8
 
8
9
  Pact.service_provider 'Animal Service' do
10
+
9
11
  honours_pact_with "Zoo App" do
10
12
  pact_uri '../zoo-app/spec/pacts/zoo_app-animal_service.json'
11
13
  end
12
- end
13
14
 
14
- RSpec.configure do | config |
15
- config.before do
16
- AnimalService::DATABASE[:animals].truncate
17
- end
18
- end
15
+ end
@@ -4,6 +4,10 @@ require 'animal_service/animal_repository'
4
4
 
5
5
  Pact.provider_states_for "Zoo App" do
6
6
 
7
+ set_up do
8
+ AnimalService::DATABASE[:animals].truncate
9
+ end
10
+
7
11
  provider_state "there is an alligator named Mary" do
8
12
  set_up do
9
13
  AnimalService::DATABASE[:animals].insert(name: 'Mary')
@@ -16,7 +20,7 @@ Pact.provider_states_for "Zoo App" do
16
20
 
17
21
  provider_state "an error occurs retrieving an alligator" do
18
22
  set_up do
19
- AnimalService::AnimalRepository.stub(:find_alligator_by_name).and_raise("Argh!!!")
23
+ allow(AnimalService::AnimalRepository).to receive(:find_alligator_by_name).and_raise("Argh!!!")
20
24
  end
21
25
  end
22
26
  end
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: ../../
3
3
  specs:
4
- pact (1.0.30)
4
+ pact (1.1.0.rc2)
5
5
  awesome_print (~> 1.1)
6
6
  find_a_port (~> 1.0.1)
7
7
  json
8
8
  rack-test (~> 0.6.2)
9
9
  randexp (~> 0.1.7)
10
10
  rspec (~> 2.12)
11
- thin
11
+ term-ansicolor (~> 1.0)
12
12
  thor
13
13
  webrick
14
14
 
@@ -17,9 +17,7 @@ GEM
17
17
  specs:
18
18
  awesome_print (1.2.0)
19
19
  coderay (1.0.9)
20
- daemons (1.1.9)
21
20
  diff-lcs (1.2.4)
22
- eventmachine (1.0.3)
23
21
  find_a_port (1.0.1)
24
22
  httparty (0.11.0)
25
23
  multi_json (~> 1.0)
@@ -46,11 +44,10 @@ GEM
46
44
  diff-lcs (>= 1.1.3, < 2.0)
47
45
  rspec-mocks (2.14.3)
48
46
  slop (3.4.6)
49
- thin (1.6.1)
50
- daemons (>= 1.0.9)
51
- eventmachine (>= 1.0.0)
52
- rack (>= 1.0.0)
53
- thor (0.18.1)
47
+ term-ansicolor (1.3.0)
48
+ tins (~> 1.0)
49
+ thor (0.19.1)
50
+ tins (1.1.0)
54
51
  webrick (1.3.1)
55
52
 
56
53
  PLATFORMS
@@ -0,0 +1,5 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ ### Pacts for Zoo App
2
+
3
+ * [Animal Service](Zoo App - Animal Service.md)
@@ -0,0 +1,75 @@
1
+ ### A pact between Zoo App and Animal Service
2
+
3
+ #### Requests from Zoo App to Animal Service
4
+
5
+ * [A request for an alligator](#a_request_for_an_alligator_given_there_is_an_alligator_named_Mary) given there is an alligator named Mary
6
+
7
+ * [A request for an alligator](#a_request_for_an_alligator_given_there_is_not_an_alligator_named_Mary) given there is not an alligator named Mary
8
+
9
+ * [A request for an alligator](#a_request_for_an_alligator_given_an_error_occurs_retrieving_an_alligator) given an error occurs retrieving an alligator
10
+
11
+ #### Interactions
12
+
13
+ <a name="a_request_for_an_alligator_given_there_is_an_alligator_named_Mary"></a>
14
+ Given **there is an alligator named Mary**, upon receiving **a request for an alligator** from Zoo App, with
15
+ ```json
16
+ {
17
+ "method": "get",
18
+ "path": "/alligators/Mary",
19
+ "headers": {
20
+ "Accept": "application/json"
21
+ }
22
+ }
23
+ ```
24
+ Animal Service will respond with:
25
+ ```json
26
+ {
27
+ "status": 200,
28
+ "headers": {
29
+ "Content-Type": "application/json;charset=utf-8"
30
+ },
31
+ "body": {
32
+ "name": "Mary"
33
+ }
34
+ }
35
+ ```
36
+ <a name="a_request_for_an_alligator_given_there_is_not_an_alligator_named_Mary"></a>
37
+ Given **there is not an alligator named Mary**, upon receiving **a request for an alligator** from Zoo App, with
38
+ ```json
39
+ {
40
+ "method": "get",
41
+ "path": "/alligators/Mary",
42
+ "headers": {
43
+ "Accept": "application/json"
44
+ }
45
+ }
46
+ ```
47
+ Animal Service will respond with:
48
+ ```json
49
+ {
50
+ "status": 404
51
+ }
52
+ ```
53
+ <a name="a_request_for_an_alligator_given_an_error_occurs_retrieving_an_alligator"></a>
54
+ Given **an error occurs retrieving an alligator**, upon receiving **a request for an alligator** from Zoo App, with
55
+ ```json
56
+ {
57
+ "method": "get",
58
+ "path": "/alligators/Mary",
59
+ "headers": {
60
+ "Accept": "application/json"
61
+ }
62
+ }
63
+ ```
64
+ Animal Service will respond with:
65
+ ```json
66
+ {
67
+ "status": 500,
68
+ "headers": {
69
+ "Content-Type": "application/json;charset=utf-8"
70
+ },
71
+ "body": {
72
+ "error": "Argh!!!"
73
+ }
74
+ }
75
+ ```
@@ -18,12 +18,12 @@ module ZooApp
18
18
 
19
19
  def self.find_alligator_by_name name
20
20
  response = get("/alligators/#{name}", :headers => {'Accept' => 'application/json'})
21
- handle_response response do
21
+ when_successful(response) do
22
22
  ZooApp::Animals::Alligator.new(parse_body(response))
23
23
  end
24
24
  end
25
25
 
26
- def self.handle_response response
26
+ def self.when_successful response
27
27
  if response.success?
28
28
  yield
29
29
  elsif response.code == 404
@@ -62,6 +62,6 @@
62
62
  }
63
63
  ],
64
64
  "metadata": {
65
- "pactSpecificationVersion": "1.0"
65
+ "pactSpecificationVersion": "1.0.0"
66
66
  }
67
67
  }
@@ -10,22 +10,22 @@ module ZooApp
10
10
 
11
11
  describe ".find_alligator_by_name" do
12
12
  context "when an alligator by the given name exists" do
13
+
13
14
  before do
14
- animal_service.
15
- given("there is an alligator named Mary").
16
- upon_receiving("a request for an alligator").
17
- with( method: :get,
18
- path: '/alligators/Mary',
19
- :headers => {'Accept' => 'application/json'} ).
20
- will_respond_with(
21
- status: 200,
22
- headers: { 'Content-Type' => 'application/json;charset=utf-8' },
23
- body: { name: 'Mary'}
24
- )
15
+ animal_service.given("there is an alligator named Mary").
16
+ upon_receiving("a request for an alligator").with(
17
+ method: :get,
18
+ path: '/alligators/Mary',
19
+ headers: {'Accept' => 'application/json'} ).
20
+ will_respond_with(
21
+ status: 200,
22
+ headers: {'Content-Type' => 'application/json;charset=utf-8'},
23
+ body: {name: 'Mary'}
24
+ )
25
25
  end
26
26
 
27
27
  it "returns the alligator" do
28
- expect(AnimalServiceClient.find_alligator_by_name("Mary")).to eq ZooApp::Animals::Alligator.new(:name => 'Mary')
28
+ expect(AnimalServiceClient.find_alligator_by_name("Mary")).to eq ZooApp::Animals::Alligator.new(name: 'Mary')
29
29
  end
30
30
 
31
31
  end
@@ -33,16 +33,12 @@ module ZooApp
33
33
  context "when an alligator by the given name does not exist" do
34
34
 
35
35
  before do
36
- animal_service.
37
- given("there is not an alligator named Mary").
38
- upon_receiving("a request for an alligator").
39
- with(
40
- method: :get,
41
- path: '/alligators/Mary',
42
- headers: {'Accept' => 'application/json'} ).
43
- will_respond_with(
44
- status: 404
45
- )
36
+ animal_service.given("there is not an alligator named Mary").
37
+ upon_receiving("a request for an alligator").with(
38
+ method: :get,
39
+ path: '/alligators/Mary',
40
+ headers: {'Accept' => 'application/json'} ).
41
+ will_respond_with(status: 404)
46
42
  end
47
43
 
48
44
  it "returns nil" do
@@ -51,19 +47,18 @@ module ZooApp
51
47
 
52
48
  end
53
49
 
54
- context "when an error response is returned" do
50
+ context "when an error occurs retrieving the alligator" do
51
+
55
52
  before do
56
- animal_service.
57
- given("an error occurs retrieving an alligator").
58
- upon_receiving("a request for an alligator").
59
- with( method: :get,
60
- path: '/alligators/Mary',
61
- :headers => {'Accept' => 'application/json'} ).
62
- will_respond_with(
63
- status: 500,
64
- headers: { 'Content-Type' => 'application/json;charset=utf-8' },
65
- body: {:error => 'Argh!!!'}
66
- )
53
+ animal_service.given("an error occurs retrieving an alligator").
54
+ upon_receiving("a request for an alligator").with(
55
+ method: :get,
56
+ path: '/alligators/Mary',
57
+ headers: {'Accept' => 'application/json'}).
58
+ will_respond_with(
59
+ status: 500,
60
+ headers: { 'Content-Type' => 'application/json;charset=utf-8'},
61
+ body: {error: 'Argh!!!'})
67
62
  end
68
63
 
69
64
  it "raises an error" do
@@ -1,6 +1,10 @@
1
1
  require_relative '../spec_helper'
2
2
  require 'pact/consumer/rspec'
3
3
 
4
+ Pact.configure do | config |
5
+ config.doc_generator = :markdown
6
+ end
7
+
4
8
  Pact.service_consumer 'Zoo App' do
5
9
  has_pact_with "Animal Service" do
6
10
  mock_service :animal_service do
@@ -1,15 +1,30 @@
1
1
  require 'ostruct'
2
2
  require 'logger'
3
+ require 'pact/doc/markdown/generator'
4
+ require 'pact/matchers/unix_diff_formatter'
5
+ require 'pact/matchers/embedded_diff_formatter'
6
+ require 'pact/matchers/list_diff_formatter'
3
7
 
4
8
  module Pact
5
9
 
6
10
  class Configuration
11
+
12
+ DOC_GENERATORS = { markdown: Pact::Doc::Markdown::Generator }
13
+
14
+ DIFF_FORMATTERS = {
15
+ :embedded => Pact::Matchers::EmbeddedDiffFormatter,
16
+ :unix => Pact::Matchers::UnixDiffFormatter,
17
+ :list => Pact::Matchers::ListDiffFormatter
18
+ }
19
+
7
20
  attr_accessor :pact_dir
8
21
  attr_accessor :log_dir
22
+ attr_accessor :doc_dir
23
+ attr_accessor :reports_dir
9
24
  attr_accessor :logger
10
25
  attr_accessor :tmp_dir
11
- attr_accessor :reports_dir
12
26
  attr_writer :pactfile_write_mode
27
+
13
28
  attr_accessor :error_stream
14
29
  attr_accessor :output_stream
15
30
 
@@ -25,6 +40,38 @@ module Pact
25
40
  end
26
41
  end
27
42
 
43
+ def doc_generator= doc_generator
44
+ doc_generators << begin
45
+ if DOC_GENERATORS[doc_generator]
46
+ DOC_GENERATORS[doc_generator]
47
+ elsif doc_generator.respond_to?(:call)
48
+ doc_generator
49
+ else
50
+ raise "Pact.configuration.doc_generator needs to respond to call, or be in the preconfigured list: #{DOC_GENERATORS.keys}"
51
+ end
52
+ end
53
+ end
54
+
55
+ def doc_generators
56
+ @doc_generators ||= []
57
+ end
58
+
59
+ def diff_formatter
60
+ @diff_formatter ||= DIFF_FORMATTERS[:unix]
61
+ end
62
+
63
+ def diff_formatter= diff_formatter
64
+ @diff_formatter = begin
65
+ if DIFF_FORMATTERS[diff_formatter]
66
+ DIFF_FORMATTERS[diff_formatter]
67
+ elsif diff_formatter.respond_to?(:call)
68
+ diff_formatter
69
+ else
70
+ raise "Pact.configuration.diff_formatter needs to respond to call, or be in the preconfigured list: #{DIFF_FORMATTERS.keys}"
71
+ end
72
+ end
73
+ end
74
+
28
75
  private
29
76
 
30
77
  #Would love a better way of determining this! It sure won't work on windows.
@@ -56,6 +103,7 @@ module Pact
56
103
  c.logger = default_logger c.log_path
57
104
  c.pactfile_write_mode = :overwrite
58
105
  c.reports_dir = File.expand_path('./reports/pacts')
106
+ c.doc_dir = File.expand_path("./doc")
59
107
  c.output_stream = $stdout
60
108
  c.error_stream = $stderr
61
109
  c