pact-support 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +29 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -0
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +80 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +4 -0
  10. data/Rakefile +4 -0
  11. data/lib/pact/configuration.rb +164 -0
  12. data/lib/pact/consumer/request.rb +27 -0
  13. data/lib/pact/consumer_contract.rb +1 -0
  14. data/lib/pact/consumer_contract/consumer_contract.rb +114 -0
  15. data/lib/pact/consumer_contract/file_name.rb +19 -0
  16. data/lib/pact/consumer_contract/headers.rb +51 -0
  17. data/lib/pact/consumer_contract/interaction.rb +73 -0
  18. data/lib/pact/consumer_contract/pact_file.rb +24 -0
  19. data/lib/pact/consumer_contract/request.rb +73 -0
  20. data/lib/pact/consumer_contract/response.rb +51 -0
  21. data/lib/pact/consumer_contract/service_consumer.rb +28 -0
  22. data/lib/pact/consumer_contract/service_provider.rb +28 -0
  23. data/lib/pact/logging.rb +14 -0
  24. data/lib/pact/matchers.rb +1 -0
  25. data/lib/pact/matchers/actual_type.rb +16 -0
  26. data/lib/pact/matchers/base_difference.rb +37 -0
  27. data/lib/pact/matchers/differ.rb +153 -0
  28. data/lib/pact/matchers/difference.rb +13 -0
  29. data/lib/pact/matchers/difference_indicator.rb +26 -0
  30. data/lib/pact/matchers/embedded_diff_formatter.rb +62 -0
  31. data/lib/pact/matchers/expected_type.rb +35 -0
  32. data/lib/pact/matchers/index_not_found.rb +15 -0
  33. data/lib/pact/matchers/list_diff_formatter.rb +101 -0
  34. data/lib/pact/matchers/matchers.rb +139 -0
  35. data/lib/pact/matchers/no_diff_indicator.rb +18 -0
  36. data/lib/pact/matchers/regexp_difference.rb +13 -0
  37. data/lib/pact/matchers/type_difference.rb +16 -0
  38. data/lib/pact/matchers/unexpected_index.rb +11 -0
  39. data/lib/pact/matchers/unexpected_key.rb +11 -0
  40. data/lib/pact/matchers/unix_diff_formatter.rb +114 -0
  41. data/lib/pact/reification.rb +28 -0
  42. data/lib/pact/rspec.rb +53 -0
  43. data/lib/pact/shared/active_support_support.rb +51 -0
  44. data/lib/pact/shared/dsl.rb +76 -0
  45. data/lib/pact/shared/jruby_support.rb +18 -0
  46. data/lib/pact/shared/json_differ.rb +15 -0
  47. data/lib/pact/shared/key_not_found.rb +15 -0
  48. data/lib/pact/shared/null_expectation.rb +31 -0
  49. data/lib/pact/shared/request.rb +97 -0
  50. data/lib/pact/shared/text_differ.rb +14 -0
  51. data/lib/pact/something_like.rb +49 -0
  52. data/lib/pact/support.rb +9 -0
  53. data/lib/pact/support/version.rb +5 -0
  54. data/lib/pact/symbolize_keys.rb +12 -0
  55. data/lib/pact/term.rb +85 -0
  56. data/lib/tasks/pact.rake +29 -0
  57. data/pact-support.gemspec +35 -0
  58. data/spec/lib/pact/consumer/request_spec.rb +25 -0
  59. data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +58 -0
  60. data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +141 -0
  61. data/spec/lib/pact/consumer_contract/headers_spec.rb +107 -0
  62. data/spec/lib/pact/consumer_contract/interaction_spec.rb +151 -0
  63. data/spec/lib/pact/consumer_contract/request_spec.rb +329 -0
  64. data/spec/lib/pact/consumer_contract/response_spec.rb +73 -0
  65. data/spec/lib/pact/matchers/differ_spec.rb +215 -0
  66. data/spec/lib/pact/matchers/difference_spec.rb +22 -0
  67. data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +90 -0
  68. data/spec/lib/pact/matchers/index_not_found_spec.rb +21 -0
  69. data/spec/lib/pact/matchers/list_diff_formatter_spec.rb +120 -0
  70. data/spec/lib/pact/matchers/matchers_spec.rb +500 -0
  71. data/spec/lib/pact/matchers/regexp_difference_spec.rb +20 -0
  72. data/spec/lib/pact/matchers/type_difference_spec.rb +34 -0
  73. data/spec/lib/pact/matchers/unexpected_index_spec.rb +20 -0
  74. data/spec/lib/pact/matchers/unexpected_key_spec.rb +20 -0
  75. data/spec/lib/pact/matchers/unix_diff_formatter_spec.rb +216 -0
  76. data/spec/lib/pact/reification_spec.rb +67 -0
  77. data/spec/lib/pact/shared/dsl_spec.rb +86 -0
  78. data/spec/lib/pact/shared/json_differ_spec.rb +36 -0
  79. data/spec/lib/pact/shared/key_not_found_spec.rb +20 -0
  80. data/spec/lib/pact/shared/request_spec.rb +196 -0
  81. data/spec/lib/pact/shared/text_differ_spec.rb +54 -0
  82. data/spec/lib/pact/something_like_spec.rb +21 -0
  83. data/spec/lib/pact/term_spec.rb +89 -0
  84. data/spec/spec_helper.rb +19 -0
  85. data/spec/support/a_consumer-a_producer.json +32 -0
  86. data/spec/support/a_consumer-a_provider.json +32 -0
  87. data/spec/support/active_support_if_configured.rb +6 -0
  88. data/spec/support/case-insensitive-response-header-matching.json +21 -0
  89. data/spec/support/consumer_contract_template.json +24 -0
  90. data/spec/support/dsl_spec_support.rb +7 -0
  91. data/spec/support/factories.rb +82 -0
  92. data/spec/support/generated_index.md +4 -0
  93. data/spec/support/generated_markdown.md +55 -0
  94. data/spec/support/interaction_view_model.json +63 -0
  95. data/spec/support/interaction_view_model_with_terms.json +50 -0
  96. data/spec/support/markdown_pact.json +48 -0
  97. data/spec/support/missing_provider_states_output.txt +25 -0
  98. data/spec/support/options.json +21 -0
  99. data/spec/support/shared_examples_for_request.rb +94 -0
  100. data/spec/support/spec_support.rb +20 -0
  101. data/spec/support/stubbing.json +22 -0
  102. data/spec/support/term.json +48 -0
  103. data/spec/support/test_app_fail.json +61 -0
  104. data/spec/support/test_app_pass.json +38 -0
  105. data/spec/support/test_app_with_right_content_type_differ.json +23 -0
  106. data/tasks/spec.rake +6 -0
  107. metadata +401 -0
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer_contract/response'
3
+
4
+ module Pact
5
+
6
+ describe Response do
7
+
8
+ subject { Response.from_hash(status: 200, headers: {'Content-Type' => 'application/json'}, body: {some: 'body'}) }
9
+
10
+ describe "#status" do
11
+ it "returns the status" do
12
+ expect(subject.status).to eq 200
13
+ end
14
+ end
15
+
16
+ describe "#headers" do
17
+ it "returns the Headers" do
18
+ expect(subject.headers).to eq Headers.new('Content-Type' => 'application/json')
19
+ end
20
+ end
21
+
22
+ describe "#body" do
23
+ it "returns the body" do
24
+ expect(subject.body).to eq some: 'body'
25
+ end
26
+ end
27
+
28
+ describe "#body_allows_any_value?" do
29
+ context "when the body is not specified" do
30
+ subject { Response.from_hash(status: 200, headers: {'Content-Type' => 'application/json'}) }
31
+
32
+ it "returns true" do
33
+ expect(subject.body_allows_any_value?).to be true
34
+ end
35
+ end
36
+
37
+ context "when the body is an empty hash" do
38
+ subject { Response.from_hash(status: 200, headers: {'Content-Type' => 'application/json'}, body: {}) }
39
+
40
+ it "returns true" do
41
+ expect(subject.body_allows_any_value?).to be true
42
+ end
43
+ end
44
+
45
+ context "when the body is an empty string" do
46
+ subject { Response.from_hash(status: 200, headers: {'Content-Type' => 'text/plain'}, body: '') }
47
+
48
+ it "returns false" do
49
+ expect(subject.body_allows_any_value?).to be false
50
+ end
51
+ end
52
+
53
+ context "when the body is a hash with values" do
54
+ subject { Response.from_hash(status: 200, headers: {'Content-Type' => 'text/plain'}, body: {some: 'body'}) }
55
+
56
+ it "returns false" do
57
+ expect(subject.body_allows_any_value?).to be false
58
+ end
59
+ end
60
+
61
+ context "when the body is a non-empty String" do
62
+ subject { Response.from_hash(status: 200, headers: {'Content-Type' => 'text/plain'}, body: 'a string') }
63
+
64
+ it "returns false" do
65
+ expect(subject.body_allows_any_value?).to be false
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,215 @@
1
+ # encoding: utf-8
2
+
3
+ # Ripped from spec/rspec/expectations/differ_spec.rb in rspec-expectations 2.14.3
4
+
5
+ require 'spec_helper'
6
+ require 'ostruct'
7
+ require 'pact/matchers/differ'
8
+
9
+ module Pact
10
+ module Matchers
11
+ describe Differ do
12
+ context "without --color" do
13
+
14
+ let(:differ) { Pact::Matchers::Differ.new }
15
+
16
+ # color disabled context
17
+
18
+ describe '#diff_as_string' do
19
+ subject { differ.diff_as_string(@expected, @actual) }
20
+ it "outputs unified diff of two strings" do
21
+ @expected="foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
22
+ @actual="foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
23
+ expect(subject).to eql(<<-'EOD')
24
+
25
+
26
+ @@ -1,6 +1,6 @@
27
+ foo
28
+ -zap
29
+ bar
30
+ +zap
31
+ this
32
+ is
33
+ soo
34
+ @@ -9,6 +9,5 @@
35
+ equal
36
+ insert
37
+ a
38
+ -another
39
+ line
40
+ EOD
41
+
42
+ end
43
+ if RUBY_VERSION.to_f > 1.9
44
+ it 'copes with encoded strings', :pending => (Diff::LCS::VERSION < '1.2.2') do
45
+ @expected="Tu avec carté {count} itém has".encode('UTF-16LE')
46
+ @actual="Tu avec carte {count} item has".encode('UTF-16LE')
47
+ expect(subject).to eql(<<-EOD.encode('UTF-16LE'))
48
+
49
+ @@ -1,2 +1,2 @@
50
+ -Tu avec carte {count} item has
51
+ +Tu avec carté {count} itém has
52
+ EOD
53
+ end
54
+ it 'copes with encoded strings', :pending => (Diff::LCS::VERSION >= '1.2.2') do
55
+ @expected="Tu avec carté {count} itém has".encode('UTF-16LE')
56
+ @actual="Tu avec carte {count} item has".encode('UTF-16LE')
57
+ expect(subject).to eql 'Could not produce a diff because of the encoding of the string (UTF-16LE)'
58
+ end
59
+ it 'ouputs a message when encountering differently encoded strings' do
60
+ @expected="Tu avec carté {count} itém has".encode('UTF-16LE')
61
+ @actual="Tu avec carte {count} item has"
62
+ expect(subject).to eql 'Could not produce a diff because the encoding of the actual string (UTF-8) differs from the encoding of the expected string (UTF-16LE)'
63
+ end
64
+ end
65
+ end
66
+
67
+ describe '#diff_as_object' do
68
+ it "outputs unified diff message of two objects" do
69
+ animal_class = Class.new do
70
+ def initialize(name, species)
71
+ @name, @species = name, species
72
+ end
73
+
74
+ def inspect
75
+ <<-EOA
76
+ <Animal
77
+ name=#{@name},
78
+ species=#{@species}
79
+ >
80
+ EOA
81
+ end
82
+ end
83
+
84
+ expected = animal_class.new "bob", "giraffe"
85
+ actual = animal_class.new "bob", "tortoise"
86
+
87
+ expected_diff = <<'EOD'
88
+
89
+ @@ -1,5 +1,5 @@
90
+ <Animal
91
+ name=bob,
92
+ - species=tortoise
93
+ + species=giraffe
94
+ >
95
+ EOD
96
+
97
+ diff = differ.diff_as_object(expected,actual)
98
+ expect(diff).to eq expected_diff
99
+ end
100
+
101
+ it "outputs unified diff message of two arrays" do
102
+ expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ]
103
+ actual = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango' , :width, 'very wide' ]
104
+
105
+ expected_diff = <<'EOD'
106
+
107
+
108
+ @@ -5,7 +5,7 @@
109
+ :metasyntactic,
110
+ "variable",
111
+ :delta,
112
+ - "tango",
113
+ + "charlie",
114
+ :width,
115
+ - "very wide"]
116
+ + "quite wide"]
117
+ EOD
118
+
119
+ diff = differ.diff_as_object(expected,actual)
120
+ expect(diff).to eq expected_diff
121
+ end
122
+
123
+ it "outputs unified diff message of two hashes" do
124
+ expected = { :foo => 'bar', :baz => 'quux', :metasyntactic => 'variable', :delta => 'charlie', :width =>'quite wide' }
125
+ actual = { :foo => 'bar', :metasyntactic => 'variable', :delta => 'charlotte', :width =>'quite wide' }
126
+
127
+ expected_diff = <<'EOD'
128
+
129
+ @@ -1,4 +1,5 @@
130
+ -:delta => "charlotte",
131
+ +:baz => "quux",
132
+ +:delta => "charlie",
133
+ :foo => "bar",
134
+ :metasyntactic => "variable",
135
+ :width => "quite wide"
136
+ EOD
137
+
138
+ diff = differ.diff_as_object(expected,actual)
139
+ expect(diff).to eq expected_diff
140
+ end
141
+
142
+ it 'outputs unified diff messaoge of two hashes with differing encoding' do
143
+ expected_diff = %Q{
144
+ @@ -1,2 +1,2 @@
145
+ -"a" => "a"
146
+ #{ (RUBY_VERSION.to_f > 1.8) ? %Q{+"ö" => "ö"} : '+"\303\266" => "\303\266"' }
147
+ }
148
+
149
+ diff = differ.diff_as_object({'ö' => 'ö'}, {'a' => 'a'})
150
+ expect(diff).to eq expected_diff
151
+ end
152
+
153
+ it "outputs unified diff message of two hashes with object keys" do
154
+ expected_diff = %Q{
155
+ @@ -1,2 +1,2 @@
156
+ -["a", "c"] => "b"
157
+ +["d", "c"] => "b"
158
+ }
159
+
160
+ diff = differ.diff_as_object({ ['d','c'] => 'b'}, { ['a','c'] => 'b' })
161
+ expect(diff).to eq expected_diff
162
+ end
163
+
164
+ it "outputs unified diff of single line strings" do
165
+ expected = "this is one string"
166
+ actual = "this is another string"
167
+
168
+ expected_diff = <<'EOD'
169
+
170
+ @@ -1,2 +1,2 @@
171
+ -"this is another string"
172
+ +"this is one string"
173
+ EOD
174
+
175
+ diff = differ.diff_as_object(expected,actual)
176
+ expect(diff).to eq expected_diff
177
+ end
178
+
179
+ it "outputs unified diff of multi line strings" do
180
+ expected = "this is:\n one string"
181
+ actual = "this is:\n another string"
182
+
183
+ expected_diff = <<'EOD'
184
+
185
+ @@ -1,3 +1,3 @@
186
+ this is:
187
+ - another string
188
+ + one string
189
+ EOD
190
+
191
+ diff = differ.diff_as_object(expected,actual)
192
+ expect(diff).to eq expected_diff
193
+ end
194
+ end
195
+ end
196
+
197
+ context "with --color" do
198
+
199
+ let(:differ) { Pact::Matchers::Differ.new(true) }
200
+
201
+ it "outputs colored diffs" do
202
+ expected = "foo bar baz"
203
+ actual = "foo bang baz"
204
+ expected_diff = "\n\e[34m@@ -1,2 +1,2 @@\n\e[0m\e[31m-foo bang baz\n\e[0m\e[32m+foo bar baz\n\e[0m"
205
+
206
+
207
+ diff = differ.diff_as_string(expected,actual)
208
+ expect(diff).to eq expected_diff
209
+ end
210
+ end
211
+
212
+ end
213
+ end
214
+ end
215
+
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ require 'pact/matchers/difference'
3
+
4
+ module Pact
5
+ module Matchers
6
+ describe Difference do
7
+
8
+ describe "#as_json" do
9
+
10
+ context "when something other than a regexp is expected" do
11
+
12
+ subject { Difference.new("apple", 'pear').as_json }
13
+
14
+ it "indicates that the actual was intended 'to eq'" do
15
+ expect(subject).to eq({:EXPECTED => "apple", :ACTUAL => "pear"})
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+ require 'pact/matchers/embedded_diff_formatter'
3
+ require 'pact/matchers/type_difference'
4
+ require 'pact/matchers/expected_type'
5
+ require 'pact/matchers/actual_type'
6
+
7
+ module Pact
8
+ module Matchers
9
+ describe EmbeddedDiffFormatter do
10
+
11
+ let(:diff) do
12
+ {
13
+ :something => TypeDifference.new(ExpectedType.new("Fred"), ActualType.new(1))
14
+ }
15
+ end
16
+
17
+ subject { EmbeddedDiffFormatter.call(diff, options) }
18
+
19
+ let(:options) { { colour: colour }}
20
+ let(:expected_coloured) { '"' + ::Term::ANSIColor.red("expected_type") + '":'}
21
+ let(:actual_coloured) { '"' + ::Term::ANSIColor.green("actual_type") + '":'}
22
+
23
+ describe ".call" do
24
+
25
+ let(:colour) { false }
26
+
27
+ context "when color_enabled is true" do
28
+
29
+ let(:colour) { true }
30
+
31
+ it "returns nicely formatted json" do
32
+ expect(subject.split("\n").size).to eq 6
33
+ end
34
+
35
+ it "returns a string displaying the diff in colour" do
36
+ expect(subject).to include expected_coloured
37
+ expect(subject).to include actual_coloured
38
+ end
39
+ end
40
+
41
+ context "when color_enabled is false" do
42
+
43
+ let(:colour) { false }
44
+
45
+ it "returns nicely formatted json" do
46
+ expect(subject.split("\n").size).to eq 6
47
+ end
48
+
49
+ it "returns a string displaying the diff without colour" do
50
+ expect(subject).to_not include expected_coloured
51
+ expect(subject).to_not include actual_coloured
52
+ end
53
+ end
54
+
55
+ context "with a Pact::Term" do
56
+ let(:diff) { {thing: Difference.new(Pact::Term.new(generate: "Joe", matcher: /Jo/), "Mary")} }
57
+
58
+ xit "displays the matcher from the Pact::Term" do
59
+ expect(subject).to_not include("Pact::Term")
60
+ expect(subject).to include("/Jo/")
61
+ end
62
+
63
+ end
64
+
65
+ context "when no options are specified" do
66
+ subject { EmbeddedDiffFormatter.call(diff) }
67
+
68
+ context "when Pact.configuration.color_enabled is true" do
69
+ it "returns a string displaying the diff in colour" do
70
+ expect(Pact.configuration).to receive(:color_enabled).and_return(true)
71
+ expect(subject).to include expected_coloured
72
+ expect(subject).to include actual_coloured
73
+ end
74
+ end
75
+
76
+ context "when Pact.configuration.color_enabled is false" do
77
+ it "returns a string displaying the diff without colour" do
78
+ expect(Pact.configuration).to receive(:color_enabled).and_return(false)
79
+ expect(subject).to_not include expected_coloured
80
+ expect(subject).to_not include actual_coloured
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+ require 'pact/matchers/index_not_found'
3
+
4
+ module Pact
5
+ describe IndexNotFound do
6
+
7
+ describe "#as_json" do
8
+ it "returns a string representation of the object" do
9
+ expect(subject.as_json).to eq subject.to_s
10
+ end
11
+ end
12
+
13
+ describe "#to_json" do
14
+ it "serialises the object to JSON" do
15
+ expect(subject.to_json).to eq "\"#{subject.to_s}\""
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+ require 'pact/matchers/list_diff_formatter'
3
+ require 'pact/matchers/matchers'
4
+
5
+ # Needed to stop the ai printing in color
6
+ # TODO: fix this!
7
+ AwesomePrint.defaults = {
8
+ plain: true
9
+ }
10
+
11
+ module Pact
12
+ module Matchers
13
+ describe ListDiffFormatter do
14
+
15
+ describe ".call" do
16
+ subject{ ListDiffFormatter.call(diff, {}) }
17
+
18
+ context "when using class based matching" do
19
+ let(:diff) { {root: TypeDifference.new(ExpectedType.new("Fred"), ActualType.new(1)) } }
20
+ let(:expected_output) { <<-EOS
21
+ \tAt:
22
+ \t\t[:root]
23
+ \tExpected type:
24
+ \t\tString
25
+ \tActual type:
26
+ \t\tFixnum
27
+ EOS
28
+ }
29
+
30
+ it "shows the expected and actual classes" do
31
+ expect(subject + "\n").to eq(expected_output)
32
+ end
33
+
34
+ end
35
+
36
+ context "when there is an unmatched regexp" do
37
+ let(:diff) { {root: RegexpDifference.new(/fr.*ed/, "mary") } }
38
+ let(:expected_output) { <<-EOS
39
+ \tAt:
40
+ \t\t[:root]
41
+ \tExpected to match:
42
+ \t\t/fr.*ed/
43
+ \tActual:
44
+ \t\t"mary"
45
+ EOS
46
+ }
47
+ it "shows the expected regexp" do
48
+ expect(subject + "\n").to eq(expected_output)
49
+ end
50
+ end
51
+
52
+ context "when there is a mismatched value" do
53
+ let(:diff) { {root: {"blah" => { 1 => Difference.new("alphabet", "woozle")}}} }
54
+ let(:expected_output) { ""}
55
+
56
+ it "includes the expected value" do
57
+ expect(subject).to match(/Expected:.*"alphabet"/m)
58
+ end
59
+ it "includes the actual value" do
60
+ expect(subject).to match(/Actual:.*"woozle"/m)
61
+ end
62
+
63
+ it "includes the path" do
64
+ expect(subject).to include('[:root]["blah"][1]')
65
+ end
66
+ end
67
+
68
+ context "when there is a missing key" do
69
+ let(:expected_hash) { {"abc" => {"def" => [1,2]}}}
70
+ let(:diff) { {root: {"blah" => { 1 => Difference.new(expected_hash, Pact::KeyNotFound.new )}}} }
71
+ let(:expected_output) { ""}
72
+
73
+ it "includes the expected value" do
74
+ expect(subject).to match(/Missing key with value\:.*\{/m)
75
+ end
76
+
77
+ it "includes the path" do
78
+ expect(subject).to include('[:root]["blah"][1]')
79
+ end
80
+ end
81
+
82
+ context "when there is a missing index" do
83
+ let(:diff) { [NoDiffIndicator.new, Difference.new(1, IndexNotFound.new )]}
84
+ it "includes the expected value" do
85
+ expect(subject).to match(/Missing.*1/m)
86
+ end
87
+
88
+ it "includes the path" do
89
+ expect(subject).to include('[1]')
90
+ end
91
+ end
92
+
93
+ context "when there is an unexpected index" do
94
+ let(:diff) { [NoDiffIndicator.new, Difference.new(UnexpectedIndex.new, 2), Difference.new(UnexpectedIndex.new, "b")]}
95
+ it "includes the unexpected value" do
96
+ expect(subject).to include("Array contained unexpected item:")
97
+ end
98
+
99
+ it "includes the path" do
100
+ expect(subject).to include('[1]')
101
+ expect(subject).to include('[2]')
102
+ end
103
+ end
104
+
105
+ context "when there is an unexpected key" do
106
+ let(:diff) { {"blah" => Difference.new(UnexpectedKey.new, "b")}}
107
+ it "includes the unexpected key" do
108
+ expect(subject).to include("Hash contained unexpected key with value:")
109
+ end
110
+
111
+ it "includes the path" do
112
+ expect(subject).to include('["blah"]')
113
+ end
114
+ end
115
+
116
+ end
117
+
118
+ end
119
+ end
120
+ end