super_diff 0.1.0 → 0.2.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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +117 -89
  3. data/lib/super_diff.rb +33 -47
  4. data/lib/super_diff/active_record.rb +41 -0
  5. data/lib/super_diff/active_record/diff_formatters.rb +10 -0
  6. data/lib/super_diff/active_record/diff_formatters/active_record_relation.rb +23 -0
  7. data/lib/super_diff/active_record/differs.rb +10 -0
  8. data/lib/super_diff/active_record/differs/active_record_relation.rb +30 -0
  9. data/lib/super_diff/active_record/object_inspection.rb +14 -0
  10. data/lib/super_diff/active_record/object_inspection/inspectors.rb +16 -0
  11. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_model.rb +38 -0
  12. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_relation.rb +18 -0
  13. data/lib/super_diff/active_record/object_inspection/map_extension.rb +18 -0
  14. data/lib/super_diff/active_record/operation_sequences.rb +10 -0
  15. data/lib/super_diff/active_record/operation_sequences/active_record_relation.rb +16 -0
  16. data/lib/super_diff/active_record/operational_sequencers.rb +14 -0
  17. data/lib/super_diff/active_record/operational_sequencers/active_record_model.rb +19 -0
  18. data/lib/super_diff/active_record/operational_sequencers/active_record_relation.rb +24 -0
  19. data/lib/super_diff/active_support.rb +33 -0
  20. data/lib/super_diff/active_support/diff_formatters.rb +10 -0
  21. data/lib/super_diff/active_support/diff_formatters/hash_with_indifferent_access.rb +36 -0
  22. data/lib/super_diff/active_support/differs.rb +10 -0
  23. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +36 -0
  24. data/lib/super_diff/active_support/object_inspection.rb +14 -0
  25. data/lib/super_diff/active_support/object_inspection/inspectors.rb +12 -0
  26. data/lib/super_diff/active_support/object_inspection/inspectors/hash_with_indifferent_access.rb +18 -0
  27. data/lib/super_diff/active_support/object_inspection/map_extension.rb +15 -0
  28. data/lib/super_diff/active_support/operation_sequences.rb +10 -0
  29. data/lib/super_diff/active_support/operation_sequences/hash_with_indifferent_access.rb +16 -0
  30. data/lib/super_diff/active_support/operational_sequencers.rb +10 -0
  31. data/lib/super_diff/active_support/operational_sequencers/hash_with_indifferent_access.rb +21 -0
  32. data/lib/super_diff/colorized_document_extensions.rb +17 -0
  33. data/lib/super_diff/csi.rb +45 -15
  34. data/lib/super_diff/csi/bold_sequence.rb +9 -0
  35. data/lib/super_diff/csi/color.rb +62 -0
  36. data/lib/super_diff/csi/color_sequence_block.rb +28 -0
  37. data/lib/super_diff/csi/colorized_document.rb +72 -0
  38. data/lib/super_diff/csi/document.rb +183 -0
  39. data/lib/super_diff/csi/eight_bit_color.rb +72 -26
  40. data/lib/super_diff/csi/four_bit_color.rb +63 -29
  41. data/lib/super_diff/csi/twenty_four_bit_color.rb +79 -18
  42. data/lib/super_diff/csi/uncolorized_document.rb +29 -0
  43. data/lib/super_diff/diff_formatter.rb +10 -15
  44. data/lib/super_diff/diff_formatters.rb +10 -1
  45. data/lib/super_diff/diff_formatters/base.rb +12 -17
  46. data/lib/super_diff/diff_formatters/collection.rb +81 -50
  47. data/lib/super_diff/diff_formatters/{object.rb → custom_object.rb} +12 -9
  48. data/lib/super_diff/diff_formatters/default_object.rb +48 -0
  49. data/lib/super_diff/diff_formatters/multiline_string.rb +31 -0
  50. data/lib/super_diff/differ.rb +35 -32
  51. data/lib/super_diff/differs.rb +16 -1
  52. data/lib/super_diff/differs/array.rb +2 -2
  53. data/lib/super_diff/differs/base.rb +11 -21
  54. data/lib/super_diff/differs/custom_object.rb +26 -0
  55. data/lib/super_diff/differs/default_object.rb +25 -0
  56. data/lib/super_diff/differs/empty.rb +1 -1
  57. data/lib/super_diff/differs/hash.rb +2 -2
  58. data/lib/super_diff/differs/{multi_line_string.rb → multiline_string.rb} +6 -5
  59. data/lib/super_diff/equality_matcher.rb +9 -22
  60. data/lib/super_diff/equality_matchers.rb +19 -1
  61. data/lib/super_diff/equality_matchers/array.rb +6 -4
  62. data/lib/super_diff/equality_matchers/base.rb +8 -16
  63. data/lib/super_diff/equality_matchers/default.rb +60 -0
  64. data/lib/super_diff/equality_matchers/hash.rb +6 -4
  65. data/lib/super_diff/equality_matchers/{multi_line_string.rb → multiline_string.rb} +9 -6
  66. data/lib/super_diff/equality_matchers/primitive.rb +34 -0
  67. data/lib/super_diff/equality_matchers/{single_line_string.rb → singleline_string.rb} +7 -5
  68. data/lib/super_diff/helpers.rb +17 -81
  69. data/lib/super_diff/no_differ_available_error.rb +22 -0
  70. data/lib/super_diff/{errors.rb → no_operational_sequencer_available_error.rb} +0 -0
  71. data/lib/super_diff/object_inspection.rb +24 -0
  72. data/lib/super_diff/object_inspection/inspection_tree.rb +144 -0
  73. data/lib/super_diff/object_inspection/inspector.rb +27 -0
  74. data/lib/super_diff/object_inspection/inspectors.rb +18 -0
  75. data/lib/super_diff/object_inspection/inspectors/array.rb +22 -0
  76. data/lib/super_diff/object_inspection/inspectors/custom_object.rb +27 -0
  77. data/lib/super_diff/object_inspection/inspectors/default_object.rb +47 -0
  78. data/lib/super_diff/object_inspection/inspectors/hash.rb +22 -0
  79. data/lib/super_diff/object_inspection/inspectors/primitive.rb +13 -0
  80. data/lib/super_diff/object_inspection/inspectors/string.rb +13 -0
  81. data/lib/super_diff/object_inspection/map.rb +28 -0
  82. data/lib/super_diff/object_inspection/nodes.rb +49 -0
  83. data/lib/super_diff/object_inspection/nodes/base.rb +86 -0
  84. data/lib/super_diff/object_inspection/nodes/break.rb +15 -0
  85. data/lib/super_diff/object_inspection/nodes/inspection.rb +15 -0
  86. data/lib/super_diff/object_inspection/nodes/nesting.rb +16 -0
  87. data/lib/super_diff/object_inspection/nodes/text.rb +15 -0
  88. data/lib/super_diff/object_inspection/nodes/when_empty.rb +30 -0
  89. data/lib/super_diff/object_inspection/nodes/when_multiline.rb +22 -0
  90. data/lib/super_diff/object_inspection/nodes/when_non_empty.rb +30 -0
  91. data/lib/super_diff/object_inspection/nodes/when_singleline.rb +24 -0
  92. data/lib/super_diff/operation_sequences.rb +9 -0
  93. data/lib/super_diff/operation_sequences/base.rb +1 -1
  94. data/lib/super_diff/operation_sequences/{object.rb → custom_object.rb} +4 -3
  95. data/lib/super_diff/operation_sequences/default_object.rb +25 -0
  96. data/lib/super_diff/operational_sequencer.rb +23 -18
  97. data/lib/super_diff/operational_sequencers.rb +12 -1
  98. data/lib/super_diff/operational_sequencers/array.rb +65 -62
  99. data/lib/super_diff/operational_sequencers/base.rb +18 -26
  100. data/lib/super_diff/operational_sequencers/custom_object.rb +35 -0
  101. data/lib/super_diff/operational_sequencers/{object.rb → default_object.rb} +21 -11
  102. data/lib/super_diff/operational_sequencers/hash.rb +8 -5
  103. data/lib/super_diff/operational_sequencers/{multi_line_string.rb → multiline_string.rb} +11 -6
  104. data/lib/super_diff/operations.rb +6 -0
  105. data/lib/super_diff/operations/binary_operation.rb +14 -34
  106. data/lib/super_diff/operations/unary_operation.rb +11 -2
  107. data/lib/super_diff/rails.rb +1 -0
  108. data/lib/super_diff/recursion_guard.rb +47 -0
  109. data/lib/super_diff/rspec-rails.rb +2 -0
  110. data/lib/super_diff/rspec.rb +52 -8
  111. data/lib/super_diff/rspec/augmented_matcher.rb +98 -0
  112. data/lib/super_diff/rspec/configuration.rb +31 -0
  113. data/lib/super_diff/rspec/differ.rb +60 -16
  114. data/lib/super_diff/rspec/differs.rb +13 -0
  115. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +23 -0
  116. data/lib/super_diff/rspec/differs/partial_array.rb +22 -0
  117. data/lib/super_diff/rspec/differs/partial_hash.rb +22 -0
  118. data/lib/super_diff/rspec/differs/partial_object.rb +22 -0
  119. data/lib/super_diff/rspec/matcher_text_builders.rb +24 -0
  120. data/lib/super_diff/rspec/matcher_text_builders/base.rb +155 -0
  121. data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +78 -0
  122. data/lib/super_diff/rspec/matcher_text_builders/contain_exactly.rb +14 -0
  123. data/lib/super_diff/rspec/matcher_text_builders/match.rb +23 -0
  124. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +13 -0
  125. data/lib/super_diff/rspec/matcher_text_builders/respond_to.rb +99 -0
  126. data/lib/super_diff/rspec/matcher_text_template.rb +240 -0
  127. data/lib/super_diff/rspec/monkey_patches.rb +601 -98
  128. data/lib/super_diff/rspec/object_inspection.rb +8 -0
  129. data/lib/super_diff/rspec/object_inspection/inspectors.rb +24 -0
  130. data/lib/super_diff/rspec/object_inspection/inspectors/collection_containing_exactly.rb +19 -0
  131. data/lib/super_diff/rspec/object_inspection/inspectors/partial_array.rb +22 -0
  132. data/lib/super_diff/rspec/object_inspection/inspectors/partial_hash.rb +21 -0
  133. data/lib/super_diff/rspec/object_inspection/inspectors/partial_object.rb +21 -0
  134. data/lib/super_diff/rspec/object_inspection/map_extension.rb +23 -0
  135. data/lib/super_diff/rspec/operational_sequencers.rb +22 -0
  136. data/lib/super_diff/rspec/operational_sequencers/collection_containing_exactly.rb +97 -0
  137. data/lib/super_diff/rspec/operational_sequencers/partial_array.rb +23 -0
  138. data/lib/super_diff/rspec/operational_sequencers/partial_hash.rb +32 -0
  139. data/lib/super_diff/rspec/operational_sequencers/partial_object.rb +64 -0
  140. data/lib/super_diff/version.rb +1 -1
  141. data/spec/examples.txt +328 -46
  142. data/spec/integration/rails/active_record_spec.rb +19 -0
  143. data/spec/integration/rails/hash_with_indifferent_access_spec.rb +19 -0
  144. data/spec/integration/rspec/be_falsey_matcher_spec.rb +53 -0
  145. data/spec/integration/rspec/be_matcher_spec.rb +565 -0
  146. data/spec/integration/rspec/be_nil_matcher_spec.rb +53 -0
  147. data/spec/integration/rspec/be_predicate_matcher_spec.rb +546 -0
  148. data/spec/integration/rspec/be_truthy_matcher_spec.rb +57 -0
  149. data/spec/integration/rspec/contain_exactly_matcher_spec.rb +368 -0
  150. data/spec/integration/rspec/eq_matcher_spec.rb +874 -0
  151. data/spec/integration/rspec/have_attributes_matcher_spec.rb +299 -0
  152. data/spec/integration/rspec/include_matcher_spec.rb +350 -0
  153. data/spec/integration/rspec/match_matcher_spec.rb +1258 -0
  154. data/spec/integration/rspec/raise_error_matcher_spec.rb +350 -0
  155. data/spec/integration/rspec/respond_to_matcher_spec.rb +994 -0
  156. data/spec/integration/rspec/unhandled_errors_spec.rb +94 -0
  157. data/spec/spec_helper.rb +19 -4
  158. data/spec/support/colorizer.rb +9 -0
  159. data/spec/support/command_runner.rb +4 -0
  160. data/spec/support/integration/helpers.rb +179 -0
  161. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +79 -41
  162. data/spec/support/models/a.rb +11 -0
  163. data/spec/support/models/active_record/person.rb +26 -0
  164. data/spec/support/models/active_record/shipping_address.rb +29 -0
  165. data/spec/support/models/customer.rb +24 -0
  166. data/spec/support/models/empty_class.rb +6 -0
  167. data/spec/support/models/item.rb +10 -0
  168. data/spec/support/models/order.rb +9 -0
  169. data/spec/support/models/person.rb +20 -0
  170. data/spec/support/models/player.rb +33 -0
  171. data/spec/support/models/shipping_address.rb +34 -0
  172. data/spec/support/ruby_versions.rb +7 -0
  173. data/spec/support/shared_examples/active_record.rb +338 -0
  174. data/spec/support/shared_examples/hash_with_indifferent_access.rb +233 -0
  175. data/spec/unit/equality_matcher_spec.rb +579 -171
  176. data/spec/unit/object_inspection_spec.rb +1092 -0
  177. data/spec/unit/rspec/matchers/be_compared_to_spec.rb +23 -0
  178. data/spec/unit/rspec/matchers/be_falsey_spec.rb +9 -0
  179. data/spec/unit/rspec/matchers/be_nil_spec.rb +9 -0
  180. data/spec/unit/rspec/matchers/be_predicate_spec.rb +31 -0
  181. data/spec/unit/rspec/matchers/be_spec.rb +17 -0
  182. data/spec/unit/rspec/matchers/be_truthy_spec.rb +9 -0
  183. data/spec/unit/rspec/matchers/contain_exactly_spec.rb +11 -0
  184. data/spec/unit/rspec/matchers/eq_spec.rb +9 -0
  185. data/spec/unit/rspec/matchers/have_attributes_spec.rb +11 -0
  186. data/spec/unit/rspec/matchers/include_spec.rb +21 -0
  187. data/spec/unit/rspec/matchers/match_spec.rb +9 -0
  188. data/spec/unit/rspec/matchers/raise_error_spec.rb +29 -0
  189. data/spec/unit/rspec/matchers/respond_to_spec.rb +78 -0
  190. data/super_diff.gemspec +4 -2
  191. metadata +231 -34
  192. data/lib/super_diff/csi/color_helper.rb +0 -52
  193. data/lib/super_diff/csi/eight_bit_sequence.rb +0 -27
  194. data/lib/super_diff/csi/four_bit_sequence.rb +0 -24
  195. data/lib/super_diff/csi/sequence.rb +0 -22
  196. data/lib/super_diff/csi/twenty_four_bit_sequence.rb +0 -27
  197. data/lib/super_diff/diff_formatters/multi_line_string.rb +0 -31
  198. data/lib/super_diff/differs/object.rb +0 -68
  199. data/lib/super_diff/equality_matchers/object.rb +0 -18
  200. data/lib/super_diff/value_inspection.rb +0 -11
  201. data/spec/integration/rspec_spec.rb +0 -261
  202. data/spec/support/color_helper.rb +0 -49
  203. data/spec/support/person.rb +0 -23
  204. data/spec/support/person_diff_formatter.rb +0 -15
  205. data/spec/support/person_operation_sequence.rb +0 -14
  206. data/spec/support/person_operational_sequencer.rb +0 -19
