super_diff 0.12.1 → 0.15.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 (272) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -19
  3. data/lib/super_diff/active_record/differs/active_record_relation.rb +2 -0
  4. data/lib/super_diff/active_record/differs.rb +3 -1
  5. data/lib/super_diff/active_record/inspection_tree_builders/active_record_model.rb +7 -5
  6. data/lib/super_diff/active_record/inspection_tree_builders/active_record_relation.rb +12 -10
  7. data/lib/super_diff/active_record/inspection_tree_builders.rb +4 -2
  8. data/lib/super_diff/active_record/monkey_patches.rb +4 -2
  9. data/lib/super_diff/active_record/object_inspection.rb +6 -4
  10. data/lib/super_diff/active_record/operation_tree_builders/active_record_model.rb +3 -1
  11. data/lib/super_diff/active_record/operation_tree_builders/active_record_relation.rb +3 -1
  12. data/lib/super_diff/active_record/operation_tree_builders.rb +4 -2
  13. data/lib/super_diff/active_record/operation_tree_flatteners/active_record_relation.rb +4 -2
  14. data/lib/super_diff/active_record/operation_tree_flatteners.rb +3 -1
  15. data/lib/super_diff/active_record/operation_trees/active_record_relation.rb +2 -0
  16. data/lib/super_diff/active_record/operation_trees.rb +3 -1
  17. data/lib/super_diff/active_record.rb +10 -8
  18. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +2 -0
  19. data/lib/super_diff/active_support/differs.rb +3 -1
  20. data/lib/super_diff/active_support/inspection_tree_builders/hash_with_indifferent_access.rb +16 -14
  21. data/lib/super_diff/active_support/inspection_tree_builders/ordered_options.rb +16 -14
  22. data/lib/super_diff/active_support/inspection_tree_builders.rb +4 -2
  23. data/lib/super_diff/active_support/object_inspection.rb +6 -4
  24. data/lib/super_diff/active_support/operation_tree_builders/hash_with_indifferent_access.rb +6 -4
  25. data/lib/super_diff/active_support/operation_tree_builders.rb +3 -1
  26. data/lib/super_diff/active_support/operation_tree_flatteners/hash_with_indifferent_access.rb +4 -2
  27. data/lib/super_diff/active_support/operation_tree_flatteners.rb +3 -1
  28. data/lib/super_diff/active_support/operation_trees/hash_with_indifferent_access.rb +2 -0
  29. data/lib/super_diff/active_support/operation_trees.rb +3 -1
  30. data/lib/super_diff/active_support.rb +8 -6
  31. data/lib/super_diff/basic/diff_formatters/collection.rb +18 -18
  32. data/lib/super_diff/basic/diff_formatters/multiline_string.rb +2 -0
  33. data/lib/super_diff/basic/diff_formatters.rb +4 -2
  34. data/lib/super_diff/basic/differs/array.rb +2 -0
  35. data/lib/super_diff/basic/differs/custom_object.rb +3 -1
  36. data/lib/super_diff/basic/differs/date_like.rb +2 -0
  37. data/lib/super_diff/basic/differs/default_object.rb +3 -1
  38. data/lib/super_diff/basic/differs/hash.rb +2 -0
  39. data/lib/super_diff/basic/differs/multiline_string.rb +2 -0
  40. data/lib/super_diff/basic/differs/time_like.rb +2 -0
  41. data/lib/super_diff/basic/differs.rb +11 -9
  42. data/lib/super_diff/basic/inspection_tree_builders/array.rb +5 -3
  43. data/lib/super_diff/basic/inspection_tree_builders/custom_object.rb +5 -3
  44. data/lib/super_diff/basic/inspection_tree_builders/data_object.rb +42 -0
  45. data/lib/super_diff/basic/inspection_tree_builders/date_like.rb +7 -5
  46. data/lib/super_diff/basic/inspection_tree_builders/default_object.rb +7 -5
  47. data/lib/super_diff/basic/inspection_tree_builders/hash.rb +7 -5
  48. data/lib/super_diff/basic/inspection_tree_builders/primitive.rb +3 -1
  49. data/lib/super_diff/basic/inspection_tree_builders/range_object.rb +19 -0
  50. data/lib/super_diff/basic/inspection_tree_builders/time_like.rb +8 -8
  51. data/lib/super_diff/basic/inspection_tree_builders.rb +18 -8
  52. data/lib/super_diff/basic/operation_tree_builders/array.rb +6 -4
  53. data/lib/super_diff/basic/operation_tree_builders/custom_object.rb +3 -1
  54. data/lib/super_diff/basic/operation_tree_builders/data_object.rb +20 -0
  55. data/lib/super_diff/basic/operation_tree_builders/date_like.rb +2 -0
  56. data/lib/super_diff/basic/operation_tree_builders/default_object.rb +32 -31
  57. data/lib/super_diff/basic/operation_tree_builders/hash.rb +49 -46
  58. data/lib/super_diff/basic/operation_tree_builders/multiline_string.rb +5 -3
  59. data/lib/super_diff/basic/operation_tree_builders/time_like.rb +5 -3
  60. data/lib/super_diff/basic/operation_tree_builders.rb +15 -9
  61. data/lib/super_diff/basic/operation_tree_flatteners/array.rb +4 -2
  62. data/lib/super_diff/basic/operation_tree_flatteners/collection.rb +11 -11
  63. data/lib/super_diff/basic/operation_tree_flatteners/custom_object.rb +5 -3
  64. data/lib/super_diff/basic/operation_tree_flatteners/default_object.rb +6 -5
  65. data/lib/super_diff/basic/operation_tree_flatteners/hash.rb +5 -3
  66. data/lib/super_diff/basic/operation_tree_flatteners/multiline_string.rb +3 -1
  67. data/lib/super_diff/basic/operation_tree_flatteners.rb +8 -6
  68. data/lib/super_diff/basic/operation_trees/array.rb +2 -0
  69. data/lib/super_diff/basic/operation_trees/custom_object.rb +2 -0
  70. data/lib/super_diff/basic/operation_trees/default_object.rb +6 -4
  71. data/lib/super_diff/basic/operation_trees/hash.rb +2 -0
  72. data/lib/super_diff/basic/operation_trees/multiline_string.rb +3 -1
  73. data/lib/super_diff/basic/operation_trees.rb +9 -7
  74. data/lib/super_diff/basic.rb +12 -7
  75. data/lib/super_diff/core/abstract_differ.rb +2 -0
  76. data/lib/super_diff/core/abstract_inspection_tree_builder.rb +2 -0
  77. data/lib/super_diff/core/abstract_operation_tree.rb +4 -2
  78. data/lib/super_diff/core/abstract_operation_tree_builder.rb +15 -18
  79. data/lib/super_diff/core/abstract_operation_tree_flattener.rb +5 -3
  80. data/lib/super_diff/core/binary_operation.rb +3 -1
  81. data/lib/super_diff/core/colorized_document_extensions.rb +2 -0
  82. data/lib/super_diff/core/configuration.rb +23 -43
  83. data/lib/super_diff/core/differ_dispatcher.rb +4 -2
  84. data/lib/super_diff/core/gem_version.rb +2 -0
  85. data/lib/super_diff/core/helpers.rb +14 -12
  86. data/lib/super_diff/core/implementation_checks.rb +6 -2
  87. data/lib/super_diff/core/inspection_tree.rb +38 -38
  88. data/lib/super_diff/core/inspection_tree_builder_dispatcher.rb +5 -5
  89. data/lib/super_diff/core/inspection_tree_nodes/as_lines_when_rendering_to_lines.rb +3 -1
  90. data/lib/super_diff/core/inspection_tree_nodes/as_prefix_when_rendering_to_lines.rb +2 -0
  91. data/lib/super_diff/core/inspection_tree_nodes/as_prelude_when_rendering_to_lines.rb +2 -0
  92. data/lib/super_diff/core/inspection_tree_nodes/as_single_line.rb +2 -0
  93. data/lib/super_diff/core/inspection_tree_nodes/base.rb +9 -9
  94. data/lib/super_diff/core/inspection_tree_nodes/inspection.rb +2 -0
  95. data/lib/super_diff/core/inspection_tree_nodes/nesting.rb +2 -0
  96. data/lib/super_diff/core/inspection_tree_nodes/only_when.rb +5 -1
  97. data/lib/super_diff/core/inspection_tree_nodes/text.rb +2 -0
  98. data/lib/super_diff/core/inspection_tree_nodes/when_empty.rb +3 -1
  99. data/lib/super_diff/core/inspection_tree_nodes/when_non_empty.rb +3 -1
  100. data/lib/super_diff/core/inspection_tree_nodes/when_rendering_to_lines.rb +3 -1
  101. data/lib/super_diff/core/inspection_tree_nodes/when_rendering_to_string.rb +2 -0
  102. data/lib/super_diff/core/inspection_tree_nodes.rb +16 -14
  103. data/lib/super_diff/core/line.rb +9 -7
  104. data/lib/super_diff/core/no_differ_available_error.rb +7 -5
  105. data/lib/super_diff/core/no_inspection_tree_builder_available_error.rb +5 -3
  106. data/lib/super_diff/core/no_operation_tree_available_error.rb +4 -2
  107. data/lib/super_diff/core/no_operation_tree_builder_available_error.rb +7 -5
  108. data/lib/super_diff/core/operation_tree_builder_dispatcher.rb +3 -3
  109. data/lib/super_diff/core/operation_tree_finder.rb +8 -8
  110. data/lib/super_diff/core/prefix_for_next_inspection_tree_node.rb +2 -0
  111. data/lib/super_diff/core/prelude_for_next_inspection_tree_node.rb +2 -0
  112. data/lib/super_diff/core/recursion_guard.rb +6 -4
  113. data/lib/super_diff/core/tiered_lines.rb +2 -0
  114. data/lib/super_diff/core/tiered_lines_elider.rb +53 -54
  115. data/lib/super_diff/core/tiered_lines_formatter.rb +6 -4
  116. data/lib/super_diff/core/unary_operation.rb +2 -0
  117. data/lib/super_diff/core.rb +31 -29
  118. data/lib/super_diff/csi/bold_sequence.rb +2 -0
  119. data/lib/super_diff/csi/color.rb +4 -4
  120. data/lib/super_diff/csi/color_sequence_block.rb +3 -1
  121. data/lib/super_diff/csi/colorized_document.rb +7 -9
  122. data/lib/super_diff/csi/document.rb +15 -18
  123. data/lib/super_diff/csi/eight_bit_color.rb +32 -37
  124. data/lib/super_diff/csi/four_bit_color.rb +12 -9
  125. data/lib/super_diff/csi/reset_sequence.rb +2 -0
  126. data/lib/super_diff/csi/twenty_four_bit_color.rb +22 -21
  127. data/lib/super_diff/csi/uncolorized_document.rb +2 -0
  128. data/lib/super_diff/csi.rb +12 -42
  129. data/lib/super_diff/differs.rb +6 -4
  130. data/lib/super_diff/equality_matchers/array.rb +18 -16
  131. data/lib/super_diff/equality_matchers/base.rb +6 -4
  132. data/lib/super_diff/equality_matchers/default.rb +5 -3
  133. data/lib/super_diff/equality_matchers/defaults.rb +3 -1
  134. data/lib/super_diff/equality_matchers/hash.rb +18 -16
  135. data/lib/super_diff/equality_matchers/main.rb +3 -1
  136. data/lib/super_diff/equality_matchers/multiline_string.rb +18 -16
  137. data/lib/super_diff/equality_matchers/primitive.rb +15 -13
  138. data/lib/super_diff/equality_matchers/singleline_string.rb +16 -14
  139. data/lib/super_diff/equality_matchers.rb +11 -9
  140. data/lib/super_diff/errors.rb +4 -2
  141. data/lib/super_diff/object_inspection.rb +17 -15
  142. data/lib/super_diff/operation_tree_builders.rb +6 -4
  143. data/lib/super_diff/operation_tree_flatteners.rb +6 -4
  144. data/lib/super_diff/operation_trees.rb +6 -4
  145. data/lib/super_diff/operations.rb +4 -2
  146. data/lib/super_diff/rails.rb +4 -2
  147. data/lib/super_diff/rspec/augmented_matcher.rb +3 -1
  148. data/lib/super_diff/rspec/differ.rb +16 -7
  149. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +2 -0
  150. data/lib/super_diff/rspec/differs/collection_including.rb +2 -0
  151. data/lib/super_diff/rspec/differs/hash_including.rb +2 -0
  152. data/lib/super_diff/rspec/differs/object_having_attributes.rb +2 -0
  153. data/lib/super_diff/rspec/differs.rb +6 -4
  154. data/lib/super_diff/rspec/inspection_tree_builders/collection_containing_exactly.rb +12 -10
  155. data/lib/super_diff/rspec/inspection_tree_builders/collection_including.rb +10 -8
  156. data/lib/super_diff/rspec/inspection_tree_builders/double.rb +20 -18
  157. data/lib/super_diff/rspec/inspection_tree_builders/generic_describable_matcher.rb +2 -0
  158. data/lib/super_diff/rspec/inspection_tree_builders/hash_including.rb +10 -8
  159. data/lib/super_diff/rspec/inspection_tree_builders/instance_of.rb +2 -0
  160. data/lib/super_diff/rspec/inspection_tree_builders/kind_of.rb +2 -0
  161. data/lib/super_diff/rspec/inspection_tree_builders/object_having_attributes.rb +12 -10
  162. data/lib/super_diff/rspec/inspection_tree_builders/primitive.rb +2 -0
  163. data/lib/super_diff/rspec/inspection_tree_builders/value_within.rb +6 -4
  164. data/lib/super_diff/rspec/inspection_tree_builders.rb +12 -10
  165. data/lib/super_diff/rspec/matcher_text_builders/base.rb +12 -12
  166. data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +19 -17
  167. data/lib/super_diff/rspec/matcher_text_builders/contain_exactly.rb +3 -1
  168. data/lib/super_diff/rspec/matcher_text_builders/have_predicate.rb +7 -5
  169. data/lib/super_diff/rspec/matcher_text_builders/match.rb +6 -4
  170. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +5 -3
  171. data/lib/super_diff/rspec/matcher_text_builders/respond_to.rb +20 -18
  172. data/lib/super_diff/rspec/matcher_text_builders.rb +9 -7
  173. data/lib/super_diff/rspec/matcher_text_template.rb +34 -39
  174. data/lib/super_diff/rspec/monkey_patches.rb +129 -56
  175. data/lib/super_diff/rspec/object_inspection.rb +7 -5
  176. data/lib/super_diff/rspec/operation_tree_builders/collection_containing_exactly.rb +4 -4
  177. data/lib/super_diff/rspec/operation_tree_builders/collection_including.rb +2 -0
  178. data/lib/super_diff/rspec/operation_tree_builders/hash_including.rb +2 -0
  179. data/lib/super_diff/rspec/operation_tree_builders/object_having_attributes.rb +2 -0
  180. data/lib/super_diff/rspec/operation_tree_builders.rb +6 -4
  181. data/lib/super_diff/rspec-rails.rb +4 -2
  182. data/lib/super_diff/rspec.rb +27 -14
  183. data/lib/super_diff/version.rb +3 -1
  184. data/lib/super_diff.rb +24 -27
  185. data/super_diff.gemspec +20 -18
  186. metadata +15 -182
  187. data/spec/examples.txt +0 -704
  188. data/spec/integration/rails/active_record_spec.rb +0 -21
  189. data/spec/integration/rails/active_support_spec.rb +0 -19
  190. data/spec/integration/rails/engines_spec.rb +0 -25
  191. data/spec/integration/rails/hash_with_indifferent_access_spec.rb +0 -21
  192. data/spec/integration/rspec/be_falsey_matcher_spec.rb +0 -58
  193. data/spec/integration/rspec/be_matcher_spec.rb +0 -605
  194. data/spec/integration/rspec/be_nil_matcher_spec.rb +0 -57
  195. data/spec/integration/rspec/be_predicate_matcher_spec.rb +0 -615
  196. data/spec/integration/rspec/be_truthy_matcher_spec.rb +0 -62
  197. data/spec/integration/rspec/contain_exactly_matcher_spec.rb +0 -377
  198. data/spec/integration/rspec/eq_matcher_spec.rb +0 -1066
  199. data/spec/integration/rspec/generic_describable_matchers_spec.rb +0 -177
  200. data/spec/integration/rspec/have_attributes_matcher_spec.rb +0 -443
  201. data/spec/integration/rspec/have_predicate_matcher_spec.rb +0 -478
  202. data/spec/integration/rspec/include_matcher_spec.rb +0 -452
  203. data/spec/integration/rspec/magic_metadata_spec.rb +0 -51
  204. data/spec/integration/rspec/match_array_matcher_spec.rb +0 -424
  205. data/spec/integration/rspec/match_matcher_spec.rb +0 -1359
  206. data/spec/integration/rspec/raise_error_matcher_spec.rb +0 -1488
  207. data/spec/integration/rspec/respond_to_matcher_spec.rb +0 -999
  208. data/spec/integration/rspec/third_party_matcher_spec.rb +0 -245
  209. data/spec/integration/rspec/unhandled_errors_spec.rb +0 -150
  210. data/spec/internal/log/test.log +0 -0
  211. data/spec/spec_helper.rb +0 -90
  212. data/spec/support/colorizer.rb +0 -9
  213. data/spec/support/command_runner.rb +0 -253
  214. data/spec/support/helpers.rb +0 -21
  215. data/spec/support/integration/helpers.rb +0 -124
  216. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +0 -104
  217. data/spec/support/integration/matchers.rb +0 -177
  218. data/spec/support/integration/test_programs/base.rb +0 -143
  219. data/spec/support/integration/test_programs/plain.rb +0 -19
  220. data/spec/support/integration/test_programs/rspec_active_record.rb +0 -20
  221. data/spec/support/integration/test_programs/rspec_active_support.rb +0 -20
  222. data/spec/support/integration/test_programs/rspec_rails.rb +0 -20
  223. data/spec/support/integration/test_programs/rspec_rails_engine.rb +0 -20
  224. data/spec/support/models/a.rb +0 -11
  225. data/spec/support/models/active_record/person.rb +0 -28
  226. data/spec/support/models/active_record/query.rb +0 -15
  227. data/spec/support/models/active_record/shipping_address.rb +0 -24
  228. data/spec/support/models/customer.rb +0 -22
  229. data/spec/support/models/empty_class.rb +0 -6
  230. data/spec/support/models/item.rb +0 -10
  231. data/spec/support/models/order.rb +0 -9
  232. data/spec/support/models/person.rb +0 -20
  233. data/spec/support/models/player.rb +0 -30
  234. data/spec/support/models/shipping_address.rb +0 -25
  235. data/spec/support/shared_examples/active_record.rb +0 -428
  236. data/spec/support/shared_examples/active_support.rb +0 -188
  237. data/spec/support/shared_examples/elided_diffs.rb +0 -938
  238. data/spec/support/shared_examples/hash_with_indifferent_access.rb +0 -749
  239. data/spec/support/shared_examples/key.rb +0 -123
  240. data/spec/support/unit/helpers.rb +0 -24
  241. data/spec/support/unit/matchers/be_deprecated_in_favor_of.rb +0 -39
  242. data/spec/support/unit/matchers/match_output.rb +0 -40
  243. data/spec/unit/active_record/object_inspection_spec.rb +0 -289
  244. data/spec/unit/active_support/object_inspection_spec.rb +0 -170
  245. data/spec/unit/basic/operation_tree_flatteners/array_spec.rb +0 -637
  246. data/spec/unit/basic/operation_tree_flatteners/custom_object_spec.rb +0 -685
  247. data/spec/unit/basic/operation_tree_flatteners/default_object_spec.rb +0 -685
  248. data/spec/unit/basic/operation_tree_flatteners/hash_spec.rb +0 -671
  249. data/spec/unit/basic/operation_tree_flatteners/multiline_string_spec.rb +0 -131
  250. data/spec/unit/core/helpers_spec.rb +0 -68
  251. data/spec/unit/core/tiered_lines_elider_spec.rb +0 -6328
  252. data/spec/unit/core/tiered_lines_formatter_spec.rb +0 -131
  253. data/spec/unit/deprecations_spec.rb +0 -176
  254. data/spec/unit/equality_matchers/main_spec.rb +0 -1842
  255. data/spec/unit/rspec/matchers/be_compared_to_spec.rb +0 -23
  256. data/spec/unit/rspec/matchers/be_falsey_spec.rb +0 -9
  257. data/spec/unit/rspec/matchers/be_nil_spec.rb +0 -9
  258. data/spec/unit/rspec/matchers/be_predicate_spec.rb +0 -31
  259. data/spec/unit/rspec/matchers/be_spec.rb +0 -17
  260. data/spec/unit/rspec/matchers/be_truthy_spec.rb +0 -9
  261. data/spec/unit/rspec/matchers/contain_exactly_spec.rb +0 -11
  262. data/spec/unit/rspec/matchers/eq_spec.rb +0 -9
  263. data/spec/unit/rspec/matchers/have_attributes_spec.rb +0 -11
  264. data/spec/unit/rspec/matchers/have_predicate_spec.rb +0 -21
  265. data/spec/unit/rspec/matchers/include_spec.rb +0 -21
  266. data/spec/unit/rspec/matchers/match_array_spec.rb +0 -11
  267. data/spec/unit/rspec/matchers/match_spec.rb +0 -9
  268. data/spec/unit/rspec/matchers/raise_error_spec.rb +0 -77
  269. data/spec/unit/rspec/matchers/respond_to_spec.rb +0 -85
  270. data/spec/unit/rspec/object_inspection/rspec_matcher_spec.rb +0 -91
  271. data/spec/unit/rspec/object_inspection_spec.rb +0 -471
  272. data/spec/unit/super_diff_spec.rb +0 -2115
