pact 1.4.0 → 1.5.0

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.
@@ -2,7 +2,20 @@ Do this to generate your change history
2
2
 
3
3
  git log --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
-
5
+ ### 1.5.0 (25 November 2014)
6
+
7
+ * 9a5ab1c - Allow path to be specified as a Pact::Term (Beth, Wed Jan 21 07:56:19 2015 +1100)
8
+ * cdec8bd - Prepended rake commands in output with 'bundle exec' (Beth, Mon Dec 22 17:27:12 2014 +1100)
9
+ * 6dfb16e - Added line to print pact verify command to stdout (Beth, Mon Dec 22 17:19:00 2014 +1100)
10
+ * b507f50 - Changed colours of missing provider state templates (Beth, Tue Dec 16 21:50:00 2014 +1100)
11
+ * d61769c - Added prompt for rake pact:verify:help on test failure. (Beth, Tue Dec 16 21:34:51 2014 +1100)
12
+ * c5377a1 - Created rake pact:verify:help task to display help text (Beth, Tue Dec 16 20:38:45 2014 +1100)
13
+ * c9d1189 - Write help to file after pact:verify (Beth, Tue Dec 16 19:49:20 2014 +1100)
14
+ * c7d8c35 - Added pact diff to help text (Beth, Tue Dec 16 13:14:35 2014 +1100)
15
+ * c877b94 - Moved interaction filter to command line argument from ENV (Beth, Sun Dec 14 22:05:44 2014 +1100)
16
+ * cd077ec - Added message to show diff between current pact and previous version when pact:verify fails. This relies on the 'diff-previous-distinct' relation being present in the pact resource, so will only work when the pact is retrieved from a pact broker (Beth, Fri Dec 12 11:25:59 2014 +1100)
17
+ * 43aa930 - Added command line option to show full backtrace for pact:verify failures (Beth, Thu Dec 4 08:45:28 2014 +1100)
18
+ * 5667874 - Ensure markdown doc rendering doesn't blow up if there is a nil description (Beth, Wed Dec 3 21:35:42 2014 +1100)
6
19
 
7
20
  ### 1.4.0 (25 November 2014)
8
21
 
@@ -1,8 +1,5 @@
1
- require 'find_a_port'
2
1
  require 'thor'
3
- require 'thwait'
4
- require 'pact/consumer'
5
- require 'rack/handler/webrick'
2
+ require 'pact/cli/run_pact_verification'
6
3
 
7
4
  module Pact
8
5
  class CLI < Thor
@@ -10,103 +7,13 @@ module Pact
10
7
  desc 'verify', "Verify a pact"
11
8
  method_option :pact_helper, aliases: "-h", desc: "Pact helper file", :required => true
12
9
  method_option :pact_uri, aliases: "-p", desc: "Pact URI"
10
+ method_option :backtrace, aliases: "-b", desc: "Show full backtrace", :default => false, :type => :boolean
11
+ method_option :description, aliases: "-d", desc: "Interaction description filter"
12
+ method_option :provider_state, aliases: "-s", desc: "Provider state filter"
13
13
 
14
14
  def verify
15
- RunPactVerification.call(options)
15
+ Cli::RunPactVerification.call(options)
16
16
  end
17
17
 
18
- private
19
-
20
- def log message
21
- puts message unless options[:quiet]
22
- end
23
- end
24
-
25
- class RunPactVerification
26
-
27
- attr_reader :options
28
-
29
- def initialize options
30
- @options = options
31
- end
32
-
33
- def self.call options
34
- new(options).call
35
- end
36
-
37
-
38
- def call
39
- initialize_rspec
40
- setup_load_path
41
- load_pact_helper
42
- run_specs
43
- end
44
-
45
- private
46
-
47
- def initialize_rspec
48
- # With RSpec3, if the pact_helper loads a library that adds its own formatter before we set one,
49
- # we will get a ProgressFormatter too, and get little dots sprinkled throughout our output.
50
- require 'pact/rspec'
51
- ::RSpec.configuration.add_formatter Pact::RSpec.formatter_class
52
- end
53
-
54
- def setup_load_path
55
- require 'pact/provider/pact_spec_runner'
56
- lib = File.join(Dir.pwd, "lib") # Assume we are running from within the project root. RSpec is smarter about this.
57
- spec = File.join(Dir.pwd, "spec")
58
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
59
- $LOAD_PATH.unshift(spec) if Dir.exist?(spec) && !$LOAD_PATH.include?(spec)
60
- end
61
-
62
- def load_pact_helper
63
- load options[:pact_helper]
64
- end
65
-
66
- def run_specs
67
- exit_code = if options[:pact_uri]
68
- run_with_pact_uri
69
- else
70
- run_with_configured_pacts
71
- end
72
- exit 1 unless exit_code == 0
73
- end
74
-
75
- def run_with_pact_uri
76
- Pact::Provider::PactSpecRunner.new([{uri: options[:pact_uri]}], pact_spec_options).run
77
- end
78
-
79
- def run_with_configured_pacts
80
- pact_verifications = Pact.configuration.pact_verifications
81
- verification_configs = pact_verifications.collect { | pact_verification | { :uri => pact_verification.uri }}
82
- raise "Please configure a pact to verify" if verification_configs.empty?
83
- Pact::Provider::PactSpecRunner.new(verification_configs, options).run
84
- end
85
-
86
- def pact_spec_options
87
- {criteria: SpecCriteria.call}
88
- end
89
-
90
- end
91
-
92
- class SpecCriteria
93
-
94
- def self.call
95
- criteria = {}
96
-
97
- description = ENV["PACT_DESCRIPTION"]
98
- criteria[:description] = Regexp.new(description) if description
99
-
100
- provider_state = ENV["PACT_PROVIDER_STATE"]
101
- if provider_state
102
- if provider_state.length == 0
103
- criteria[:provider_state] = nil #Allow PACT_PROVIDER_STATE="" to mean no provider state
104
- else
105
- criteria[:provider_state] = Regexp.new(provider_state)
106
- end
107
- end
108
-
109
- criteria
110
- end
111
18
  end