@@ -0,0 +1,94 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Integration with RSpec and unhandled errors", type: :integration do
4
+ context "when a random exception occurs" do
5
+ it "highlights the whole output after the code snippet in red" do
6
+ as_both_colored_and_uncolored do |color_enabled|
7
+ snippet = <<~TEST.strip
8
+ raise "Some kind of error or whatever"
9
+ TEST
10
+ program = make_plain_test_program(
11
+ snippet,
12
+ color_enabled: color_enabled,
13
+ )
14
+
15
+ expected_output = colored(color_enabled: color_enabled) do
16
+ line "Failures:\n"
17
+
18
+ line "1) test passes", indent_by: 2
19
+
20
+ line indent_by: 5 do
21
+ bold "Failure/Error: "
22
+ plain %|raise "Some kind of error or whatever"|
23
+ end
24
+
25
+ newline
26
+
27
+ indent by: 5 do
28
+ red_line "RuntimeError:"
29
+ plain_line " Some kind of error or whatever"
30
+ end
31
+ end
32
+
33
+ expect(program).
34
+ to produce_output_when_run(expected_output).
35
+ in_color(color_enabled)
36
+ end
37
+ end
38
+ end
39
+
40
+ context "when a matcher that has a multi-line message fails" do
41
+ it "highlights the first line of the failure message in red" do
42
+ as_both_colored_and_uncolored do |color_enabled|
43
+ snippet = <<~TEST.strip
44
+ RSpec::Matchers.define :fail_with_multiline_message do
45
+ match do
46
+ false
47
+ end
48
+
49
+ failure_message do
50
+ <<\~MESSAGE
51
+ First line
52
+
53
+ Second line
54
+
55
+ Third line
56
+ MESSAGE
57
+ end
58
+ end
59
+
60
+ expect(:foo).to fail_with_multiline_message
61
+ TEST
62
+ program = make_plain_test_program(
63
+ snippet,
64
+ color_enabled: color_enabled,
65
+ )
66
+
67
+ expected_output = colored(color_enabled: color_enabled) do
68
+ line "Failures:\n"
69
+
70
+ line "1) test passes", indent_by: 2
71
+
72
+ line indent_by: 5 do
73
+ bold "Failure/Error: "
74
+ plain %|expect(:foo).to fail_with_multiline_message|
75
+ end
76
+
77
+ newline
78
+
79
+ indent by: 5 do
80
+ red_line " First line"
81
+ newline
82
+ plain_line " Second line"
83
+ newline
84
+ plain_line " Third line"
85
+ end
86
+ end
87
+
88
+ expect(program).
89
+ to produce_output_when_run(expected_output).
90
+ in_color(color_enabled)
91
+ end
92
+ end
93
+ end
94
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,3 @@
1
- require_relative "../lib/super_diff"
2
- require_relative "../lib/super_diff/rspec"
3
-
4
1
  begin
