super_diff 0.1.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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +174 -0
  3. data/lib/super_diff/csi/color_helper.rb +52 -0
  4. data/lib/super_diff/csi/eight_bit_color.rb +131 -0
  5. data/lib/super_diff/csi/eight_bit_sequence.rb +27 -0
  6. data/lib/super_diff/csi/four_bit_color.rb +80 -0
  7. data/lib/super_diff/csi/four_bit_sequence.rb +24 -0
  8. data/lib/super_diff/csi/reset_sequence.rb +9 -0
  9. data/lib/super_diff/csi/sequence.rb +22 -0
  10. data/lib/super_diff/csi/twenty_four_bit_color.rb +41 -0
  11. data/lib/super_diff/csi/twenty_four_bit_sequence.rb +27 -0
  12. data/lib/super_diff/csi.rb +29 -0
  13. data/lib/super_diff/diff_formatter.rb +37 -0
  14. data/lib/super_diff/diff_formatters/array.rb +21 -0
  15. data/lib/super_diff/diff_formatters/base.rb +37 -0
  16. data/lib/super_diff/diff_formatters/collection.rb +107 -0
  17. data/lib/super_diff/diff_formatters/hash.rb +34 -0
  18. data/lib/super_diff/diff_formatters/multi_line_string.rb +31 -0
  19. data/lib/super_diff/diff_formatters/object.rb +27 -0
  20. data/lib/super_diff/diff_formatters.rb +5 -0
  21. data/lib/super_diff/differ.rb +48 -0
  22. data/lib/super_diff/differs/array.rb +24 -0
  23. data/lib/super_diff/differs/base.rb +42 -0
  24. data/lib/super_diff/differs/empty.rb +13 -0
  25. data/lib/super_diff/differs/hash.rb +24 -0
  26. data/lib/super_diff/differs/multi_line_string.rb +27 -0
  27. data/lib/super_diff/differs/object.rb +68 -0
  28. data/lib/super_diff/differs.rb +5 -0
  29. data/lib/super_diff/equality_matcher.rb +45 -0
  30. data/lib/super_diff/equality_matchers/array.rb +44 -0
  31. data/lib/super_diff/equality_matchers/base.rb +42 -0
  32. data/lib/super_diff/equality_matchers/hash.rb +44 -0
  33. data/lib/super_diff/equality_matchers/multi_line_string.rb +44 -0
  34. data/lib/super_diff/equality_matchers/object.rb +18 -0
  35. data/lib/super_diff/equality_matchers/single_line_string.rb +28 -0
  36. data/lib/super_diff/equality_matchers.rb +5 -0
  37. data/lib/super_diff/errors.rb +20 -0
  38. data/lib/super_diff/helpers.rb +96 -0
  39. data/lib/super_diff/operation_sequences/array.rb +14 -0
  40. data/lib/super_diff/operation_sequences/base.rb +11 -0
  41. data/lib/super_diff/operation_sequences/hash.rb +14 -0
  42. data/lib/super_diff/operation_sequences/object.rb +14 -0
  43. data/lib/super_diff/operational_sequencer.rb +43 -0
  44. data/lib/super_diff/operational_sequencers/array.rb +127 -0
  45. data/lib/super_diff/operational_sequencers/base.rb +97 -0
  46. data/lib/super_diff/operational_sequencers/hash.rb +82 -0
  47. data/lib/super_diff/operational_sequencers/multi_line_string.rb +85 -0
  48. data/lib/super_diff/operational_sequencers/object.rb +96 -0
  49. data/lib/super_diff/operational_sequencers.rb +5 -0
  50. data/lib/super_diff/operations/binary_operation.rb +47 -0
  51. data/lib/super_diff/operations/unary_operation.rb +25 -0
  52. data/lib/super_diff/rspec/differ.rb +30 -0
  53. data/lib/super_diff/rspec/monkey_patches.rb +122 -0
  54. data/lib/super_diff/rspec.rb +19 -0
  55. data/lib/super_diff/value_inspection.rb +11 -0
  56. data/lib/super_diff/version.rb +3 -0
  57. data/lib/super_diff.rb +50 -0
  58. data/spec/examples.txt +46 -0
  59. data/spec/integration/rspec_spec.rb +261 -0
  60. data/spec/spec_helper.rb +44 -0
  61. data/spec/support/color_helper.rb +49 -0
  62. data/spec/support/command_runner.rb +279 -0
  63. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +76 -0
  64. data/spec/support/person.rb +23 -0
  65. data/spec/support/person_diff_formatter.rb +15 -0
  66. data/spec/support/person_operation_sequence.rb +14 -0
  67. data/spec/support/person_operational_sequencer.rb +19 -0
  68. data/spec/unit/equality_matcher_spec.rb +1233 -0
  69. data/super_diff.gemspec +23 -0
  70. metadata +153 -0