112
19
  end
@@ -0,0 +1,74 @@
1
+ require 'pact/cli/spec_criteria'
2
+
3
+ module Pact
4
+ module Cli
5
+ class RunPactVerification
6
+
7
+ attr_reader :options
8
+
9
+ def initialize options
10
+ @options = options
11
+ end
12
+
13
+ def self.call options
14
+ new(options).call
15
+ end
16
+
17
+
18
+ def call
19
+ initialize_rspec
20
+ setup_load_path
21
+ load_pact_helper
22
+ run_specs
23
+ end
24
+
25
+ private
26
+
27
+ def initialize_rspec
28
+ # With RSpec3, if the pact_helper loads a library that adds its own formatter before we set one,
29
+ # we will get a ProgressFormatter too, and get little dots sprinkled throughout our output.
30
+ require 'pact/rspec'
31
+ ::RSpec.configuration.add_formatter Pact::RSpec.formatter_class
32
+ end
33
+
34
+ def setup_load_path
35
+ require 'pact/provider/pact_spec_runner'
36
+ lib = File.join(Dir.pwd, "lib") # Assume we are running from within the project root. RSpec is smarter about this.
37
+ spec = File.join(Dir.pwd, "spec")
38
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
39
+ $LOAD_PATH.unshift(spec) if Dir.exist?(spec) && !$LOAD_PATH.include?(spec)
40
+ end
41
+
42
+ def load_pact_helper
43
+ load options[:pact_helper]
44
+ end
45
+
46
+ def run_specs
47
+ exit_code = if options[:pact_uri]
48
+ run_with_pact_uri
49
+ else
50
+ run_with_configured_pacts
51
+ end
52
+ exit exit_code
53
+ end
54
+
55
+ def run_with_pact_uri
56
+ Pact::Provider::PactSpecRunner.new([options[:pact_uri]], pact_spec_options).run
57
+ end
58
+
59
+ def run_with_configured_pacts
60
+ pact_urls = Pact.provider_world.pact_urls
61
+ raise "Please configure a pact to verify" if pact_urls.empty?
62
+ Pact::Provider::PactSpecRunner.new(pact_urls, pact_spec_options).run
63
+ end
64
+
65
+ def pact_spec_options
66
+ {
67
+ full_backtrace: options[:backtrace],
68
+ criteria: SpecCriteria.call(options)
69
+ }
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,23 @@
1
+ module Pact
2
+ module Cli
3
+ class SpecCriteria
4
+
5
+ def self.call options
6
+ criteria = {}
7
+
8
+ criteria[:description] = Regexp.new(options[:description]) if options[:description]
9
+
10
+ provider_state = options[:provider_state]
11
+ if provider_state
12
+ if provider_state.length == 0
13
+ criteria[:provider_state] = nil #Allow PACT_PROVIDER_STATE="" to mean no provider state
14
+ else
15
+ criteria[:provider_state] = Regexp.new(provider_state)
16
+ end
17
+ end
18
+
19
+ criteria
20
+ end
21
+ end
22
+ end
23
+ end
@@ -17,6 +17,18 @@ module Pact
17
17
  @doc_dir = doc_dir
18
18
  end
19
19
 
20
+ def reports_dir
21
+ @reports_dir ||= default_reports_dir
22
+ end
23
+
24
+ def default_reports_dir
25
+ File.expand_path("./reports/pacts")
26
+ end
27
+
28
+ def reports_dir= reports_dir
29
+ @reports_dir = reports_dir
30
+ end
31
+
20
32
  def add_provider_verification &block
21
33
  provider_verifications << block
22
34
  end
@@ -17,7 +17,7 @@ module Pact
17
17
  if has_provider_state?
