super_diff 0.12.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (271) 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/object_inspection.rb +7 -5
  175. data/lib/super_diff/rspec/operation_tree_builders/collection_containing_exactly.rb +4 -4
  176. data/lib/super_diff/rspec/operation_tree_builders/collection_including.rb +2 -0
  177. data/lib/super_diff/rspec/operation_tree_builders/hash_including.rb +2 -0
  178. data/lib/super_diff/rspec/operation_tree_builders/object_having_attributes.rb +2 -0
  179. data/lib/super_diff/rspec/operation_tree_builders.rb +6 -4
  180. data/lib/super_diff/rspec-rails.rb +4 -2
  181. data/lib/super_diff/rspec.rb +15 -13
  182. data/lib/super_diff/version.rb +3 -1
  183. data/lib/super_diff.rb +24 -27
  184. data/super_diff.gemspec +20 -18
  185. metadata +15 -182
  186. data/spec/examples.txt +0 -704
  187. data/spec/integration/rails/active_record_spec.rb +0 -21
  188. data/spec/integration/rails/active_support_spec.rb +0 -19
  189. data/spec/integration/rails/engines_spec.rb +0 -25
  190. data/spec/integration/rails/hash_with_indifferent_access_spec.rb +0 -21
  191. data/spec/integration/rspec/be_falsey_matcher_spec.rb +0 -58
  192. data/spec/integration/rspec/be_matcher_spec.rb +0 -605
  193. data/spec/integration/rspec/be_nil_matcher_spec.rb +0 -57
  194. data/spec/integration/rspec/be_predicate_matcher_spec.rb +0 -615
  195. data/spec/integration/rspec/be_truthy_matcher_spec.rb +0 -62
  196. data/spec/integration/rspec/contain_exactly_matcher_spec.rb +0 -377
  197. data/spec/integration/rspec/eq_matcher_spec.rb +0 -1066
  198. data/spec/integration/rspec/generic_describable_matchers_spec.rb +0 -177
  199. data/spec/integration/rspec/have_attributes_matcher_spec.rb +0 -443
  200. data/spec/integration/rspec/have_predicate_matcher_spec.rb +0 -478
  201. data/spec/integration/rspec/include_matcher_spec.rb +0 -452
  202. data/spec/integration/rspec/magic_metadata_spec.rb +0 -51
  203. data/spec/integration/rspec/match_array_matcher_spec.rb +0 -424
  204. data/spec/integration/rspec/match_matcher_spec.rb +0 -1359
  205. data/spec/integration/rspec/raise_error_matcher_spec.rb +0 -1488
  206. data/spec/integration/rspec/respond_to_matcher_spec.rb +0 -999
  207. data/spec/integration/rspec/third_party_matcher_spec.rb +0 -245
  208. data/spec/integration/rspec/unhandled_errors_spec.rb +0 -150
  209. data/spec/internal/log/test.log +0 -0
  210. data/spec/spec_helper.rb +0 -90
  211. data/spec/support/colorizer.rb +0 -9
  212. data/spec/support/command_runner.rb +0 -253
  213. data/spec/support/helpers.rb +0 -21
  214. data/spec/support/integration/helpers.rb +0 -124
  215. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +0 -104
  216. data/spec/support/integration/matchers.rb +0 -177
  217. data/spec/support/integration/test_programs/base.rb +0 -143
  218. data/spec/support/integration/test_programs/plain.rb +0 -19
  219. data/spec/support/integration/test_programs/rspec_active_record.rb +0 -20
  220. data/spec/support/integration/test_programs/rspec_active_support.rb +0 -20
  221. data/spec/support/integration/test_programs/rspec_rails.rb +0 -20
  222. data/spec/support/integration/test_programs/rspec_rails_engine.rb +0 -20
  223. data/spec/support/models/a.rb +0 -11
  224. data/spec/support/models/active_record/person.rb +0 -28
  225. data/spec/support/models/active_record/query.rb +0 -15
  226. data/spec/support/models/active_record/shipping_address.rb +0 -24
  227. data/spec/support/models/customer.rb +0 -22
  228. data/spec/support/models/empty_class.rb +0 -6
  229. data/spec/support/models/item.rb +0 -10
  230. data/spec/support/models/order.rb +0 -9
  231. data/spec/support/models/person.rb +0 -20
  232. data/spec/support/models/player.rb +0 -30
  233. data/spec/support/models/shipping_address.rb +0 -25
  234. data/spec/support/shared_examples/active_record.rb +0 -428
  235. data/spec/support/shared_examples/active_support.rb +0 -188
  236. data/spec/support/shared_examples/elided_diffs.rb +0 -938
  237. data/spec/support/shared_examples/hash_with_indifferent_access.rb +0 -749
  238. data/spec/support/shared_examples/key.rb +0 -123
  239. data/spec/support/unit/helpers.rb +0 -24
  240. data/spec/support/unit/matchers/be_deprecated_in_favor_of.rb +0 -39
  241. data/spec/support/unit/matchers/match_output.rb +0 -40
  242. data/spec/unit/active_record/object_inspection_spec.rb +0 -289
  243. data/spec/unit/active_support/object_inspection_spec.rb +0 -170
  244. data/spec/unit/basic/operation_tree_flatteners/array_spec.rb +0 -637
  245. data/spec/unit/basic/operation_tree_flatteners/custom_object_spec.rb +0 -685
  246. data/spec/unit/basic/operation_tree_flatteners/default_object_spec.rb +0 -685
  247. data/spec/unit/basic/operation_tree_flatteners/hash_spec.rb +0 -671
  248. data/spec/unit/basic/operation_tree_flatteners/multiline_string_spec.rb +0 -131
  249. data/spec/unit/core/helpers_spec.rb +0 -68
  250. data/spec/unit/core/tiered_lines_elider_spec.rb +0 -6328
  251. data/spec/unit/core/tiered_lines_formatter_spec.rb +0 -131
  252. data/spec/unit/deprecations_spec.rb +0 -176
  253. data/spec/unit/equality_matchers/main_spec.rb +0 -1842
  254. data/spec/unit/rspec/matchers/be_compared_to_spec.rb +0 -23
  255. data/spec/unit/rspec/matchers/be_falsey_spec.rb +0 -9
  256. data/spec/unit/rspec/matchers/be_nil_spec.rb +0 -9
  257. data/spec/unit/rspec/matchers/be_predicate_spec.rb +0 -31
  258. data/spec/unit/rspec/matchers/be_spec.rb +0 -17
  259. data/spec/unit/rspec/matchers/be_truthy_spec.rb +0 -9
  260. data/spec/unit/rspec/matchers/contain_exactly_spec.rb +0 -11
  261. data/spec/unit/rspec/matchers/eq_spec.rb +0 -9
  262. data/spec/unit/rspec/matchers/have_attributes_spec.rb +0 -11
  263. data/spec/unit/rspec/matchers/have_predicate_spec.rb +0 -21
  264. data/spec/unit/rspec/matchers/include_spec.rb +0 -21
  265. data/spec/unit/rspec/matchers/match_array_spec.rb +0 -11
  266. data/spec/unit/rspec/matchers/match_spec.rb +0 -9
  267. data/spec/unit/rspec/matchers/raise_error_spec.rb +0 -77
  268. data/spec/unit/rspec/matchers/respond_to_spec.rb +0 -85
  269. data/spec/unit/rspec/object_inspection/rspec_matcher_spec.rb +0 -91
  270. data/spec/unit/rspec/object_inspection_spec.rb +0 -471
  271. 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