@@ -1,253 +0,0 @@
1
- require "childprocess"
2
-
3
- require "English"
4
- require "shellwords"
5
- require "timeout"
6
-
7
- class CommandRunner
8
- class CommandFailedError < StandardError
9
- def self.create(command:, exit_status:, output:, message: nil)
10
- allocate.tap do |error|
11
- error.command = command
12
- error.exit_status = exit_status
13
- error.output = output
14
- error.__send__(:initialize, message)
15
- end
16
- end
17
-
18
- attr_accessor :command, :exit_status, :output
19
-
20
- def initialize(message = nil)
21
- super(message || build_message)
22
- end
23
-
24
- private
25
-
26
- def build_message
27
- message = <<-MESSAGE
28
- Command #{command.inspect} failed, exiting with status #{exit_status}.
29
- MESSAGE
30
-
31
- message << <<-MESSAGE if output
32
- Output:
33
- #{
34
- SuperDiff::Test::OutputHelpers.divider("START") + output +
35
- SuperDiff::Test::OutputHelpers.divider("END")
36
- }
37
- MESSAGE
38
-
39
- message
40
- end
41
- end
42
-
43
- class CommandTimedOutError < StandardError
44
- def self.create(command:, timeout:, output:, message: nil)
45
- allocate.tap do |error|
46
- error.command = command
47
- error.timeout = timeout
48
- error.output = output
49
- error.__send__(:initialize, message)
50
- end
51
- end
52
-
53
- attr_accessor :command, :timeout, :output
54
-
55
- def initialize(message = nil)
56
- super(message || build_message)
57
- end
58
-
59
- private
60
-
61
- def build_message
62
- message = <<-MESSAGE
63
- Command #{formatted_command.inspect} timed out after #{timeout} seconds.
64
- MESSAGE
65
-
66
- message << <<-MESSAGE if output
67
- Output:
68
- #{
69
- SuperDiff::Test::OutputHelpers.divider("START") + output +
70
- SuperDiff::Test::OutputHelpers.divider("END")
71
- }
72
- MESSAGE
73
-
74
- message
75
- end
76
- end
77
-
78
- def self.run(*args)
79
- new(*args).tap do |runner|
80
- yield runner if block_given?
81
- runner.run
82
- end
83
- end
84
-
85
- def self.run!(*args)
86
- run(*args) do |runner|
87
- runner.run_successfully = true
88
- yield runner if block_given?
89
- end
90
- end
91
-
92
- attr_reader :status, :options, :env
93
- attr_accessor :run_quickly, :run_successfully, :retries, :timeout
94
-
95
- def initialize(*args)
96
- @reader, @writer = IO.pipe
97
- options = (args.last.is_a?(Hash) ? args.pop : {})
98
- @args = args
99
- @options = options.merge(err: %i[child out], out: @writer)
100
- @env = extract_env_from(@options)
101
-
102
- @process = ChildProcess.build(*command)
103
- @env.each { |key, value| @process.environment[key] = value }
104
- @process.io.stdout = @process.io.stderr = @writer
105
-
106
- @wrapper = ->(block) { block.call }
107
- self.directory = Dir.pwd
108
- @run_quickly = false
109
- @run_successfully = false
110
- @retries = 1
111
- @num_times_run = 0
112
- @timeout = 10
113
- end
114
-
115
- def around_command(&block)
116
- @wrapper = block
117
- end
118
-
119
- def directory
120
- @options[:chdir]
121
- end
122
-
123
- def directory=(directory)
124
- @options[:chdir] = (directory || Dir.pwd).to_s
125
- end
126
-
127
- def formatted_command
128
- [formatted_env, Shellwords.join(command)].reject(&:empty?).join(" ")
129
- end
130
-
131
- def run
132
- possibly_running_quickly do
133
- run_with_debugging
134
-
135
- fail! if run_successfully && !success?
136
- end
137
-
138
- self
139
- end
140
-
141
- def stop
142
- writer.close if !writer.closed?
143
- end
144
-
145
- def output
146
- @_output ||=
147
- begin
148
- stop
149
- reader.read
150
- end
151
- end
152
-
153
- def elided_output
154
- lines = output.split(/\n/)
155
- new_lines = lines[0..4]
156
-
157
- new_lines << "(...#{lines.size - 10} more lines...)" if lines.size > 10
158
-
159
- new_lines << lines[-5..-1]
160
- new_lines.join("\n")
161
- end
162
-
163
- def success?
164
- status.success?
165
- end
166
-
167
- def exit_status
168
- status.exitstatus
169
- end
170
-
171
- def fail!
172
- raise CommandFailedError.create(
173
- command: formatted_command,
174
- exit_status: exit_status,
175
- output: output
176
- )
177
- end
178
-
179
- def has_output?(expected_output)
180
- if expected_output.is_a?(Regexp)
181
- output =~ expected_output
182
- else
183
- output.include?(expected_output)
184
- end
185
- end
186
-
187
- protected
188
-
189
- attr_reader :args, :reader, :writer, :wrapper, :process
190
-
191
- private
192
-
193
- def extract_env_from(options)
194
- options
195
- .delete(:env) { {} }
196
- .reduce({}) { |hash, (key, value)| hash.merge(key.to_s => value) }
197
- end
198
-
199
- def command
200
- args.flatten.flat_map { |word| Shellwords.split(word) }
201
- end
202
-
203
- def formatted_env
204
- env.map { |key, value| "#{key}=#{value.inspect}" }.join(" ")
205
- end
206
-
207
- def run_freely
208
- process.start
209
- process.wait
210
- end
211
-
212
- def run_with_wrapper
213
- wrapper.call(method(:run_freely))
214
- end
215
-
216
- def run_with_debugging
217
- debug { "\n\e[33mChanging to directory:\e[0m #{directory}" }
218
- debug { "\e[32mRunning command:\e[0m #{formatted_command}" }
219
-
220
- run_with_wrapper
221
-
222
- debug do
223
- "\n" + SuperDiff::Test::OutputHelpers.divider("START") + output +
224
- SuperDiff::Test::OutputHelpers.divider("END")
225
- end
226
- end
227
-
228
- def possibly_running_quickly(&block)
229
- if run_quickly
230
- begin
231
- Timeout.timeout(timeout, &block)
232
- rescue Timeout::Error
233
- stop
234
-
235
- raise CommandTimedOutError.create(
236
- command: formatted_command,
237
- timeout: timeout,
238
- output: output
239
- )
240
- end
241
- else
242
- yield
243
- end
244
- end
245
-
246
- def debugging_enabled?
247
- ENV["DEBUG_COMMANDS"] == "1"
248
- end
249
-
250
- def debug
251
- puts yield if debugging_enabled?
252
- end
253
- end
@@ -1,21 +0,0 @@
1
- module SuperDiff
2
- module Test
3
- module OutputHelpers
4
- def self.bookended(text)
5
- divider("START") + text + "\n" + divider("END")
6
- end
7
-
8
- def self.divider(title = "")
9
- total_length = 72
10
- start_length = 3
11
-
12
- string = ""
13
- string << ("-" * start_length)
14
- string << title
15
- string << "-" * (total_length - start_length - title.length)
16
- string << "\n"
17
- string
18
- end
19
- end
20
- end
21
- end
@@ -1,124 +0,0 @@
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 { |color_enabled| yield color_enabled }
7
- end
8
-
9
- def make_plain_test_program(
10
- test,
11
- color_enabled:,
12
- super_diff_configuration: {},
13
- preserve_as_whole_file: false
14
- )
15
- TestPrograms::Plain.new(
16
- test,
17
- color_enabled: color_enabled,
18
- super_diff_configuration: super_diff_configuration,
19
- preserve_as_whole_file: preserve_as_whole_file
20
- )
21
- end
22
-
23
- def make_rspec_active_record_program(test, color_enabled:)
24
- TestPrograms::RSpecActiveRecord.new(test, color_enabled: color_enabled)
25
- end
26
-
27
- def make_rspec_active_support_program(test, color_enabled:)
28
- TestPrograms::RSpecActiveSupport.new(test, color_enabled: color_enabled)
29
- end
30
-
31
- def make_rspec_rails_test_program(test, color_enabled:)
32
- TestPrograms::RSpecRails.new(test, color_enabled: color_enabled)
33
- end
34
-
35
- def make_rspec_rails_engine_with_action_controller_program(
36
- test,
37
- color_enabled:
38
- )
39
- TestPrograms::RspecRailsEngineWithActionController.new(
40
- test,
41
- color_enabled: color_enabled
42
- )
43
- end
44
-
45
- def build_expected_output(
46
- color_enabled:,
47
- snippet:,
48
- expectation:,
49
- test_name: "test passes",
50
- key_enabled: true,
51
- newline_before_expectation: false,
52
- indentation: 7,
53
- diff: nil,
54
- extra_failure_lines: nil
55
- )
56
- colored(color_enabled: color_enabled) do
57
- line "Failures:\n"
58
-
59
- line "1) #{test_name}", indent_by: 2
60
-
61
- line indent_by: 5 do
62
- bold "Failure/Error: "
63
- plain snippet
64
- end
65
-
66
- newline if diff || newline_before_expectation
67
-
68
- indent by: indentation do
69
- evaluate_block(&expectation)
70
-
71
- if diff
72
- newline
73
-
74
- white_line "Diff:"
75
-
76
- if key_enabled
77
- newline
78
-
79
- line { blue "┌ (Key) ──────────────────────────┐" }
80
-
81
- line do
82
- blue "│ "
83
- magenta "‹-› in expected, not in actual"
84
- blue " │"
85
- end
86
-
87
- line do
88
- blue "│ "
89
- yellow "‹+› in actual, not in expected"
90
- blue " │"
91
- end
92
-
93
- line do
94
- blue "│ "
95
- text "‹ › in both expected and actual"
96
- blue " │"
97
- end
98
-
99
- line { blue "└─────────────────────────────────┘" }
100
- end
101
-
102
- newline
103
-
104
- evaluate_block(&diff)
105
-
106
- newline
107
- end
108
- end
109
-
110
- if extra_failure_lines
111
- newline
112
- evaluate_block(&extra_failure_lines)
113
- end
114
- end
115
- end
116
-
117
- def colored(color_enabled: true, &block)
118
- SuperDiff::Core::Helpers
119
- .style(color_enabled: color_enabled, &block)
120
- .to_s
121
- .chomp
122
- end
123
- end
124
- end
@@ -1,104 +0,0 @@
1
- module SuperDiff
2
- module IntegrationTests
3
- def produce_output_when_run(output)
4
- ProduceOutputWhenRunMatcher.new(output)
5
- end
6
-
7
- class ProduceOutputWhenRunMatcher
8
- def initialize(expected_output)
9
- @expected_output = expected_output.to_s
10
- @output_processor = nil
11
- @expect_output_to_contain_color = nil
12
- end
13
-
14
- def removing_object_ids
15
- first_replacing(/#<([\w_:]+):0x[a-f0-9]+/, '#<\1')
16
- self
17
- end
18
-
19
- def in_color(color_enabled)
20
- @expect_output_to_contain_color = color_enabled
21
- self
22
- end
23
-
24
- def matches?(program)
25
- @program = program
26
-
27
- output_matches? && presence_of_color_matches?
28
- end
29
-
30
- def failure_message
31
- if output_matches?
32
- "Expected output of test " +
33
- (expect_output_to_contain_color? ? "to " : "not to ") +
34
- "contain color, but " +
35
- (expect_output_to_contain_color? ? "it did not" : "it did") + "."
36
- else
37
- message =
38
- "Expected test to produce #{expect_output_to_contain_color? ? "colored" : "uncolored"} output, but it did not.\n\n" +
39
- "Expected output to contain:\n\n" +
40
- SuperDiff::Test::OutputHelpers.bookended(expected_output) + "\n" +
41
- "Actual output:\n\n" +
42
- SuperDiff::Test::OutputHelpers.bookended(actual_output)
43
-
44
- if %w[1 true].include?(ENV["SHOW_DIFF"])
45
- ::RSpec::Matchers::ExpectedsForMultipleDiffs.from(
46
- expected_output
47
- ).message_with_diff(
48
- message,
49
- ::RSpec::Expectations.differ,
50
- actual_output
51
- )
52
- else
53
- message
54
- end
55
- end
56
- end
57
-
58
- def failure_message_when_negated
59
- "Expected output of test not to produce output, but it did.\n\n" +
60
- "Actual output:\n\n" +
61
- SuperDiff::Test::OutputHelpers.bookended(actual_output)
62
- end
63
-
64
- private
65
-
66
- attr_reader :expected_output, :program, :output_processor
67
-
68
- def expect_output_to_contain_color?
69
- @expect_output_to_contain_color
70
- end
71
-
72
- def first_replacing(pattern, replacement)
73
- @output_processor = [pattern, replacement]
74
- self
75
- end
76
-
77
- def output_matches?
78
- actual_output.include?(expected_output)
79
- end
80
-
81
- def actual_output
82
- @_actual_output ||=
83
- begin
84
- output = program.run.output.strip
85
-
86
- if output_processor
87
- output.gsub!(output_processor[0], output_processor[1])
88
- end
89
-
90
- output
91
- end
92
- end
93
-
94
- def presence_of_color_matches?
95
- @expect_output_to_contain_color.nil? ||
96
- output_has_color? == expect_output_to_contain_color?
97
- end
98
-
99
- def output_has_color?
100
- !!(actual_output =~ /\e\[\d+m/)
101
- end
102
- end
103
- end
104
- end
@@ -1,177 +0,0 @@
1
- module SuperDiff
2
- module IntegrationTests
3
- def fail_with_indented_multiline_failure_message
4
- FailWithIndentedMultilineFailureMessageMatcher.new
5
- end
6
-
7
- def fail_with_paragraphed_failure_message
8
- FailWithParagraphedFailureMessageMatcher.new
9
- end
10
-
11
- def fail_with_non_indented_multiline_failure_message
12
- FailWithNonIndentedMultilineFailureMessageMatcher.new
13
- end
14
-
15
- def fail_with_singleline_failure_message
16
- FailWithSinglelineFailureMessageMatcher.new
17
- end
18
-
19
- def pass_with_indented_multiline_failure_message
20
- PassWithIndentedMultilineFailureMessageMatcher.new
21
- end
22
-
23
- def pass_with_paragraphed_failure_message
24
- PassWithParagraphedFailureMessageMatcher.new
25
- end
26
-
27
- def pass_with_non_indented_multiline_failure_message
28
- PassWithNonIndentedMultilineFailureMessageMatcher.new
29
- end
30
-
31
- def pass_with_singleline_failure_message
32
- PassWithSinglelineFailureMessageMatcher.new
33
- end
34
-
35
- RSpec::Matchers.define :failing_custom_matcher_from_dsl do |value|
36
- match { false }
37
-
38
- description do
39
- "custom matcher defined via the DSL with value #{value.inspect}"
40
- end
41
- end
42
-
43
- def failing_custom_matcher_from_scratch(value)
44
- FailingCustomMatcherFromScratch.new(value)
45
- end
46
-
47
- class FailingCustomMatcherFromScratch
48
- def initialize(value)
49
- @value = value
50
- end
51
-
52
- def matches?(_)
53
- false
54
- end
55
-
56
- def description
57
- "custom matcher defined from scratch with value #{value.inspect}"
58
- end
59
-
60
- def failure_message
61
- "Expected custom matcher not to fail, but did"
62
- end
63
-
64
- private
65
-
66
- attr_reader :value
67
- end
68
-
69
- class FailWithIndentedMultilineFailureMessageMatcher
70
- def matches?(_)
71
- false
72
- end
73
-
74
- def failure_message
75
- <<-MESSAGE
76
- This is a message that spans multiple lines.
77
- Here is the next line.
78
- This part is indented, for whatever reason. It just kinda keeps
79
- going until we finish saying whatever it is we want to say.
80
- MESSAGE
81
- end
82
- end
83
-
84
- class FailWithParagraphedFailureMessageMatcher
85
- def matches?(_)
86
- false
87
- end
88
-
89
- def failure_message
90
- <<-MESSAGE
91
- This is a message that spans multiple paragraphs.
92
-
93
- Here is the next paragraph.
94
- MESSAGE
95
- end
96
- end
97
-
98
- class FailWithNonIndentedMultilineFailureMessageMatcher
99
- def matches?(_)
100
- false
101
- end
102
-
103
- def failure_message
104
- <<-MESSAGE
105
- This is a message that spans multiple lines.
106
- Here is the next line.
107
- MESSAGE
108
- end
109
- end
110
-
111
- class FailWithSinglelineFailureMessageMatcher
112
- def matches?(_)
113
- false
114
- end
115
-
116
- def failure_message
117
- <<-MESSAGE
118
- This is a message that spans only one line.
119
- MESSAGE
120
- end
121
- end
122
-
123
- class PassWithIndentedMultilineFailureMessageMatcher
124
- def does_not_match?(_)
125
- false
126
- end
127
-
128
- def failure_message_when_negated
129
- <<-MESSAGE
130
- This is a message that spans multiple lines.
131
- Here is the next line.
132
- This part is indented, for whatever reason. It just kinda keeps
133
- going until we finish saying whatever it is we want to say.
134
- MESSAGE
135
- end
136
- end
137
-
138
- class PassWithParagraphedFailureMessageMatcher
139
- def does_not_match?(_)
140
- false
141
- end
142
-
143
- def failure_message_when_negated
144
- <<-MESSAGE
145
- This is a message that spans multiple paragraphs.
146
-
147
- Here is the next paragraph.
148
- MESSAGE
149
- end
150
- end
151
-
152
- class PassWithNonIndentedMultilineFailureMessageMatcher
153
- def does_not_match?(_)
154
- false
155
- end
156
-
157
- def failure_message_when_negated
158
- <<-MESSAGE
159
- This is a message that spans multiple lines.
160
- Here is the next line.
161
- MESSAGE
162
- end
163
- end
164
-
165
- class PassWithSinglelineFailureMessageMatcher
166
- def does_not_match?(_)
167
- false
168
- end
169
-
170
- def failure_message_when_negated
171
- <<-MESSAGE
172
- This is a message that spans only one line.
173
- MESSAGE
174
- end
175
- end
176
- end
177
- end