pact 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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