@@ -0,0 +1,261 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Integration with RSpec", type: :integration do
4
+ context "comparing two different integers" do
5
+ it "produces the correct output" do
6
+ test = <<~TEST
7
+ expect(1).to eq(42)
8
+ TEST
9
+
10
+ expected_output = <<~OUTPUT
11
+ expected: 42
12
+ got: 1
13
+ OUTPUT
14
+
15
+ expect(test).to produce_output_when_run(expected_output)
16
+ end
17
+ end
18
+
19
+ context "comparing two different symbols" do
20
+ it "produces the correct output" do
21
+ test = <<~TEST
22
+ expect(:bar).to eq(:foo)
23
+ TEST
24
+
25
+ expected_output = <<~OUTPUT
26
+ expected: :foo
27
+ got: :bar
28
+ OUTPUT
29
+
30
+ expect(test).to produce_output_when_run(expected_output)
31
+ end
32
+ end
33
+
34
+ context "comparing two different single-line strings" do
35
+ it "produces the correct output" do
36
+ test = <<~TEST
37
+ expect("Jennifer").to eq("Marty")
38
+ TEST
39
+
40
+ expected_output = <<~OUTPUT
41
+ expected: "Marty"
42
+ got: "Jennifer"
43
+ OUTPUT
44
+
45
+ expect(test).to produce_output_when_run(expected_output)
46
+ end
47
+ end
48
+
49
+ context "comparing two closely different multi-line strings" do
50
+ it "produces the correct output" do
51
+ test = <<~TEST
52
+ expected = "This is a line\nAnd that's a line\nAnd there's a line too"
53
+ actual = "This is a line\nSomething completely different\nAnd there's a line too"
54
+ expect(actual).to eq(expected)
55
+ TEST
56
+
57
+ expected_output = <<~OUTPUT
58
+ Diff:
59
+
60
+ #{
61
+ colored do
62
+ plain_line %( This is a line⏎)
63
+ red_line %(- And that's a line⏎)
64
+ green_line %(+ Something completely different⏎)
65
+ plain_line %( And there's a line too)
66
+ end
67
+ }
68
+ OUTPUT
69
+
70
+ expect(test).to produce_output_when_run(expected_output)
71
+ end
72
+ end
73
+
74
+ context "comparing two completely different multi-line strings" do
75
+ it "produces the correct output" do
76
+ test = <<~TEST
77
+ expected = "This is a line\nAnd that's a line\n"
78
+ actual = "Something completely different\nAnd something else too\n"
79
+ expect(actual).to eq(expected)
80
+ TEST
81
+
82
+ expected_output = <<~OUTPUT
83
+ Diff:
84
+
85
+ #{
86
+ colored do
87
+ red_line %(- This is a line⏎)
88
+ red_line %(- And that's a line⏎)
89
+ green_line %(+ Something completely different⏎)
90
+ green_line %(+ And something else too⏎)
91
+ end
92
+ }
93
+ OUTPUT
94
+
95
+ expect(test).to produce_output_when_run(expected_output)
96
+ end
97
+ end
98
+
99
+ context "comparing two arrays with other data structures inside" do
100
+ it "produces the correct output" do
101
+ test = <<~TEST
102
+ expected = [
103
+ [
104
+ :h1,
105
+ [:span, [:text, "Hello world"]],
106
+ {
107
+ class: "header",
108
+ data: {
109
+ "sticky" => true,
110
+ person: SuperDiff::Test::Person.new(name: "Marty")
111
+ }
112
+ }
113
+ ]
114
+ ]
115
+ actual = [
116
+ [
117
+ :h2,
118
+ [:span, [:text, "Goodbye world"]],
119
+ {
120
+ id: "hero",
121
+ class: "header",
122
+ data: {
123
+ "sticky" => false,
124
+ role: "deprecated",
125
+ person: SuperDiff::Test::Person.new(name: "Doc")
126
+ }
127
+ }
128
+ ],
129
+ :br
130
+ ]
131
+ expect(actual).to eq(expected)
132
+ TEST
133
+
134
+ expected_output = <<~OUTPUT
135
+ Diff:
136
+
137
+ #{
138
+ colored do
139
+ plain_line %( [)
140
+ plain_line %( [)
141
+ red_line %(- :h1,)
142
+ green_line %(+ :h2,)
143
+ plain_line %( [)
144
+ plain_line %( :span,)
145
+ plain_line %( [)
146
+ plain_line %( :text,)
147
+ red_line %(- "Hello world")
148
+ green_line %(+ "Goodbye world")
149
+ plain_line %( ])
150
+ plain_line %( ],)
151
+ plain_line %( {)
152
+ plain_line %( class: "header",)
153
+ plain_line %( data: {)
154
+ red_line %(- "sticky" => true,)
155
+ green_line %(+ "sticky" => false,)
156
+ plain_line %( person: #<SuperDiff::Test::Person {)
157
+ red_line %(- name: "Marty")
158
+ green_line %(+ name: "Doc")
159
+ plain_line %( }>,)
160
+ green_line %(+ role: "deprecated")
161
+ plain_line %( },)
162
+ green_line %(+ id: "hero")
163
+ plain_line %( })
164
+ plain_line %( ],)
165
+ green_line %(+ :br)
166
+ plain_line %( ])
167
+ end
168
+ }
169
+ OUTPUT
170
+
171
+ expect(test).to produce_output_when_run(expected_output)
172
+ end
173
+ end
174
+
175
+ context "comparing two hashes with other data structures inside" do
176
+ it "produces the correct output" do
177
+ test = <<~TEST
178
+ expected = {
179
+ customer: {
180
+ person: SuperDiff::Test::Person.new(name: "Marty McFly"),
181
+ shipping_address: {
182
+ line_1: "123 Main St.",
183
+ city: "Hill Valley",
184
+ state: "CA",
185
+ zip: "90382"
186
+ }
187
+ },
188
+ items: [
189
+ {
190
+ name: "Fender Stratocaster",
191
+ cost: 100_000,
192
+ options: ["red", "blue", "green"]
193
+ },
194
+ { name: "Chevy 4x4" }
195
+ ]
196
+ }
197
+ actual = {
198
+ customer: {
199
+ person: SuperDiff::Test::Person.new(name: "Marty McFly, Jr."),
200
+ shipping_address: {
201
+ line_1: "456 Ponderosa Ct.",
202
+ city: "Hill Valley",
203
+ state: "CA",
204
+ zip: "90382"
205
+ }
206
+ },
207
+ items: [
208
+ {
209
+ name: "Fender Stratocaster",
210
+ cost: 100_000,
211
+ options: ["red", "blue", "green"]
212
+ },
213
+ { name: "Mattel Hoverboard" }
214
+ ]
215
+ }
216
+ expect(actual).to eq(expected)
217
+ TEST
218
+
219
+ expected_output = <<~OUTPUT
220
+ Diff:
221
+
222
+ #{
223
+ colored do
224
+ plain_line %( {)
225
+ plain_line %( customer: {)
226
+ plain_line %( person: #<SuperDiff::Test::Person {)
227
+ red_line %(- name: "Marty McFly")
228
+ green_line %(+ name: "Marty McFly, Jr.")
229
+ plain_line %( }>,)
230
+ plain_line %( shipping_address: {)
231
+ red_line %(- line_1: "123 Main St.",)
232
+ green_line %(+ line_1: "456 Ponderosa Ct.",)
233
+ plain_line %( city: "Hill Valley",)
234
+ plain_line %( state: "CA",)
235
+ plain_line %( zip: "90382")
236
+ plain_line %( })
237
+ plain_line %( },)
238
+ plain_line %( items: [)
239
+ plain_line %( {)
240
+ plain_line %( name: "Fender Stratocaster",)
241
+ plain_line %( cost: 100000,)
242
+ plain_line %( options: ["red", "blue", "green"])
243
+ plain_line %( },)
244
+ plain_line %( {)
245
+ red_line %(- name: "Chevy 4x4")
246
+ green_line %(+ name: "Mattel Hoverboard")
247
+ plain_line %( })
248
+ plain_line %( ])
249
+ plain_line %( })
250
+ end
251
+ }
252
+ OUTPUT
253
+
254
+ expect(test).to produce_output_when_run(expected_output)
255
+ end
256
+ end
257
+
258
+ def colored(&block)
259
+ SuperDiff::Tests::Colorizer.call(&block).chomp
260
+ end
261
+ end
@@ -0,0 +1,44 @@
1
+ require_relative "../lib/super_diff"
2
+ require_relative "../lib/super_diff/rspec"
3
+
4
+ begin
5
+ require "pry-byebug"
6
+ rescue LoadError
7
+ end
8
+
9
+ begin
10
+ require "pry-nav"
11
+ rescue LoadError
12
+ end
13
+
14
+ Dir.glob(File.expand_path("support/**/*.rb", __dir__)).each do |file|
15
+ require file
16
+ end
17
+
18
+ RSpec.configure do |config|
19
+ config.include(SuperDiff::IntegrationTests, type: :integration)
20
+
21
+ config.expect_with :rspec do |expectations|
22
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
23
+ expectations.max_formatted_output_length = nil
24
+ end
25
+
26
+ config.mock_with :rspec do |mocks|
27
+ mocks.verify_partial_doubles = true
28
+ end
29
+
30
+ config.shared_context_metadata_behavior = :apply_to_host_groups
31
+ config.filter_run_when_matching :focus
32
+ config.example_status_persistence_file_path = "spec/examples.txt"
33
+ config.disable_monkey_patching!
34
+ config.warnings = true
35
+
36
+ if config.files_to_run.one?
37
+ config.default_formatter = "documentation"
38
+ end
39
+
40
+ config.order = :random
41
+ Kernel.srand config.seed
42
+ end
43
+
44
+ require "pp"
@@ -0,0 +1,49 @@
1
+ module SuperDiff
2
+ module Tests
3
+ class Colorizer < BasicObject
4
+ def self.call(&block)
5
+ new.instance_eval(&block).to_s
6
+ end
7
+
8
+ def initialize
9
+ @string = ""
10
+ end
11
+
12
+ def method_missing(name, *args, &block)
13
+ match = name.to_s.match(/\A(.+)_line\Z/)
14
+
15
+ if match
16
+ real_name = match.captures[0]
17
+
18
+ if Csi::ColorHelper.respond_to?(real_name)
19
+ addition = Csi::ColorHelper.public_send(real_name, *args)
20
+
21
+ if match
22
+ addition << "\n"
23
+ end
24
+
25
+ @string << addition
26
+ else
27
+ super
28
+ end
29
+ else
30
+ super
31
+ end
32
+ end
33
+
34
+ def respond_to_missing?(name, include_private = false)
35
+ match = name.to_s.match(/\A(.+)_line\Z/)
36
+
37
+ if match
38
+ Csi::ColorHelper.respond_to?(match.captures[0]) || super
39
+ else
40
+ super
41
+ end
42
+ end
43
+
44
+ def to_s
45
+ @string.strip
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,279 @@
1
+ require "childprocess"
2
+
3
+ require "English"
4
+ require "shellwords"
5
+ require "timeout"
6
+
7
+ class CommandRunner
8
+ module OutputHelpers
9
+ def self.divider(title = "")
10
+ total_length = 72
11
+ start_length = 3
12
+
13
+ string = ""
14
+ string << ("-" * start_length)
15
+ string << title
16
+ string << "-" * (total_length - start_length - title.length)
17
+ string << "\n"
18
+ string
19
+ end
20
+ end
21
+
22
+ class CommandFailedError < StandardError
23
+ def self.create(command:, exit_status:, output:, message: nil)
24
+ allocate.tap do |error|
25
+ error.command = command
26
+ error.exit_status = exit_status
27
+ error.output = output
28
+ error.__send__(:initialize, message)
29
+ end
30
+ end
31
+
32
+ attr_accessor :command, :exit_status, :output
33
+
34
+ def initialize(message = nil)
35
+ super(message || build_message)
36
+ end
37
+
38
+ private
39
+
40
+ def build_message
41
+ message = <<-MESSAGE
42
+ Command #{command.inspect} failed, exiting with status #{exit_status}.
43
+ MESSAGE
44
+
45
+ if output
46
+ message << <<-MESSAGE
47
+ Output:
48
+ #{OutputHelpers.divider("START") + output + OutputHelpers.divider("END")}
49
+ MESSAGE
50
+ end
51
+
52
+ message
53
+ end
54
+ end
55
+
56
+ class CommandTimedOutError < StandardError
57
+ def self.create(command:, timeout:, output:, message: nil)
58
+ allocate.tap do |error|
59
+ error.command = command
60
+ error.timeout = timeout
61
+ error.output = output
62
+ error.__send__(:initialize, message)
63
+ end
64
+ end
65
+
66
+ attr_accessor :command, :timeout, :output
67
+
68
+ def initialize(message = nil)
69
+ super(message || build_message)
70
+ end
71
+
72
+ private
73
+
74
+ def build_message
75
+ message = <<-MESSAGE
76
+ Command #{formatted_command.inspect} timed out after #{timeout} seconds.
77
+ MESSAGE
78
+
79
+ if output
80
+ message << <<-MESSAGE
81
+ Output:
82
+ #{OutputHelpers.divider("START") + output + OutputHelpers.divider("END")}
83
+ MESSAGE
84
+ end
85
+
86
+ message
87
+ end
88
+ end
89
+
90
+ def self.run(*args)
91
+ new(*args).tap do |runner|
92
+ yield runner if block_given?
93
+ runner.run
94
+ end
95
+ end
96
+
97
+ def self.run!(*args)
98
+ run(*args) do |runner|
99
+ runner.run_successfully = true
100
+ yield runner if block_given?
101
+ end
102
+ end
103
+
104
+ attr_reader :status, :options, :env
105
+ attr_accessor :run_quickly, :run_successfully, :retries,
106
+ :timeout
107
+
108
+ def initialize(*args)
109
+ @reader, @writer = IO.pipe
110
+ options = (args.last.is_a?(Hash) ? args.pop : {})
111
+ @args = args
112
+ @options = options.merge(
113
+ err: [:child, :out],
114
+ out: @writer,
115
+ )
116
+ @env = extract_env_from(@options)
117
+
118
+ @process = ChildProcess.build(*command)
119
+ @process.io.stdout = @process.io.stderr = @writer
120
+
121
+ @wrapper = -> (block) { block.call }
122
+ self.directory = Dir.pwd
123
+ @run_quickly = false
124
+ @run_successfully = false
125
+ @retries = 1
126
+ @num_times_run = 0
127
+ @timeout = 10
128
+ end
129
+
130
+ def around_command(&block)
131
+ @wrapper = block
132
+ end
133
+
134
+ def directory
135
+ @options[:chdir]
136
+ end
137
+
138
+ def directory=(directory)
139
+ @options[:chdir] = (directory || Dir.pwd).to_s
140
+ end
141
+
142
+ def formatted_command
143
+ [formatted_env, Shellwords.join(command)].
144
+ reject(&:empty?).
145
+ join(" ")
146
+ end
147
+
148
+ def run
149
+ possibly_running_quickly do
150
+ run_with_debugging
151
+
152
+ if run_successfully && !success?
153
+ fail!
154
+ end
155
+ end
156
+
157
+ self
158
+ end
159
+
160
+ def stop
161
+ if !writer.closed?
162
+ writer.close
163
+ end
164
+ end
165
+
166
+ def output
167
+ @_output ||= begin
168
+ stop
169
+ reader.read
170
+ end
171
+ end
172
+
173
+ def elided_output
174
+ lines = output.split(/\n/)
175
+ new_lines = lines[0..4]
176
+
177
+ if lines.size > 10
178
+ new_lines << "(...#{lines.size - 10} more lines...)"
179
+ end
180
+
181
+ new_lines << lines[-5..-1]
182
+ new_lines.join("\n")
183
+ end
184
+
185
+ def success?
186
+ status.success?
187
+ end
188
+
189
+ def exit_status
190
+ status.exitstatus
191
+ end
192
+
193
+ def fail!
194
+ raise CommandFailedError.create(
195
+ command: formatted_command,
196
+ exit_status: exit_status,
197
+ output: output,
198
+ )
199
+ end
200
+
201
+ def has_output?(expected_output)
202
+ if expected_output.is_a?(Regexp)
203
+ output =~ expected_output
204
+ else
205
+ output.include?(expected_output)
206
+ end
207
+ end
208
+
209
+ protected
210
+
211
+ attr_reader :args, :reader, :writer, :wrapper, :process
212
+
213
+ private
214
+
215
+ def extract_env_from(options)
216
+ options.delete(:env) { {} }.reduce({}) do |hash, (key, value)|
217
+ hash.merge(key.to_s => value)
218
+ end
219
+ end
220
+
221
+ def command
222
+ args.flatten.flat_map { |word| Shellwords.split(word) }
223
+ end
224
+
225
+ def formatted_env
226
+ env.map { |key, value| "#{key}=#{value.inspect}" }.join(" ")
227
+ end
228
+
229
+ def run_freely
230
+ process.start
231
+ process.wait
232
+ end
233
+
234
+ def run_with_wrapper
235
+ wrapper.call(method(:run_freely))
236
+ end
237
+
238
+ def run_with_debugging
239
+ debug { "\n\e[33mChanging to directory:\e[0m #{directory}" }
240
+ debug { "\e[32mRunning command:\e[0m #{formatted_command}" }
241
+
242
+ run_with_wrapper
243
+
244
+ debug do
245
+ "\n" +
246
+ OutputHelpers.divider("START") +
247
+ output +
248
+ OutputHelpers.divider("END")
249
+ end
250
+ end
251
+
252
+ def possibly_running_quickly(&block)
253
+ if run_quickly
254
+ begin
255
+ Timeout.timeout(timeout, &block)
256
+ rescue Timeout::Error
257
+ stop
258
+
259
+ raise CommandTimedOutError.create(
260
+ command: formatted_command,
261
+ timeout: timeout,
262
+ output: output,
263
+ )
264
+ end
265
+ else
266
+ yield
267
+ end
268
+ end
269
+
270
+ def debugging_enabled?
271
+ ENV["DEBUG_COMMANDS"] == "1"
272
+ end
273
+
274
+ def debug
275
+ if debugging_enabled?
276
+ puts yield
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,76 @@
1
+ module SuperDiff
2
+ module IntegrationTests
3
+ def produce_output_when_run(output)
4
+ ProduceOutputWhenRunMatcher.new(output)
5
+ end
6
+
7
+ class ProduceOutputWhenRunMatcher
8
+ PROJECT_DIRECTORY = Pathname.new("../../../../../").expand_path(__FILE__)
9
+ TEMP_DIRECTORY = PROJECT_DIRECTORY.join("tmp")
10
+
11
+ def initialize(expected_output)
12
+ @expected_output =
13
+ expected_output.
14
+ strip.
15
+ split(/(\n+)/).
16
+ map { |line| line =~ /\n+/ ? line : (" " * 7) + line }.
17
+ join
18
+ end
19
+
20
+ def matches?(test)
21
+ @test = test.strip
22
+ TEMP_DIRECTORY.mkpath
23
+ actual_output.include?(expected_output)
24
+ end
25
+
26
+ def failure_message
27
+ "Expected test to produce output, but it did not.\n\n" +
28
+ "Expected output:\n\n" +
29
+ CommandRunner::OutputHelpers.divider("START") +
30
+ expected_output + "\n" +
31
+ CommandRunner::OutputHelpers.divider("END") +
32
+ "\n" +
33
+ "Actual output:\n\n" +
34
+ CommandRunner::OutputHelpers.divider("START") +
35
+ actual_output + "\n" +
36
+ CommandRunner::OutputHelpers.divider("END")
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :expected_output, :test
42
+
43
+ def actual_output
44
+ @_actual_output ||=
45
+ CommandRunner.run("rspec", tempfile.to_s).output.strip
46
+ end
47
+
48
+ def tempfile
49
+ @_tempfile =
50
+ TEMP_DIRECTORY.join("acceptance_spec.rb").
51
+ tap { |tempfile| tempfile.write(program) }
52
+ end
53
+
54
+ def program
55
+ <<~PROGRAM
56
+ require "#{PROJECT_DIRECTORY.join("lib/super_diff/rspec.rb")}"
57
+ require "#{PROJECT_DIRECTORY.join("spec/support/person.rb")}"
58
+ require "#{PROJECT_DIRECTORY.join("spec/support/person_diff_formatter.rb")}"
59
+ require "#{PROJECT_DIRECTORY.join("spec/support/person_operation_sequence.rb")}"
60
+ require "#{PROJECT_DIRECTORY.join("spec/support/person_operational_sequencer.rb")}"
61
+
62
+ SuperDiff::RSpec.configure do |config|
63
+ config.extra_operational_sequencer_classes << SuperDiff::Test::PersonOperationalSequencer
64
+ config.extra_diff_formatter_classes << SuperDiff::Test::PersonDiffFormatter
65
+ end
66
+
67
+ RSpec.describe "test" do
68
+ it "passes" do
69
+ #{test}
70
+ end
71
+ end
72
+ PROGRAM
73
+ end
74
+ end
75
+ end
76
+ end