18
18
  "#{description} given #{interaction.provider_state}"
19
19
  else
20
- interaction.description
20
+ description
21
21
  end.gsub(/\s+/,'_')
22
22
  end
23
23
  end
@@ -51,6 +51,7 @@ module Pact
51
51
  end
52
52
 
53
53
  def description start_of_sentence = false
54
+ return '' unless @interaction.description
54
55
  apply_capitals(@interaction.description.strip, start_of_sentence)
55
56
  end
56
57
 
@@ -21,14 +21,6 @@ module Pact
21
21
  end
22
22
  end
23
23
 
24
- def add_pact_verification verification
25
- pact_verifications << verification
26
- end
27
-
28
- def pact_verifications
29
- @pact_verifications ||= []
30
- end
31
-
32
24
  def config_ru_path
33
25
  @config_ru_path ||= './config.ru'
34
26
  end
@@ -1,5 +1,6 @@
1
1
  require 'pact/provider/pact_verification'
2
2
  require 'pact/shared/dsl'
3
+ require 'pact/provider/world'
3
4
 
4
5
  module Pact
5
6
  module Provider
@@ -33,7 +34,7 @@ module Pact
33
34
 
34
35
  def create_pact_verification
35
36
  verification = Pact::Provider::PactVerification.new(consumer_name, pact_uri, ref)
36
- Pact.configuration.add_pact_verification verification
37
+ Pact.provider_world.add_pact_verification verification
37
38
  end
38
39
 
39
40
  def validate