5
2
  require "pry-byebug"
6
3
  rescue LoadError
@@ -11,6 +8,24 @@ begin
11
8
  rescue LoadError
12
9
  end
13
10
 
11
+ #---
12
+
13
+ require_relative "../support/current_bundle"
14
+
15
+ SuperDiff::CurrentBundle.instance.assert_appraisal!
16
+
17
+ #---
18
+
19
+ require "active_record"
20
+
21
+ ActiveRecord::Base.establish_connection(
22
+ adapter: "sqlite3",
23
+ database: ":memory:",
24
+ )
25
+
26
+ $:.unshift(File.expand_path("../lib", __dir__))
27
+ require "super_diff/rspec-rails"
28
+
14
29
  Dir.glob(File.expand_path("support/**/*.rb", __dir__)).each do |file|
15
30
  require file
16
31
  end
@@ -33,7 +48,7 @@ RSpec.configure do |config|
33
48
  config.disable_monkey_patching!
34
49
  config.warnings = true
35
50
 
36
- if config.files_to_run.one?
51
+ if !["true", "1"].include?(ENV["CI"])
37
52
  config.default_formatter = "documentation"
38
53
  end
39
54
 
@@ -0,0 +1,9 @@
1
+ module SuperDiff
2
+ module Tests
3
+ module Colorizer
4
+ def self.call(*args, **opts, &block)
5
+ SuperDiff::Helpers.style(*args, **opts, &block)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -6,6 +6,10 @@ require "timeout"
6
6
 