@@ -0,0 +1,80 @@
1
+ require 'pact/provider/help/content'
2
+ require 'fileutils'
3
+ require 'pact/consumer/configuration'
4
+ require 'pact/provider/help/write'
5
+ require 'term/ansicolor'
6
+
7
+ module Pact
8
+ module Provider
9
+ module Help
10
+ class ConsoleText
11
+
12
+ C = ::Term::ANSIColor
13
+
14
+ def self.call reports_dir = Pact.configuration.reports_dir, options = {color: true}
15
+ new(reports_dir || Pact.configuration.reports_dir, options).call
16
+ end
17
+
18
+ def initialize reports_dir, options
19
+ @reports_dir = File.expand_path(reports_dir)
20
+ @options = options
21
+ end
22
+
23
+ def call
24
+ begin
25
+ options[:color] ? ColorizeMarkdown.(help_text) : help_text
26
+ rescue Errno::ENOENT
27
+ options[:color] ? error_text_coloured : error_text_plain
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :reports_dir, :options
34
+
35
+ def help_text
36
+ File.read(help_file_path)
37
+ end
38
+
39
+ def help_file_path
40
+ File.join(reports_dir, Write::HELP_FILE_NAME)
41
+ end
42
+
43
+ def error_text_plain
44
+ "Sorry, could not find help file at #{help_file_path}. Please ensure you have run `rake pact:verify`.\n" +
45
+ "If this does not fix the problem, please raise a github issues for this bug."
46
+ end
47
+
48
+ def error_text_coloured
49
+ C.red(error_text_plain)
50
+ end
51
+
52
+ class ColorizeMarkdown
53
+
54
+ C = ::Term::ANSIColor
55
+
56
+ def self.call markdown
57
+ markdown.split("\n").collect do | line |
58
+ if line.start_with?("# ")
59
+ yellow_underling line.gsub(/^# /, '')
60
+ elsif line.start_with?("* ")
61
+ green("* ") + line.gsub(/^\* /, '')
62
+ else
63
+ line
64
+ end
65
+ end.join("\n")
66
+ end
67
+
68
+ def self.yellow_underling string
69
+ C.underline(C.yellow(string))
70
+ end
71
+
72
+ def self.green string
73
+ C.green(string)
74
+ end
75
+
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,38 @@
1
+ require 'pact/provider/help/pact_diff'
2
+
3
+ module Pact
4
+ module Provider
5
+ module Help
6
+ class Content
7
+
8
+ def initialize pact_jsons
9
+ @pact_jsons = pact_jsons
10
+ end
11
+
12
+ def text
13
+ help_text + "\n\n" + pact_diffs
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :pact_jsons
19
+
20
+ def help_text
21
+ temp_dir = Pact.configuration.tmp_dir
22
+ log_path = Pact.configuration.log_path
23
+ ERB.new(template_string).result(binding)
24
+ end
25
+
26
+ def template_string
27
+ File.read(File.expand_path( '../../../templates/help.erb', __FILE__))
28
+ end
29
+
30
+ def pact_diffs
31
+ pact_jsons.collect do | pact_json |
32
+ PactDiff.call(pact_json)
33
+ end.compact.join("\n")
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,67 @@
1
+ module Pact
2
+ module Provider
3
+ module Help
4
+
5
+ class PactDiff
6
+
7
+ class PrintPactDiffError < StandardError; end
8
+
9
+ attr_reader :pact_json, :output
10
+
11
+ def initialize pact_json
12
+ @pact_json = pact_json
13
+ end
14
+
15
+ def self.call pact_json
16
+ new(pact_json).call
17
+ end
18
+
19
+ def call
20
+ begin
21
+ if diff_rel && diff_url
22
+ header + "\n" + get_diff
23
+ end
24
+ rescue PrintPactDiffError => e
25
+ return e.message
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def header
32
+ "The following changes have been made since the previous distinct version of this pact, and may be responsible for verification failure:\n"
33
+ end
34
+
35
+ def pact_hash
36
+ @pact_hash ||= json_load(pact_json)
37
+ end
38
+
39
+ def links
40
+ pact_hash['_links'] || pact_hash['links']
41
+ end
42
+
43
+ def diff_rel
44
+ return nil unless links
45
+ key = links.keys.find { | key | key =~ /diff/ && key =~ /distinct/ && key =~ /previous/}
46
+ key ? links[key] : nil
47
+ end
48
+
49
+ def diff_url
50
+ diff_rel['href']
51
+ end
52
+
53
+ def get_diff
54
+ begin
55
+ open(diff_url) { | file | file.read }
56
+ rescue StandardError => e
57
+ raise PrintPactDiffError.new("Tried to retrieve diff with previous pact from #{diff_url}, but received response code #{e}.")
58
+ end
59
+ end
60
+
61
+ def json_load json
62
+ JSON.load(json, nil, { max_nesting: 50 })
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,51 @@
1
+ require 'pact/consumer/configuration'
2
+ require 'term/ansicolor'
3
+ require 'pathname'
4
+
5
+ module Pact
6
+ module Provider
7
+ module Help
8
+ class PromptText
9
+
10
+ C = ::Term::ANSIColor
11
+
12
+ def self.call reports_dir = Pact.configuration.reports_dir, options = {color: Pact.configuration.color_enabled}
13
+ new(reports_dir, options).call
14
+ end
15
+
16
+ def initialize reports_dir, options
17
+ @reports_dir = File.expand_path(reports_dir)
18
+ @options = options
19
+ end
20
+
21
+ def call
22
+ options[:color] ? prompt_text_colored : prompt_text_plain
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :reports_dir, :options
28
+
29
+ def prompt_text_plain
30
+ "For assistance debugging failures, run `bundle exec rake pact:verify:help#{rake_args}`\n"
31
+ end
32
+
33
+ def prompt_text_colored
34
+ C.yellow(prompt_text_plain)
35
+ end
36
+
37
+ def rake_args
38
+ if reports_dir == Pact.configuration.default_reports_dir
39
+ ''
40
+ else
41
+ "[#{relative_reports_dir}]"
42
+ end
43
+ end
44
+
45
+ def relative_reports_dir
46
+ Pathname.new(reports_dir).relative_path_from(Pathname.new(Dir.pwd))
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,55 @@
1
+ require 'pact/provider/help/content'
2
+ require 'fileutils'
3
+ require 'pact/consumer/configuration'
4
+
5
+ module Pact
6
+ module Provider
7
+ module Help
8
+ class Write
9
+
10
+ HELP_FILE_NAME = 'help.md'
11
+
12
+ def self.call pact_jsons, reports_dir = Pact.configuration.reports_dir
13
+ new(pact_jsons, reports_dir).call
14
+ end
15
+
16
+ def initialize pact_jsons, reports_dir
17
+ @pact_jsons = pact_jsons
18
+ @reports_dir = File.expand_path(reports_dir)
19
+ end
20
+
21
+ def call
22
+ clean_reports_dir
23
+ write
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :reports_dir, :pact_jsons
29
+
30
+ def clean_reports_dir
31
+ raise "Cleaning report dir #{reports_dir} would delete project!" if reports_dir_contains_pwd
32
+ FileUtils.rm_rf reports_dir
33
+ FileUtils.mkdir_p reports_dir
34
+ end
35
+
36
+ def reports_dir_contains_pwd
37
+ Dir.pwd.start_with?(reports_dir)
38
+ end
39
+
40
+ def write
41
+ File.open(help_path, "w") { |file| file << help_text }
42
+ end
43
+
44
+ def help_path
45
+ File.join(reports_dir, 'help.md')
46
+ end
47
+
48
+ def help_text
49
+ Content.new(pact_jsons).text
50
+ end
51
+
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,19 @@
1
+ require 'pact/consumer_contract/pact_file'
2
+
3
+ module PactBroker
4
+ module Provider
5
+ class PactSource
6
+
7
+ attr_reader :uri
8
+
9
+ def initialize uri
10
+ @uri = uri
11
+ end
12
+
13
+ def pact_json
14
+ @pact_json ||= Pact::PactFile.read(uri, {})
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -5,6 +5,8 @@ require 'rspec/core/formatters/documentation_formatter'
5
5
  require 'pact/provider/pact_helper_locator'
6
6
  require 'pact/project_root'
7
7
  require 'pact/rspec'
8
+ require 'pact/provider/pact_source'
9
+ require 'pact/provider/help/write'
8
10
 
9
11
  require_relative 'rspec'
10
12
 
@@ -15,12 +17,12 @@ module Pact
15
17
 
16
18
  include Pact::Provider::RSpec::ClassMethods
17
19
 
18
- attr_reader :spec_definitions
20
+ attr_reader :pact_urls
19
21
  attr_reader :options
20
22
  attr_reader :output
21
23
 
22
- def initialize spec_definitions, options = {}
23
- @spec_definitions = spec_definitions
24
+ def initialize pact_urls, options = {}
25
+ @pact_urls = pact_urls
24
26
  @options = options
25
27
  @results = nil
26
28
  end
@@ -38,17 +40,6 @@ module Pact
38
40
 
39
41
  private
40
42
 
41
- def initialize_specs
42
- spec_definitions.each do | spec_definition |
43
- options = {
44
- consumer: spec_definition[:consumer],
45
- save_pactfile_to_tmp: true,
46
- criteria: @options[:criteria]
47
- }
48
- honour_pactfile spec_definition[:uri], options
49
- end
50
- end
51
-
52
43
  def configure_rspec
53
44
  monkey_patch_backtrace_formatter
54
45
 
@@ -74,6 +65,7 @@ module Pact
74
65
  formatter_class = Pact::RSpec.formatter_class
75
66
  pact_formatter = ::RSpec.configuration.formatters.find {|f| f.class == formatter_class && f.output == ::RSpec.configuration.output_stream}
76
67
  ::RSpec.configuration.add_formatter formatter_class unless pact_formatter
68
+ ::RSpec.configuration.full_backtrace = @options[:full_backtrace]
77
69
 
78
70
  config.before(:suite) do
79
71
  # Preload app before suite so the classes loaded in memory are consistent for
@@ -84,6 +76,12 @@ module Pact
84
76
  Pact.configuration.provider.app
85
77
  end
86
78
 
79
+ jsons = pact_jsons
80
+
81
+ config.after(:suite) do
82
+ Pact::Provider::Help::Write.call(jsons)
83
+ end
84
+
87
85
  end
88
86
 
89
87
  def run_specs
@@ -106,6 +104,27 @@ module Pact
106
104
  end
107
105
  end
108
106
 
107
+ def pact_sources
108
+ @pact_sources ||= begin
109
+ pact_urls.collect do | pact_url |
110
+ PactBroker::Provider::PactSource.new(pact_url)
111
+ end
112
+ end
113
+ end
114
+
115
+ def pact_jsons
116
+ pact_sources.collect(&:pact_json)
117
+ end
118
+
119
+ def initialize_specs
120
+ pact_sources.each do | pact_source |
121
+ options = {
122
+ criteria: @options[:criteria]
123
+ }
124
+ honour_pactfile pact_source.uri, pact_source.pact_json, options
125
+ end
126
+ end
127
+
109
128
  def class_exists? name
110
129
  Kernel.const_get name
111
130
  rescue NameError
@@ -1,16 +1,23 @@
1
+ require 'term/ansicolor'
2
+
1
3
  module Pact
2
4
  module Provider
3
5
  class PrintMissingProviderStates
4
6
 
7
+ C = ::Term::ANSIColor
8
+
5
9
  # Hash of consumer names to array of names of missing provider states
6
10
  def self.call missing_provider_states, output
7
11
  if missing_provider_states.any?
8
- output.puts orangeify(text(missing_provider_states))
12
+ output.puts colorize(text(missing_provider_states))
9
13
  end
10
14
  end
11
15
 
12
- def self.orangeify string
13
- "\e[33m#{string}\e[m"
16
+ def self.colorize string
17
+ lines = string.split("\n")
18
+ first_line = C.cyan(C.underline(lines[0]))
19
+ other_lines = C.cyan(lines[1..-1].join("\n"))
20
+ first_line + "\n" + other_lines
14
21
  end
15
22
 
16
23
  def self.text missing_provider_states
@@ -18,18 +18,18 @@ module Pact
18
18
 
19
19
  include ::RSpec::Core::DSL
20
20
 
21
- def honour_pactfile pactfile_uri, options = {}
21
+ def honour_pactfile pact_uri, pact_json, options
22
22
  #TODO change puts to use output stream
23
- puts "Reading pact at #{pactfile_uri}"
23
+ puts "Reading pact at #{pact_uri}"
24
24
  puts "Filtering interactions by: #{options[:criteria]}" if options[:criteria] && options[:criteria].any?
25
- consumer_contract = Pact::ConsumerContract.from_json(read_pact_from(pactfile_uri, options))
26
- ::RSpec.describe "Verifying a pact between #{consumer_contract.consumer.name} and #{consumer_contract.provider.name}", :pactfile_uri => pactfile_uri do
27
- honour_consumer_contract consumer_contract, options
25
+ consumer_contract = Pact::ConsumerContract.from_json(pact_json)
26
+ ::RSpec.describe "Verifying a pact between #{consumer_contract.consumer.name} and #{consumer_contract.provider.name}", :pactfile_uri => pact_uri do
27
+ honour_consumer_contract consumer_contract, options.merge(pact_json: pact_json)
28
28
  end
29
29
  end
30
30
 
31
31
  def honour_consumer_contract consumer_contract, options = {}
32
- describe_consumer_contract consumer_contract, options.merge({:consumer => consumer_contract.consumer.name})
32
+ describe_consumer_contract consumer_contract, options.merge(:consumer => consumer_contract.consumer.name)
33
33
  end
34
34
 
35
35
  private
@@ -63,7 +63,8 @@ module Pact
63
63
  metadata = {
64
64
  :pact => :verify,
65
65
  :pact_interaction => interaction,
66
- :pact_interaction_example_description => interaction_description_for_rerun_command(interaction)
66
+ :pact_interaction_example_description => interaction_description_for_rerun_command(interaction),
67
+ :pact_json => options[:pact_json]
67
68
  }
68
69
 
69
70
  describe description_for(interaction), metadata do
@@ -148,10 +149,6 @@ module Pact
148
149
  description_for(interaction).capitalize + ( interaction.provider_state ? " given #{interaction.provider_state}" : "")
149
150
  end
150
151
 
151
- def read_pact_from uri, options = {}
152
- Pact::PactFile.read(uri, options)
153
- end
154
-
155
152
  end
156
153
 
157
154
  # The "arrange" and "act" parts of the test really only need to be run once,
@@ -1,6 +1,7 @@
1
1
  require 'pact/provider/print_missing_provider_states'
2
2
  require 'rspec/core/formatters/documentation_formatter'
3
3
  require 'term/ansicolor'
4
+ require 'pact/provider/help/prompt_text'
4
5
 
5
6
  module Pact
6
7
  module Provider
@@ -42,7 +43,7 @@ module Pact
42
43
  description = example.metadata[:pact_interaction].description
43
44
  pactfile_uri = example.metadata[:pactfile_uri]
44
45
  example_description = example.metadata[:pact_interaction_example_description]
45
- failure_color("rake pact:verify:at[#{pactfile_uri}] PACT_DESCRIPTION=\"#{description}\" PACT_PROVIDER_STATE=\"#{provider_state}\"") + " " + detail_color("# #{example_description}")
46
+ failure_color("bundle exec rake pact:verify:at[#{pactfile_uri}] PACT_DESCRIPTION=\"#{description}\" PACT_PROVIDER_STATE=\"#{provider_state}\"") + " " + detail_color("# #{example_description}")
46
47
  end
47
48
 
48
49
  def print_failure_message
@@ -50,9 +51,7 @@ module Pact
50
51
  end
51
52
 
52
53
  def failure_message
53
- "\n" + C.underline(C.yellow("For assistance debugging failures, please note:")) + "\n\n" +
54
- "The pact files have been stored locally in the following temp directory:\n #{Pact.configuration.tmp_dir}\n\n" +
55
- "The requests and responses are logged in the following log file:\n #{Pact.configuration.log_path}\n\n"
54
+ "\n" + Pact::Provider::Help::PromptText.() + "\n"
56
55
  end
57
56
 
58
57
  end
@@ -1,6 +1,7 @@
1
1
  require 'pact/provider/print_missing_provider_states'
2
2
  require 'rspec/core/formatters'
3
3
  require 'term/ansicolor'
4
+ require 'pact/provider/help/prompt_text'
4
5
 
5
6
  module Pact
6
7
  module Provider
@@ -25,11 +26,11 @@ module Pact
25
26
  private
26
27
 
27
28
  def interactions_count(summary)
28
- summary.examples.collect{ |e|e.metadata[:pact_interaction_example_description]}.uniq.size
29
+ summary.examples.collect{ |e| e.metadata[:pact_interaction_example_description] }.uniq.size
29
30
  end
30
31
 
31
32
  def failed_interactions_count(summary)
32
- summary.failed_examples.collect{ |e|e.metadata[:pact_interaction_example_description]}.uniq.size
33
+ summary.failed_examples.collect{ |e| e.metadata[:pact_interaction_example_description] }.uniq.size
33
34
  end
34
35
 
35
36
  def totals_line summary
@@ -39,11 +40,11 @@ module Pact
39
40
  end
40
41
 
41
42
  def colorized_totals_line(summary)
42
- if summary.failure_count > 0
43
- colorizer.wrap(totals_line(summary), ::RSpec.configuration.failure_color)
44
- else
45
- colorizer.wrap(totals_line(summary), ::RSpec.configuration.success_color)
46
- end
43
+ colorizer.wrap(totals_line(summary), color_for_summary(summary))
44
+ end
45
+
46
+ def color_for_summary summary
47
+ summary.failure_count > 0 ? ::RSpec.configuration.failure_color : ::RSpec.configuration.success_color
47
48
  end
48
49
 
49
50
  def print_rerun_commands summary
@@ -68,7 +69,7 @@ module Pact
68
69
  description = example.metadata[:pact_interaction].description
69
70
  pactfile_uri = example.metadata[:pactfile_uri]
70
71
  example_description = example.metadata[:pact_interaction_example_description]
71
- colorizer.wrap("rake pact:verify:at[#{pactfile_uri}] PACT_DESCRIPTION=\"#{description}\" PACT_PROVIDER_STATE=\"#{provider_state}\" ", ::RSpec.configuration.failure_color) +
72
+ colorizer.wrap("bundle exec rake pact:verify:at[#{pactfile_uri}] PACT_DESCRIPTION=\"#{description}\" PACT_PROVIDER_STATE=\"#{provider_state}\" ", ::RSpec.configuration.failure_color) +
72
73
  colorizer.wrap("# #{example_description}", ::RSpec.configuration.detail_color)
73
74
  end
74
75
 
@@ -77,9 +78,7 @@ module Pact
77
78
  end
78
79
 
79
80
  def failure_message
80
- "\n" + C.underline(C.yellow("For assistance debugging failures, please note:")) + "\n\n" +
81
- "The pact files have been stored locally in the following temp directory:\n #{Pact.configuration.tmp_dir}\n\n" +
82
- "The requests and responses are logged in the following log file:\n #{Pact.configuration.log_path}\n\n"
81
+ "\n" + Pact::Provider::Help::PromptText.() + "\n"
83
82
  end
84
83
 
85
84
  def colorizer
@@ -18,6 +18,18 @@ module Pact
18
18
  @provider_states_proxy ||= Pact::Provider::State::ProviderStateProxy.new
19
19
  end
20
20
 
21
+ def add_pact_verification verification
22
+ pact_verifications << verification
23
+ end
24
+
25
+ def pact_verifications
26
+ @pact_verifications ||= []
27
+ end
28
+
29
+ def pact_urls
30
+ pact_verifications.collect(&:uri)
31
+ end
32
+
21
33
  end
22
34
  end
23
35
  end
@@ -23,12 +23,16 @@ module Pact
23
23
  command_parts << "SPEC_OPTS=#{Shellwords.escape(rspec_opts || '')}"
24
24
  command_parts << FileUtils::RUBY
25
25
  command_parts << "-S pact verify"
26
- command_parts << "-h" << (pact_helper.end_with?(".rb") ? pact_helper : pact_helper + ".rb")
27
- (command_parts << "-p" << pact_uri) if pact_uri
26
+ command_parts << "--pact-helper" << (pact_helper.end_with?(".rb") ? pact_helper : pact_helper + ".rb")
27
+ (command_parts << "--pact-uri" << pact_uri) if pact_uri
28
+ command_parts << "--backtrace" if ENV['BACKTRACE'] == 'true'
29
+ command_parts << "--description #{Shellwords.escape(ENV['PACT_DESCRIPTION'])}" if ENV['PACT_DESCRIPTION']
30
+ command_parts << "--provider-state #{Shellwords.escape(ENV['PACT_PROVIDER_STATE'])}" if ENV['PACT_PROVIDER_STATE']
28
31
  command_parts.flatten.join(" ")
29
32
  end
30
33
 
31
34
  def execute_cmd command
35
+ $stdout.puts command
32
36
  system(command) ? 0 : 1
33
37
  end
34
38
 
@@ -0,0 +1,22 @@
1
+ # For assistance debugging failures
2
+
3
+ * The pact files have been stored locally in the following temp directory:
4
+ <%= temp_dir %>
5
+
6
+ * The requests and responses are logged in the following log file:
7
+ <%= log_path %>
8
+
9
+ * Add BACKTRACE=true to the `rake pact:verify` command to see the full backtrace
10
+
11
+ * If the diff output is confusing, try using another diff formatter.
12
+ The options are :unix, :embedded and :list
13
+
14
+ Pact.configure do | config |
15
+ config.diff_formatter = :embedded
16
+ end
17
+
18
+ See https://github.com/realestate-com-au/pact/blob/master/documentation/configuration.md#diff_formatter for examples and more information.
19
+
20
+ * Check out https://github.com/realestate-com-au/pact/wiki/Troubleshooting
21
+
22
+ * Ask a question in the google users' group https://groups.google.com/forum/#!forum/pact-support
@@ -1,3 +1,3 @@
1
1
  module Pact
2
- VERSION = "1.4.0"
2
+ VERSION = "1.5.0"
3
3
  end
@@ -26,4 +26,10 @@ namespace :pact do
26
26
  end
27
27
  end
28
28
 
29
+ desc "Get help debugging pact:verify failures."
30
+ task 'verify:help', :reports_dir do | t, args |
31
+ require 'pact/provider/help/console_text'
32
+ puts Pact::Provider::Help::ConsoleText.(args[:reports_dir])
33
+ end
34
+
29
35
  end
@@ -28,8 +28,8 @@ Gem::Specification.new do |gem|
28
28
  gem.add_runtime_dependency 'webrick'
29
29
  gem.add_runtime_dependency 'term-ansicolor', '~> 1.0'
30
30
 
31
- gem.add_runtime_dependency 'pact-support', '~> 0.1.2'
32
- gem.add_runtime_dependency 'pact-mock_service', '~> 0.2.0'
31
+ gem.add_runtime_dependency 'pact-support', '~> 0.2.1'
32
+ gem.add_runtime_dependency 'pact-mock_service', '~> 0.2.3'
33
33
 
34
34
  gem.add_development_dependency 'rake', '~> 10.0.3'
35
35
  gem.add_development_dependency 'webmock', '~> 1.18.0'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2014-11-25 00:00:00.000000000 Z
16
+ date: 2015-01-20 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: randexp
@@ -166,7 +166,7 @@ dependencies:
166
166
  requirements:
167
167
  - - ~>
168
168
  - !ruby/object:Gem::Version
169
- version: 0.1.2
169
+ version: 0.2.1
170
170
  type: :runtime
171
171
  prerelease: false
172
172
  version_requirements: !ruby/object:Gem::Requirement
@@ -174,7 +174,7 @@ dependencies:
174
174
  requirements:
175
175
  - - ~>
176
176
  - !ruby/object:Gem::Version
177
- version: 0.1.2
177
+ version: 0.2.1
178
178
  - !ruby/object:Gem::Dependency
179
179
  name: pact-mock_service
180
180
  requirement: !ruby/object:Gem::Requirement
@@ -182,7 +182,7 @@ dependencies:
182
182
  requirements:
183
183
  - - ~>
184
184
  - !ruby/object:Gem::Version
185
- version: 0.2.0
185
+ version: 0.2.3
186
186
  type: :runtime
187
187
  prerelease: false
188
188
  version_requirements: !ruby/object:Gem::Requirement
@@ -190,7 +190,7 @@ dependencies:
190
190
  requirements:
191
191
  - - ~>
192
192
  - !ruby/object:Gem::Version
193
- version: 0.2.0
193
+ version: 0.2.3
194
194
  - !ruby/object:Gem::Dependency
195
195
  name: rake
196
196
  requirement: !ruby/object:Gem::Requirement
@@ -338,6 +338,8 @@ files:
338
338
  - bin/pact
339
339
  - lib/pact.rb
340
340
  - lib/pact/cli.rb
341
+ - lib/pact/cli/run_pact_verification.rb
342
+ - lib/pact/cli/spec_criteria.rb
341
343
  - lib/pact/consumer.rb
342
344
  - lib/pact/consumer/configuration.rb
343
345
  - lib/pact/consumer/configuration/configuration_extensions.rb
@@ -370,8 +372,14 @@ files:
370
372
  - lib/pact/provider/configuration/service_provider_config.rb
371
373
  - lib/pact/provider/configuration/service_provider_dsl.rb
372
374
  - lib/pact/provider/context.rb
375
+ - lib/pact/provider/help/console_text.rb
376
+ - lib/pact/provider/help/content.rb
377
+ - lib/pact/provider/help/pact_diff.rb
378
+ - lib/pact/provider/help/prompt_text.rb
379
+ - lib/pact/provider/help/write.rb
373
380
  - lib/pact/provider/matchers/messages.rb
374
381
  - lib/pact/provider/pact_helper_locator.rb
382
+ - lib/pact/provider/pact_source.rb
375
383
  - lib/pact/provider/pact_spec_runner.rb
376
384
  - lib/pact/provider/pact_verification.rb
377
385
  - lib/pact/provider/print_missing_provider_states.rb
@@ -392,6 +400,7 @@ files:
392
400
  - lib/pact/tasks.rb
393
401
  - lib/pact/tasks/task_helper.rb
394
402
  - lib/pact/tasks/verification_task.rb
403
+ - lib/pact/templates/help.erb
395
404
  - lib/pact/templates/provider_state.erb
396
405
  - lib/pact/version.rb
397
406
  - lib/tasks/pact.rake
@@ -411,7 +420,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
411
420
  version: '0'
412
421
  segments:
413
422
  - 0
414
- hash: -2181790472220138069
423
+ hash: -4361813118953471608
415
424
  required_rubygems_version: !ruby/object:Gem::Requirement
416
425
  none: false
417
426
  requirements:
@@ -420,7 +429,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
420
429
  version: '0'
421
430
  segments:
422
431
  - 0
423
- hash: -2181790472220138069
432
+ hash: -4361813118953471608
424
433
  requirements: []
425
434
  rubyforge_project:
426
435
  rubygems_version: 1.8.23