7
7
  class CommandRunner
8
8
  module OutputHelpers
9
+ def self.bookended(text)
10
+ divider("START") + text + "\n" + divider("END")
11
+ end
12
+
9
13
  def self.divider(title = "")
10
14
  total_length = 72
11
15
  start_length = 3
@@ -0,0 +1,179 @@
1
+ module SuperDiff
2
+ module IntegrationTests
3
+ PROJECT_DIRECTORY = Pathname.new("../../..").expand_path(__dir__)
4
+
5
+ def as_both_colored_and_uncolored
6
+ [true, false].each do |color_enabled|
7
+ yield color_enabled
8
+ end
9
+ end
10
+
11
+ def make_plain_test_program(test, color_enabled:)
12
+ <<~PROGRAM
13
+ #{set_up_with("super_diff/rspec", color_enabled: color_enabled)}
14
+ #{describe_block_including(test)}
15
+ PROGRAM
16
+ end
17
+
18
+ def make_rspec_active_record_program(test, color_enabled:)
19
+ <<~PROGRAM
20
+ #{
21
+ set_up_active_record_around do
22
+ set_up_with(
23
+ "super_diff/rspec", "super_diff/active_record",
24
+ color_enabled: color_enabled
25
+ )
26
+ end
27
+ }
28
+ #{describe_block_including(test)}
29
+ PROGRAM
30
+ end
31
+
32
+ def make_rspec_rails_test_program(test, color_enabled:)
33
+ <<~PROGRAM
34
+ #{
35
+ set_up_active_record_around do
36
+ set_up_with("super_diff/rspec-rails", color_enabled: color_enabled)
37
+ end
38
+ }
39
+ #{describe_block_including(test)}
40
+ PROGRAM
41
+ end
42
+
43
+ def set_up_active_record_around(&block)
44
+ <<~PROGRAM
45
+ require "active_record"
46
+
47
+ ActiveRecord::Base.establish_connection(
48
+ adapter: "sqlite3",
49
+ database: ":memory:"
50
+ )
51
+
52
+ RSpec.configuration do |config|
53
+ config.before do
54
+ SuperDiff::Test::Models::ActiveRecord::Person.delete_all
55
+ SuperDiff::Test::Models::ActiveRecord::ShippingAddress.delete_all
56
+ end
57
+ end
58
+
59
+ #{block.call}
60
+
61
+ Dir.glob(SUPPORT_DIR.join("models/active_record/*.rb")).each do |path|
62
+ require path
63
+ end
64
+ PROGRAM
65
+ end
66
+
67
+ def set_up_with(*libraries, color_enabled:)
68
+ <<~SETUP
69
+ PROJECT_DIRECTORY = Pathname.new("#{PROJECT_DIRECTORY}")
70
+ SUPPORT_DIR = PROJECT_DIRECTORY.join("spec/support")
71
+ INSIDE_INTEGRATION_TEST = true
72
+
73
+ $LOAD_PATH.unshift(PROJECT_DIRECTORY.join("lib"))
74
+ #\$LOAD_PATH.unshift(PROJECT_DIRECTORY)
75
+
76
+ begin
77
+ require "pry-byebug"
78
+ rescue LoadError
79
+ require "pry-nav"
80
+ end
81
+
82
+ RSpec.configure do |config|
83
+ config.color_mode = :#{color_enabled ? "on" : "off"}
84
+ end
85
+
86
+ #{libraries.map { |library| %( require "#{library}") }.join("\n")}
87
+
88
+ Dir.glob(SUPPORT_DIR.join("{diff_formatters,models,operational_sequencers,operation_sequences}/*.rb")).each do |path|
89
+ require path
90
+ end
91
+ SETUP
92
+ end
93
+
94
+ def describe_block_including(test)
95
+ <<~PROGRAM
96
+ RSpec.describe "test" do
97
+ it "passes" do
98
+ #{reindent(test, level: 2)}
99
+ end
100
+ end
101
+ PROGRAM
102
+ end
103
+
104
+ def build_expected_output(
105
+ color_enabled:,
106
+ snippet:,
107
+ expectation:,
108
+ newline_before_expectation: false,
109
+ diff: nil
110
+ )
111
+ colored(color_enabled: color_enabled) do
112
+ line "Failures:\n"
113
+
114
+ line "1) test passes", indent_by: 2
115
+
116
+ line indent_by: 5 do
117
+ bold "Failure/Error: "
118
+ plain snippet
119
+ end
120
+
121
+ if diff || newline_before_expectation
122
+ newline
123
+ end
124
+
125
+ indent by: 7 do
126
+ evaluate_block(&expectation)
127
+
128
+ if diff
129
+ newline
130
+
131
+ white_line "Diff:"
132
+
133
+ newline
134
+
135
+ line do
136
+ blue "┌ (Key) ──────────────────────────┐"
137
+ end
138
+
139
+ line do
140
+ blue "│ "
141
+ magenta "‹-› in expected, not in actual"
142
+ blue " │"
143
+ end
144
+
145
+ line do
146
+ blue "│ "
147
+ yellow "‹+› in actual, not in expected"
148
+ blue " │"
149
+ end
150
+
151
+ line do
152
+ blue "│ "
153
+ text "‹ › in both expected and actual"
154
+ blue " │"
155
+ end
156
+
157
+ line do
158
+ blue "└─────────────────────────────────┘"
159
+ end
160
+
161
+ newline
162
+
163
+ evaluate_block(&diff)
164
+
165
+ newline
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ def colored(color_enabled: true, &block)
172
+ SuperDiff::Helpers.style(color_enabled: color_enabled, &block).to_s.chomp
173
+ end
174
+
175
+ def reindent(code, level: 0)
176
+ code.strip.split("\n").map { |line| (" " * level) + line }.join("\n")
177
+ end
178
+ end
179
+ end
@@ -9,67 +9,105 @@ module SuperDiff
9
9
  TEMP_DIRECTORY = PROJECT_DIRECTORY.join("tmp")
10
10
 
11
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
12
+ @expected_output = expected_output.to_s.strip
13
+ @output_processor = nil
14
+ @expect_output_to_contain_color = nil
18
15
  end
19
16
 
20
- def matches?(test)
21
- @test = test.strip
17
+ def removing_object_ids
18
+ first_replacing(/#<([\w:]+):0x[a-z0-9]+(.*?)>/, '#<\1\2>')
19
+ self
20
+ end
21
+
22
+ def in_color(color_enabled)
23
+ @expect_output_to_contain_color = color_enabled
24
+ self
25
+ end
26
+
27
+ def matches?(program)
28
+ @program = program.strip
29
+
22
30
  TEMP_DIRECTORY.mkpath
23
- actual_output.include?(expected_output)
31
+
32
+ output_matches? && presence_of_color_matches?
24
33
  end
25
34
 
26
35
  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")
36
+ if output_matches?
37
+ "Expected output of test " +
38
+ (expect_output_to_contain_color? ? "to " : "not to ") +
39
+ "contain color, but " +
40
+ (expect_output_to_contain_color? ? "it did not" : "it did") +
41
+ "."
42
+ else
43
+ message =
44
+ "Expected test to produce output, but it did not.\n\n" +
45
+ "Expected output to contain:\n\n" +
46
+ CommandRunner::OutputHelpers.bookended(expected_output) +
47
+ "\n" +
48
+ "Actual output:\n\n" +
49
+ CommandRunner::OutputHelpers.bookended(actual_output)
50
+
51
+ ::RSpec::Matchers::ExpectedsForMultipleDiffs.
52
+ from(expected_output).
53
+ message_with_diff(
54
+ message,
55
+ ::RSpec::Expectations.differ,
56
+ actual_output,
57
+ )
58
+ end
37
59
  end
38
60
 
39
61
  private
40
62
 
41
- attr_reader :expected_output, :test
63
+ attr_reader :expected_output, :program, :output_processor
64
+
65
+ def expect_output_to_contain_color?
66
+ @expect_output_to_contain_color
67
+ end
68
+
69
+ def first_replacing(pattern, replacement)
70
+ @output_processor = [pattern, replacement]
71
+ self
72
+ end
73
+
74
+ def output_matches?
75
+ actual_output.include?(expected_output)
76
+ end
42
77
 
43
78
  def actual_output
44
- @_actual_output ||=
45
- CommandRunner.run("rspec", tempfile.to_s).output.strip
79
+ @_actual_output ||= begin
80
+ output = run_command.output.strip
81
+
82
+ if output_processor
83
+ output.gsub!(output_processor[0], output_processor[1])
84
+ end
85
+
86
+ output
87
+ end
88
+ end
89
+
90
+ def run_command
91
+ CommandRunner.run(
92
+ "rspec",
93
+ tempfile.to_s,
94
+ env: { "DISABLE_PRY" => "true" },
95
+ )
46
96
  end
47
97
 
48
98
  def tempfile
49
99
  @_tempfile =
50
- TEMP_DIRECTORY.join("acceptance_spec.rb").
100
+ TEMP_DIRECTORY.join("integration_spec.rb").
51
101
  tap { |tempfile| tempfile.write(program) }
52
102
  end
53
103
 
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
104
+ def presence_of_color_matches?
105
+ @expect_output_to_contain_color.nil? ||
106
+ output_has_color? == expect_output_to_contain_color?
107
+ end
66
108
 
67
- RSpec.describe "test" do
68
- it "passes" do
69
- #{test}
70
- end
71
- end
72
- PROGRAM
109
+ def output_has_color?
110
+ !!(actual_output =~ /\e\[\d+m/)
73
111
  end
74
112
  end
75
113
  end