super_diff 0.10.0 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -166
  3. data/lib/super_diff/active_record/differs/active_record_relation.rb +1 -1
  4. data/lib/super_diff/active_record/inspection_tree_builders/active_record_model.rb +57 -0
  5. data/lib/super_diff/active_record/inspection_tree_builders/active_record_relation.rb +34 -0
  6. data/lib/super_diff/active_record/inspection_tree_builders.rb +14 -0
  7. data/lib/super_diff/active_record/monkey_patches.rb +6 -3
  8. data/lib/super_diff/active_record/object_inspection.rb +16 -4
  9. data/lib/super_diff/active_record/operation_tree_builders/active_record_model.rb +6 -2
  10. data/lib/super_diff/active_record/operation_tree_builders/active_record_relation.rb +1 -1
  11. data/lib/super_diff/active_record/operation_tree_flatteners/active_record_relation.rb +1 -1
  12. data/lib/super_diff/active_record/operation_trees/active_record_relation.rb +1 -1
  13. data/lib/super_diff/active_record.rb +12 -16
  14. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +1 -1
  15. data/lib/super_diff/active_support/inspection_tree_builders/hash_with_indifferent_access.rb +44 -0
  16. data/lib/super_diff/active_support/inspection_tree_builders/ordered_options.rb +44 -0
  17. data/lib/super_diff/active_support/inspection_tree_builders.rb +14 -0
  18. data/lib/super_diff/active_support/object_inspection.rb +16 -4
  19. data/lib/super_diff/active_support/operation_tree_builders/hash_with_indifferent_access.rb +1 -1
  20. data/lib/super_diff/active_support/operation_tree_flatteners/hash_with_indifferent_access.rb +1 -1
  21. data/lib/super_diff/active_support/operation_trees/hash_with_indifferent_access.rb +1 -1
  22. data/lib/super_diff/active_support.rb +11 -14
  23. data/lib/super_diff/basic/diff_formatters/collection.rb +135 -0
  24. data/lib/super_diff/basic/diff_formatters/multiline_string.rb +34 -0
  25. data/lib/super_diff/basic/diff_formatters.rb +11 -0
  26. data/lib/super_diff/basic/differs/array.rb +17 -0
  27. data/lib/super_diff/basic/differs/custom_object.rb +19 -0
  28. data/lib/super_diff/basic/differs/date_like.rb +17 -0
  29. data/lib/super_diff/basic/differs/default_object.rb +24 -0
  30. data/lib/super_diff/basic/differs/hash.rb +17 -0
  31. data/lib/super_diff/basic/differs/multiline_string.rb +18 -0
  32. data/lib/super_diff/basic/differs/time_like.rb +17 -0
  33. data/lib/super_diff/basic/differs.rb +24 -0
  34. data/lib/super_diff/basic/inspection_tree_builders/array.rb +53 -0
  35. data/lib/super_diff/basic/inspection_tree_builders/custom_object.rb +41 -0
  36. data/lib/super_diff/basic/inspection_tree_builders/date_like.rb +51 -0
  37. data/lib/super_diff/basic/inspection_tree_builders/default_object.rb +77 -0
  38. data/lib/super_diff/basic/inspection_tree_builders/hash.rb +63 -0
  39. data/lib/super_diff/basic/inspection_tree_builders/primitive.rb +19 -0
  40. data/lib/super_diff/basic/inspection_tree_builders/time_like.rb +58 -0
  41. data/lib/super_diff/basic/inspection_tree_builders.rb +20 -0
  42. data/lib/super_diff/basic/operation_tree_builders/array.rb +111 -0
  43. data/lib/super_diff/basic/operation_tree_builders/custom_object.rb +42 -0
  44. data/lib/super_diff/basic/operation_tree_builders/date_like.rb +17 -0
  45. data/lib/super_diff/basic/operation_tree_builders/default_object.rb +117 -0
  46. data/lib/super_diff/basic/operation_tree_builders/hash.rb +222 -0
  47. data/lib/super_diff/basic/operation_tree_builders/multiline_string.rb +90 -0
  48. data/lib/super_diff/basic/operation_tree_builders/time_like.rb +26 -0
  49. data/lib/super_diff/basic/operation_tree_builders.rb +34 -0
  50. data/lib/super_diff/basic/operation_tree_flatteners/array.rb +17 -0
  51. data/lib/super_diff/basic/operation_tree_flatteners/collection.rb +140 -0
  52. data/lib/super_diff/basic/operation_tree_flatteners/custom_object.rb +30 -0
  53. data/lib/super_diff/basic/operation_tree_flatteners/default_object.rb +32 -0
  54. data/lib/super_diff/basic/operation_tree_flatteners/hash.rb +35 -0
  55. data/lib/super_diff/basic/operation_tree_flatteners/multiline_string.rb +20 -0
  56. data/lib/super_diff/basic/operation_tree_flatteners.rb +24 -0
  57. data/lib/super_diff/basic/operation_trees/array.rb +17 -0
  58. data/lib/super_diff/basic/operation_trees/custom_object.rb +17 -0
  59. data/lib/super_diff/basic/operation_trees/default_object.rb +42 -0
  60. data/lib/super_diff/basic/operation_trees/hash.rb +17 -0
  61. data/lib/super_diff/basic/operation_trees/multiline_string.rb +17 -0
  62. data/lib/super_diff/basic/operation_trees.rb +25 -0
  63. data/lib/super_diff/basic.rb +48 -0
  64. data/lib/super_diff/{differs/base.rb → core/abstract_differ.rb} +2 -2
  65. data/lib/super_diff/core/abstract_inspection_tree_builder.rb +26 -0
  66. data/lib/super_diff/{operation_trees/base.rb → core/abstract_operation_tree.rb} +6 -2
  67. data/lib/super_diff/{operation_tree_builders/base.rb → core/abstract_operation_tree_builder.rb} +4 -8
  68. data/lib/super_diff/{operation_tree_flatteners/base.rb → core/abstract_operation_tree_flattener.rb} +2 -2
  69. data/lib/super_diff/{operations → core}/binary_operation.rb +1 -1
  70. data/lib/super_diff/core/colorized_document_extensions.rb +20 -0
  71. data/lib/super_diff/core/configuration.rb +192 -0
  72. data/lib/super_diff/core/differ_dispatcher.rb +31 -0
  73. data/lib/super_diff/core/gem_version.rb +47 -0
  74. data/lib/super_diff/core/helpers.rb +88 -0
  75. data/lib/super_diff/core/implementation_checks.rb +21 -0
  76. data/lib/super_diff/{object_inspection → core}/inspection_tree.rb +32 -26
  77. data/lib/super_diff/core/inspection_tree_builder_dispatcher.rb +23 -0
  78. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/as_lines_when_rendering_to_lines.rb +12 -5
  79. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/as_prefix_when_rendering_to_lines.rb +3 -3
  80. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/as_prelude_when_rendering_to_lines.rb +3 -3
  81. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/as_single_line.rb +3 -3
  82. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/base.rb +2 -2
  83. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/inspection.rb +7 -11
  84. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/nesting.rb +2 -2
  85. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/only_when.rb +2 -2
  86. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/text.rb +2 -2
  87. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/when_empty.rb +2 -2
  88. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/when_non_empty.rb +2 -2
  89. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/when_rendering_to_lines.rb +2 -2
  90. data/lib/super_diff/{object_inspection/nodes → core/inspection_tree_nodes}/when_rendering_to_string.rb +2 -2
  91. data/lib/super_diff/core/inspection_tree_nodes.rb +55 -0
  92. data/lib/super_diff/core/line.rb +85 -0
  93. data/lib/super_diff/{errors → core}/no_differ_available_error.rb +1 -1
  94. data/lib/super_diff/core/no_inspection_tree_builder_available_error.rb +21 -0
  95. data/lib/super_diff/core/no_operation_tree_available_error.rb +20 -0
  96. data/lib/super_diff/{errors/no_operational_sequencer_available_error.rb → core/no_operation_tree_builder_available_error.rb} +6 -4
  97. data/lib/super_diff/{operation_tree_builders/main.rb → core/operation_tree_builder_dispatcher.rb} +9 -13
  98. data/lib/super_diff/core/operation_tree_finder.rb +27 -0
  99. data/lib/super_diff/core/prefix_for_next_inspection_tree_node.rb +6 -0
  100. data/lib/super_diff/core/prelude_for_next_inspection_tree_node.rb +6 -0
  101. data/lib/super_diff/core/recursion_guard.rb +52 -0
  102. data/lib/super_diff/core/tiered_lines.rb +6 -0
  103. data/lib/super_diff/core/tiered_lines_elider.rb +472 -0
  104. data/lib/super_diff/core/tiered_lines_formatter.rb +77 -0
  105. data/lib/super_diff/{operations → core}/unary_operation.rb +1 -1
  106. data/lib/super_diff/core.rb +69 -0
  107. data/lib/super_diff/differs.rb +19 -11
  108. data/lib/super_diff/equality_matchers/array.rb +3 -3
  109. data/lib/super_diff/equality_matchers/default.rb +8 -3
  110. data/lib/super_diff/equality_matchers/hash.rb +3 -3
  111. data/lib/super_diff/equality_matchers/multiline_string.rb +3 -3
  112. data/lib/super_diff/equality_matchers/primitive.rb +3 -3
  113. data/lib/super_diff/equality_matchers/singleline_string.rb +2 -2
  114. data/lib/super_diff/errors.rb +12 -12
  115. data/lib/super_diff/object_inspection.rb +63 -14
  116. data/lib/super_diff/operation_tree_builders.rb +19 -14
  117. data/lib/super_diff/operation_tree_flatteners.rb +19 -16
  118. data/lib/super_diff/operation_trees.rb +19 -9
  119. data/lib/super_diff/operations.rb +12 -2
  120. data/lib/super_diff/rspec/augmented_matcher.rb +1 -1
  121. data/lib/super_diff/rspec/differ.rb +4 -5
  122. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +1 -1
  123. data/lib/super_diff/rspec/differs/collection_including.rb +1 -1
  124. data/lib/super_diff/rspec/differs/hash_including.rb +1 -1
  125. data/lib/super_diff/rspec/differs/object_having_attributes.rb +1 -1
  126. data/lib/super_diff/rspec/inspection_tree_builders/collection_containing_exactly.rb +34 -0
  127. data/lib/super_diff/rspec/inspection_tree_builders/collection_including.rb +40 -0
  128. data/lib/super_diff/rspec/inspection_tree_builders/double.rb +100 -0
  129. data/lib/super_diff/rspec/inspection_tree_builders/generic_describable_matcher.rb +17 -0
  130. data/lib/super_diff/rspec/inspection_tree_builders/hash_including.rb +40 -0
  131. data/lib/super_diff/rspec/inspection_tree_builders/instance_of.rb +25 -0
  132. data/lib/super_diff/rspec/inspection_tree_builders/kind_of.rb +25 -0
  133. data/lib/super_diff/rspec/inspection_tree_builders/object_having_attributes.rb +34 -0
  134. data/lib/super_diff/rspec/inspection_tree_builders/primitive.rb +9 -0
  135. data/lib/super_diff/rspec/inspection_tree_builders/value_within.rb +30 -0
  136. data/lib/super_diff/rspec/inspection_tree_builders.rb +40 -0
  137. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +3 -7
  138. data/lib/super_diff/rspec/monkey_patches.rb +59 -8
  139. data/lib/super_diff/rspec/object_inspection.rb +14 -4
  140. data/lib/super_diff/rspec/operation_tree_builders/collection_containing_exactly.rb +4 -4
  141. data/lib/super_diff/rspec/operation_tree_builders/collection_including.rb +1 -1
  142. data/lib/super_diff/rspec/operation_tree_builders/hash_including.rb +1 -1
  143. data/lib/super_diff/rspec/operation_tree_builders/object_having_attributes.rb +2 -2
  144. data/lib/super_diff/rspec.rb +28 -25
  145. data/lib/super_diff/version.rb +1 -1
  146. data/lib/super_diff.rb +78 -21
  147. data/spec/examples.txt +704 -493
  148. data/spec/integration/rails/engines_spec.rb +8 -3
  149. data/spec/integration/rspec/contain_exactly_matcher_spec.rb +19 -19
  150. data/spec/integration/rspec/eq_matcher_spec.rb +111 -39
  151. data/spec/integration/rspec/generic_describable_matchers_spec.rb +177 -0
  152. data/spec/integration/rspec/have_attributes_matcher_spec.rb +25 -25
  153. data/spec/integration/rspec/include_matcher_spec.rb +23 -23
  154. data/spec/integration/rspec/magic_metadata_spec.rb +51 -0
  155. data/spec/integration/rspec/match_array_matcher_spec.rb +30 -30
  156. data/spec/integration/rspec/match_matcher_spec.rb +93 -93
  157. data/spec/integration/rspec/raise_error_matcher_spec.rb +813 -69
  158. data/spec/internal/log/test.log +0 -0
  159. data/spec/spec_helper.rb +3 -0
  160. data/spec/support/integration/helpers.rb +19 -11
  161. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +1 -1
  162. data/spec/support/integration/matchers.rb +34 -0
  163. data/spec/support/integration/test_programs/base.rb +6 -6
  164. data/spec/support/integration/test_programs/rspec_rails_engine.rb +3 -13
  165. data/spec/support/models/active_record/person.rb +8 -1
  166. data/spec/support/shared_examples/active_record.rb +38 -38
  167. data/spec/support/shared_examples/active_support.rb +125 -4
  168. data/spec/support/shared_examples/elided_diffs.rb +48 -48
  169. data/spec/support/shared_examples/hash_with_indifferent_access.rb +88 -88
  170. data/spec/support/shared_examples/key.rb +10 -10
  171. data/spec/support/unit/helpers.rb +12 -1
  172. data/spec/support/unit/matchers/be_deprecated_in_favor_of.rb +39 -0
  173. data/spec/unit/active_record/object_inspection_spec.rb +5 -5
  174. data/spec/unit/active_support/object_inspection_spec.rb +170 -0
  175. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/array_spec.rb +8 -8
  176. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/custom_object_spec.rb +9 -9
  177. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/default_object_spec.rb +9 -9
  178. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/hash_spec.rb +8 -8
  179. data/spec/unit/{operation_tree_flatteners → basic/operation_tree_flatteners}/multiline_string_spec.rb +4 -4
  180. data/spec/unit/{helpers_spec.rb → core/helpers_spec.rb} +2 -2
  181. data/spec/unit/{tiered_lines_elider_spec.rb → core/tiered_lines_elider_spec.rb} +2 -2
  182. data/spec/unit/{tiered_lines_formatter_spec.rb → core/tiered_lines_formatter_spec.rb} +1 -1
  183. data/spec/unit/deprecations_spec.rb +176 -0
  184. data/spec/unit/equality_matchers/main_spec.rb +5 -5
  185. data/spec/unit/rspec/matchers/raise_error_spec.rb +43 -11
  186. data/spec/unit/rspec/object_inspection/rspec_matcher_spec.rb +91 -0
  187. data/spec/unit/rspec/object_inspection_spec.rb +2 -2
  188. data/spec/unit/super_diff_spec.rb +64 -0
  189. data/super_diff.gemspec +6 -0
  190. metadata +137 -112
  191. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders/active_record_model.rb +0 -39
  192. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders/active_record_relation.rb +0 -27
  193. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders.rb +0 -16
  194. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders/hash_with_indifferent_access.rb +0 -31
  195. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders.rb +0 -12
  196. data/lib/super_diff/colorized_document_extensions.rb +0 -18
  197. data/lib/super_diff/configuration.rb +0 -149
  198. data/lib/super_diff/diff_formatters/collection.rb +0 -132
  199. data/lib/super_diff/diff_formatters/multiline_string.rb +0 -31
  200. data/lib/super_diff/differs/array.rb +0 -15
  201. data/lib/super_diff/differs/custom_object.rb +0 -17
  202. data/lib/super_diff/differs/default_object.rb +0 -19
  203. data/lib/super_diff/differs/defaults.rb +0 -12
  204. data/lib/super_diff/differs/empty.rb +0 -13
  205. data/lib/super_diff/differs/hash.rb +0 -15
  206. data/lib/super_diff/differs/main.rb +0 -31
  207. data/lib/super_diff/differs/multiline_string.rb +0 -16
  208. data/lib/super_diff/differs/time_like.rb +0 -15
  209. data/lib/super_diff/errors/no_diff_formatter_available_error.rb +0 -21
  210. data/lib/super_diff/gem_version.rb +0 -45
  211. data/lib/super_diff/helpers.rb +0 -86
  212. data/lib/super_diff/implementation_checks.rb +0 -19
  213. data/lib/super_diff/line.rb +0 -83
  214. data/lib/super_diff/object_inspection/inspection_tree_builders/array.rb +0 -34
  215. data/lib/super_diff/object_inspection/inspection_tree_builders/base.rb +0 -27
  216. data/lib/super_diff/object_inspection/inspection_tree_builders/custom_object.rb +0 -31
  217. data/lib/super_diff/object_inspection/inspection_tree_builders/default_object.rb +0 -54
  218. data/lib/super_diff/object_inspection/inspection_tree_builders/defaults.rb +0 -14
  219. data/lib/super_diff/object_inspection/inspection_tree_builders/hash.rb +0 -38
  220. data/lib/super_diff/object_inspection/inspection_tree_builders/main.rb +0 -30
  221. data/lib/super_diff/object_inspection/inspection_tree_builders/primitive.rb +0 -21
  222. data/lib/super_diff/object_inspection/inspection_tree_builders/time_like.rb +0 -47
  223. data/lib/super_diff/object_inspection/inspection_tree_builders.rb +0 -44
  224. data/lib/super_diff/object_inspection/nodes.rb +0 -50
  225. data/lib/super_diff/object_inspection/prefix_for_next_node.rb +0 -6
  226. data/lib/super_diff/object_inspection/prelude_for_next_node.rb +0 -6
  227. data/lib/super_diff/operation_tree_builders/array.rb +0 -107
  228. data/lib/super_diff/operation_tree_builders/custom_object.rb +0 -40
  229. data/lib/super_diff/operation_tree_builders/default_object.rb +0 -119
  230. data/lib/super_diff/operation_tree_builders/defaults.rb +0 -5
  231. data/lib/super_diff/operation_tree_builders/hash.rb +0 -218
  232. data/lib/super_diff/operation_tree_builders/multiline_string.rb +0 -86
  233. data/lib/super_diff/operation_tree_builders/time_like.rb +0 -24
  234. data/lib/super_diff/operation_tree_flatteners/array.rb +0 -15
  235. data/lib/super_diff/operation_tree_flatteners/collection.rb +0 -136
  236. data/lib/super_diff/operation_tree_flatteners/custom_object.rb +0 -28
  237. data/lib/super_diff/operation_tree_flatteners/default_object.rb +0 -31
  238. data/lib/super_diff/operation_tree_flatteners/hash.rb +0 -33
  239. data/lib/super_diff/operation_tree_flatteners/multiline_string.rb +0 -18
  240. data/lib/super_diff/operation_trees/array.rb +0 -15
  241. data/lib/super_diff/operation_trees/custom_object.rb +0 -15
  242. data/lib/super_diff/operation_trees/default_object.rb +0 -40
  243. data/lib/super_diff/operation_trees/defaults.rb +0 -5
  244. data/lib/super_diff/operation_trees/hash.rb +0 -15
  245. data/lib/super_diff/operation_trees/main.rb +0 -35
  246. data/lib/super_diff/operation_trees/multiline_string.rb +0 -15
  247. data/lib/super_diff/recursion_guard.rb +0 -50
  248. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/collection_containing_exactly.rb +0 -29
  249. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/collection_including.rb +0 -36
  250. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/double.rb +0 -98
  251. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/hash_including.rb +0 -37
  252. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/instance_of.rb +0 -28
  253. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/kind_of.rb +0 -28
  254. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/object_having_attributes.rb +0 -29
  255. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/primitive.rb +0 -10
  256. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/value_within.rb +0 -33
  257. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders.rb +0 -44
  258. data/lib/super_diff/tiered_lines.rb +0 -4
  259. data/lib/super_diff/tiered_lines_elider.rb +0 -462
  260. data/lib/super_diff/tiered_lines_formatter.rb +0 -75
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb5307b0f4dab85f765805443f6315ea45ec58d81f94211292326e32b98e1539
4
- data.tar.gz: 3af49d5f9a3d7396828fdc6c1b74cd8e4103ff35fc2ebced5dbef15071fe0bab
3
+ metadata.gz: b261fa1a942123632f87e74d6b123826571840e9d779d21424ca590b6a646f8f
4
+ data.tar.gz: a2a780bc9752ec935edfd34bfb7588aa13c8a2357f1422037102e1c7774c31db
5
5
  SHA512:
6
- metadata.gz: 9aea5c125c0dbde9f754f4d0fd72dd20142cfe4f49077d9f7ab7e47994ea09297c5f58fc3cd59f564fe9534e17ae7e2a062433c03830dc3d209ee2217d503270
7
- data.tar.gz: f1f31c074ce8f043f7ac72127b5bd46158433a5ec6af3a0b79250f08e276fba8d1936b5ed5a09e2134e1ee3e4087b7bec36535da556f7b0b04953690edb949b9
6
+ metadata.gz: 45a49cec47615c6c82e1cbae577c1bd9ad57852469f7a69d13c7daa8425971f8fdb109de7991db7b3f810dfcd9eb58d0cd1635c9497b913496ef8e5ab9e0f73b
7
+ data.tar.gz: 8bf439969e3e15fe39661e25e65abca5a442a055efad43089d16bdd0a383c36c0ff02c67a6f73644d04c5581c8cf2a0c72b50f5a67d543046acd875a8c081e64
data/README.md CHANGED
@@ -8,24 +8,23 @@
8
8
  [issuehunt-badge]: https://img.shields.io/badge/sponsored_through-IssueHunt-2EC28C
9
9
  [issuehunt]: https://issuehunt.io/r/mcmire/super_diff
10
10
 
11
- SuperDiff is a gem that hooks into RSpec
12
- to intelligently display the differences between two data structures of any type.
11
+ **SuperDiff** is a Ruby gem
12
+ which is designed to display the differences between two objects of any type
13
+ in a familiar and intelligent fashion.
13
14
 
14
15
  📢 **[See what's changed in recent versions.][changelog]**
15
16
 
16
- [changelog]: CHANGELOG.md
17
+ [changelog]: ./CHANGELOG.md
17
18
 
18
19
  ## Introduction
19
20
 
20
21
  The primary motivation behind this gem
21
22
  is to vastly improve upon RSpec's built-in diffing capabilities.
22
-
23
- Sometimes, whenever you use a matcher such as `eq`, `match`, `include`, or `have_attributes`,
23
+ RSpec has many nice features,
24
+ and one of them is that whenever you use a matcher such as `eq`, `match`, `include`, or `have_attributes`,
24
25
  you will get a diff of the two data structures you are trying to match against.
25
26
  This is great if all you want to do is compare multi-line strings.
26
- But if you want to compare other, more "real world" kinds of values,
27
- such as what you might work with when developing API endpoints
28
- or testing methods that make database calls and return a set of model objects,
27
+ But if you want to compare other, more "real world" kinds of values such as API or database data,
29
28
  then you are out of luck.
30
29
  Since [RSpec merely runs your `expected` and `actual` values through Ruby's PrettyPrinter library][rspec-differ-fail]
31
30
  and then performs a diff of these strings,
@@ -33,8 +32,7 @@ the output it produces leaves much to be desired.
33
32
 
34
33
  [rspec-differ-fail]: https://github.com/rspec/rspec-support/blob/c69a231d7369dd165ad7ce4742e1a2e21e3462b5/lib/rspec/support/differ.rb#L178
35
34
 
36
- For instance,
37
- let's say you wanted to compare these two hashes:
35
+ For instance, let's say you wanted to compare these two hashes:
38
36
 
39
37
  ```ruby
40
38
  actual = {
@@ -78,7 +76,7 @@ expect(actual).to eq(expected)
78
76
 
79
77
  You would get output that looks like this:
80
78
 
81
- ![Before super_diff](docs/before.png)
79
+ ![Before super_diff](docs/assets/before.png)
82
80
 
83
81
  What this library does
84
82
  is to provide a diff engine
@@ -87,162 +85,14 @@ and display them in a sensible way.
87
85
  So, using the example above,
88
86
  you'd get this instead:
89
87
 
90
- ![After super_diff](docs/after.png)
91
-
92
- ## Installation
93
-
94
- There are a few different ways to install `super_diff`
95
- depending on your type of project.
96
-
97
- ### Rails apps
98
-
99
- If you're developing a Rails app,
100
- add the following to your Gemfile:
101
-
102
- ```ruby
103
- group :test do
104
- gem "super_diff"
105
- end
106
- ```
107
-
108
- After running `bundle install`,
109
- add the following to your `rails_helper`:
110
-
111
- ```ruby
112
- require "super_diff/rspec-rails"
113
- ```
114
-
115
- ### Projects using some part of Rails (e.g. ActiveModel)
116
-
117
- If you're developing an app using Hanami or Sinatra,
118
- or merely using a part of Rails such as ActiveModel,
119
- add the following to your Gemfile where appropriate:
120
-
121
- ```ruby
122
- gem "super_diff"
123
- ```
124
-
125
- After running `bundle install`,
126
- add the following to your `spec_helper`:
127
-
128
- ```ruby
129
- require "super_diff/rspec"
130
- require "super_diff/active_support"
131
- ```
132
-
133
- ### Gems
134
-
135
- If you're developing a gem,
136
- add the following to your gemspec:
137
-
138
- ```ruby
139
- spec.add_development_dependency "super_diff"
140
- ```
141
-
142
- Now add the following to your `spec_helper`:
143
-
144
- ```ruby
145
- require "super_diff/rspec"
146
- ```
147
-
148
- ## Configuration
149
-
150
- You can customize the behavior of the gem
151
- by adding a configuration block
152
- to your test helper file
153
- (`rails_helper` or `spec_helper`)
154
- which looks something like this:
155
-
156
- ```ruby
157
- SuperDiff.configure do |config|
158
- # ...
159
- end
160
- ```
161
-
162
- ### Customizing colors
163
-
164
- If you don't like the colors that SuperDiff uses,
165
- you can change them like this:
88
+ ![After super_diff](docs/assets/after.png)
166
89
 
167
- ```ruby
168
- SuperDiff.configure do |config|
169
- config.actual_color = :green
170
- config.expected_color = :red
171
- config.border_color = :yellow
172
- config.header_color = :yellow
173
- end
174
- ```
175
-
176
- See [eight_bit_color.rb](lib/super_diff/csi/eight_bit_color.rb)
177
- for the list of available colors.
178
-
179
- You can also completely disable colorized output.
180
-
181
- <!-- prettier-ignore-start -->
182
- ```ruby
183
- SuperDiff.configure do |config|
184
- config.color_enabled = false
185
- end
186
- ```
187
- <!-- prettier-ignore-end -->
90
+ ## Installation & Usage
188
91
 
189
- ### Disabling the key
92
+ 📘 For more on how to install and use SuperDiff,
93
+ [read the user documentation][user-docs].
190
94
 
191
- You can disable the key by changing the following config (default: true):
192
-
193
- <!-- prettier-ignore-start -->
194
- ```ruby
195
- SuperDiff.configure do |config|
196
- config.key_enabled = false
197
- end
198
- ```
199
- <!-- prettier-ignore-end -->
200
-
201
- ### Hiding unimportant lines
202
-
203
- When looking at a large diff for which many of the lines do not change,
204
- it can be difficult to locate the lines which do. Text-oriented
205
- diffs such as those you get from a conventional version control system
206
- solve this problem by removing those unchanged lines from the diff
207
- entirely. The same can be done in SuperDiff.
208
-
209
- ```ruby
210
- SuperDiff.configure do |config|
211
- config.diff_elision_enabled = false
212
- config.diff_elision_maximum = 3
213
- end
214
- ```
215
-
216
- - `diff_elision_enabled` — The elision logic is disabled by default so
217
- as not to surprise people, so setting this to `true` will turn it on.
218
- - `diff_elision_maximum` — This number controls what happens to
219
- unchanged lines (i.e. lines that are neither "insert" lines nor
220
- "delete" lines) that are in between changed lines. If a section of
221
- unchanged lines is beyond this number, the gem will elide (a fancy
222
- word for remove) the data structures within that section as much as
223
- possible until the limit is reached or it cannot go further. Elided
224
- lines are replaced with a `# ...` marker.
225
-
226
- ### Diffing custom objects
227
-
228
- If you are comparing two data structures
229
- that involve a class that is specific to your project,
230
- the resulting diff may not look as good as diffs involving native or primitive objects.
231
- This happens because if SuperDiff doesn't recognize a class,
232
- it will fall back to a generic representation when diffing instances of that class.
233
- Fortunately, the gem has a pluggable interface
234
- that allows you to insert your own implementations
235
- of key pieces involved in the diffing process.
236
- I'll have more about how that works soon,
237
- but here is what such a configuration would look like:
238
-
239
- ```ruby
240
- SuperDiff.configure do |config|
241
- config.add_extra_differ_class(YourDiffer)
242
- config.add_extra_operation_tree_builder_class(YourOperationTreeBuilder)
243
- config.add_extra_operation_tree_class(YourOperationTree)
244
- end
245
- ```
95
+ [user-docs]: ./docs/users/getting-started.md
246
96
 
247
97
  ## Support
248
98
 
@@ -257,16 +107,19 @@ I'll try to respond to it as soon as I can!
257
107
  ## Contributing
258
108
 
259
109
  Any code contributions to improve this library are welcome!
260
- Please see the [contributing](./CONTRIBUTING.md) document for more on how to do that.
110
+ Please see the [contributing](./docs/contributors/index.md) document
111
+ for more on how to do that.
261
112
 
262
113
  ## Sponsoring
263
114
 
264
115
  If there's a change you want implemented, you can choose to sponsor that change!
265
116
  `super_diff` is set up on IssueHunt,
266
117
  so feel free to search for an existing issue (or make your own)
267
- and [add a bounty](https://issuehunt.io/r/mcmire/super_diff).
118
+ and [add a bounty][issuehunt].
268
119
  I'll get notified right away!
269
120
 
121
+ [issuehunt]: https://issuehunt.io/r/mcmire/super_diff
122
+
270
123
  ## Compatibility
271
124
 
272
125
  `super_diff` is [tested][gh-actions] to work with
@@ -1,7 +1,7 @@
1
1
  module SuperDiff
2
2
  module ActiveRecord
3
3
  module Differs
4
- class ActiveRecordRelation < SuperDiff::Differs::Base
4
+ class ActiveRecordRelation < Core::AbstractDiffer
5
5
  def self.applies_to?(expected, actual)
6
6
  expected.is_a?(::Array) && actual.is_a?(::ActiveRecord::Relation)
7
7
  end
@@ -0,0 +1,57 @@
1
+ module SuperDiff
2
+ module ActiveRecord
3
+ module InspectionTreeBuilders
4
+ class ActiveRecordModel < Core::AbstractInspectionTreeBuilder
5
+ def self.applies_to?(value)
6
+ value.is_a?(::ActiveRecord::Base)
7
+ end
8
+
9
+ def id
10
+ object.class.primary_key
11
+ end
12
+
13
+ def call
14
+ Core::InspectionTree.new do |t1|
15
+ t1.as_lines_when_rendering_to_lines(
16
+ collection_bookend: :open
17
+ ) do |t2|
18
+ t2.add_text "#<#{object.class} "
19
+
20
+ # stree-ignore
21
+ t2.when_rendering_to_lines do |t3|
22
+ t3.add_text "{"
23
+ end
24
+ end
25
+
26
+ t1.nested do |t2|
27
+ t2.insert_separated_list(
28
+ [id] + (object.attributes.keys.sort - [id])
29
+ ) do |t3, name|
30
+ t3.as_prefix_when_rendering_to_lines do |t4|
31
+ t4.add_text "#{name}: "
32
+ end
33
+
34
+ if name == id
35
+ t3.add_inspection_of object.id
36
+ else
37
+ t3.add_inspection_of object.read_attribute(name)
38
+ end
39
+ end
40
+ end
41
+
42
+ t1.as_lines_when_rendering_to_lines(
43
+ collection_bookend: :close
44
+ ) do |t2|
45
+ # stree-ignore
46
+ t2.when_rendering_to_lines do |t3|
47
+ t3.add_text "}"
48
+ end
49
+
50
+ t2.add_text ">"
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,34 @@
1
+ module SuperDiff
2
+ module ActiveRecord
3
+ module InspectionTreeBuilders
4
+ class ActiveRecordRelation < Core::AbstractInspectionTreeBuilder
5
+ def self.applies_to?(value)
6
+ value.is_a?(::ActiveRecord::Relation)
7
+ end
8
+
9
+ def call
10
+ Core::InspectionTree.new do |t1|
11
+ # stree-ignore
12
+ t1.as_lines_when_rendering_to_lines(
13
+ collection_bookend: :open
14
+ ) do |t2|
15
+ t2.add_text "#<ActiveRecord::Relation ["
16
+ end
17
+
18
+ # stree-ignore
19
+ t1.nested do |t2|
20
+ t2.insert_array_inspection_of(object)
21
+ end
22
+
23
+ # stree-ignore
24
+ t1.as_lines_when_rendering_to_lines(
25
+ collection_bookend: :close
26
+ ) do |t2|
27
+ t2.add_text "]>"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module SuperDiff
2
+ module ActiveRecord
3
+ module InspectionTreeBuilders
4
+ autoload(
5
+ :ActiveRecordModel,
6
+ "super_diff/active_record/inspection_tree_builders/active_record_model"
7
+ )
8
+ autoload(
9
+ :ActiveRecordRelation,
10
+ "super_diff/active_record/inspection_tree_builders/active_record_relation"
11
+ )
12
+ end
13
+ end
14
+ end
@@ -1,9 +1,12 @@
1
1
  # rubocop:disable Style/BracesAroundHashParameters, Style/ClassAndModuleChildren
2
2
  class ActiveRecord::Base
3
+ # TODO: Remove this monkey patch if possible
3
4
  def attributes_for_super_diff
4
- (attributes.keys.sort - ["id"]).reduce({ id: id }) do |hash, key|
5
- hash.merge(key.to_sym => attributes[key])
6
- end
5
+ id_attr = self.class.primary_key
6
+
7
+ (attributes.keys.sort - [id_attr]).reduce(
8
+ { id_attr.to_sym => id }
9
+ ) { |hash, key| hash.merge(key.to_sym => attributes[key]) }
7
10
  end
8
11
  end
9
12
  # rubocop:enable Style/BracesAroundHashParameters, Style/ClassAndModuleChildren
@@ -1,10 +1,22 @@
1
1
  module SuperDiff
2
2
  module ActiveRecord
3
3
  module ObjectInspection
4
- autoload(
5
- :InspectionTreeBuilders,
6
- "super_diff/active_record/object_inspection/inspection_tree_builders"
7
- )
4
+ module InspectionTreeBuilders
5
+ def self.const_missing(missing_const_name)
6
+ if ActiveRecord::InspectionTreeBuilders.const_defined?(
7
+ missing_const_name
8
+ )
9
+ warn <<~EOT
10
+ WARNING: SuperDiff::ActiveRecord::ObjectInspection::InspectionTreeBuilders::#{missing_const_name} is deprecated and will be removed in the next major release.
11
+ Please use SuperDiff::ActiveRecord::InspectionTreeBuilders::#{missing_const_name} instead.
12
+ #{caller_locations.join("\n")}
13
+ EOT
14
+ ActiveRecord::InspectionTreeBuilders.const_get(missing_const_name)
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
8
20
  end
9
21
  end
10
22
  end
@@ -1,7 +1,7 @@
1
1
  module SuperDiff
2
2
  module ActiveRecord
3
3
  module OperationTreeBuilders
4
- class ActiveRecordModel < SuperDiff::OperationTreeBuilders::CustomObject
4
+ class ActiveRecordModel < Basic::OperationTreeBuilders::CustomObject
5
5
  def self.applies_to?(expected, actual)
6
6
  expected.is_a?(::ActiveRecord::Base) &&
7
7
  actual.is_a?(::ActiveRecord::Base) && expected.class == actual.class
@@ -9,8 +9,12 @@ module SuperDiff
9
9
 
10
10
  protected
11
11
 
12
+ def id
13
+ expected.class.primary_key
14
+ end
15
+
12
16
  def attribute_names
13
- ["id"] + (expected.attributes.keys.sort - ["id"])
17
+ [id] + (expected.attributes.keys.sort - [id])
14
18
  end
15
19
  end
16
20
  end
@@ -1,7 +1,7 @@
1
1
  module SuperDiff
2
2
  module ActiveRecord
3
3
  module OperationTreeBuilders
4
- class ActiveRecordRelation < SuperDiff::OperationTreeBuilders::Array
4
+ class ActiveRecordRelation < Basic::OperationTreeBuilders::Array
5
5
  def self.applies_to?(expected, actual)
6
6
  expected.is_a?(::Array) && actual.is_a?(::ActiveRecord::Relation)
7
7
  end
@@ -1,7 +1,7 @@
1
1
  module SuperDiff
2
2
  module ActiveRecord
3
3
  module OperationTreeFlatteners
4
- class ActiveRecordRelation < SuperDiff::OperationTreeFlatteners::Collection
4
+ class ActiveRecordRelation < Basic::OperationTreeFlatteners::Collection
5
5
  protected
6
6
 
7
7
  def open_token
@@ -1,7 +1,7 @@
1
1
  module SuperDiff
2
2
  module ActiveRecord
3
3
  module OperationTrees
4
- class ActiveRecordRelation < SuperDiff::OperationTrees::Array
4
+ class ActiveRecordRelation < Basic::OperationTrees::Array
5
5
  def self.applies_to?(value)
6
6
  value.is_a?(ActiveRecord::Relation)
7
7
  end
@@ -1,28 +1,24 @@
1
1
  require "super_diff/active_support"
2
2
 
3
+ require "super_diff/active_record/differs"
4
+ require "super_diff/active_record/inspection_tree_builders"
5
+ require "super_diff/active_record/operation_trees"
6
+ require "super_diff/active_record/operation_tree_builders"
7
+ require "super_diff/active_record/operation_tree_flatteners"
8
+
3
9
  module SuperDiff
4
10
  module ActiveRecord
5
- autoload :Differs, "super_diff/active_record/differs"
6
- autoload(:ObjectInspection, "super_diff/active_record/object_inspection")
7
- autoload(:OperationTrees, "super_diff/active_record/operation_trees")
8
- autoload(
9
- :OperationTreeBuilders,
10
- "super_diff/active_record/operation_tree_builders"
11
- )
12
- autoload(
13
- :OperationTreeFlatteners,
14
- "super_diff/active_record/operation_tree_flatteners"
15
- )
11
+ autoload :ObjectInspection, "super_diff/active_record/object_inspection"
16
12
 
17
13
  SuperDiff.configure do |config|
18
- config.add_extra_differ_classes(Differs::ActiveRecordRelation)
19
- config.add_extra_operation_tree_builder_classes(
14
+ config.prepend_extra_differ_classes(Differs::ActiveRecordRelation)
15
+ config.prepend_extra_operation_tree_builder_classes(
20
16
  OperationTreeBuilders::ActiveRecordModel,
21
17
  OperationTreeBuilders::ActiveRecordRelation
22
18
  )
23
- config.add_extra_inspection_tree_builder_classes(
24
- ObjectInspection::InspectionTreeBuilders::ActiveRecordModel,
25
- ObjectInspection::InspectionTreeBuilders::ActiveRecordRelation
19
+ config.prepend_extra_inspection_tree_builder_classes(
20
+ InspectionTreeBuilders::ActiveRecordModel,
21
+ InspectionTreeBuilders::ActiveRecordRelation
26
22
  )
27
23
  end
28
24
  end
@@ -1,7 +1,7 @@
1
1
  module SuperDiff
2
2
  module ActiveSupport
3
3
  module Differs
4
- class HashWithIndifferentAccess < SuperDiff::Differs::Hash
4
+ class HashWithIndifferentAccess < Basic::Differs::Hash
5
5
  def self.applies_to?(expected, actual)
6
6
  (
7
7
  expected.is_a?(::HashWithIndifferentAccess) && actual.is_a?(::Hash)
@@ -0,0 +1,44 @@
1
+ module SuperDiff
2
+ module ActiveSupport
3
+ module InspectionTreeBuilders
4
+ class HashWithIndifferentAccess < Core::AbstractInspectionTreeBuilder
5
+ def self.applies_to?(value)
6
+ value.is_a?(::HashWithIndifferentAccess)
7
+ end
8
+
9
+ def call
10
+ Core::InspectionTree.new do |t1|
11
+ # stree-ignore
12
+ t1.as_lines_when_rendering_to_lines(
13
+ collection_bookend: :open
14
+ ) do |t2|
15
+ t2.add_text "#<HashWithIndifferentAccess {"
16
+ end
17
+
18
+ # stree-ignore
19
+ t1.when_rendering_to_string do |t2|
20
+ t2.add_text " "
21
+ end
22
+
23
+ # stree-ignore
24
+ t1.nested do |t2|
25
+ t2.insert_hash_inspection_of(object)
26
+ end
27
+
28
+ # stree-ignore
29
+ t1.when_rendering_to_string do |t2|
30
+ t2.add_text " "
31
+ end
32
+
33
+ # stree-ignore
34
+ t1.as_lines_when_rendering_to_lines(
35
+ collection_bookend: :close
36
+ ) do |t2|
37
+ t2.add_text "}>"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ module SuperDiff
2
+ module ActiveSupport
3
+ module InspectionTreeBuilders
4
+ class OrderedOptions < Basic::InspectionTreeBuilders::Hash
5
+ def self.applies_to?(value)
6
+ value.is_a?(::ActiveSupport::OrderedOptions)
7
+ end
8
+
9
+ def call
10
+ Core::InspectionTree.new do |t1|
11
+ # stree-ignore
12
+ t1.as_lines_when_rendering_to_lines(
13
+ collection_bookend: :open
14
+ ) do |t2|
15
+ t2.add_text "#<OrderedOptions {"
16
+ end
17
+
18
+ # stree-ignore
19
+ t1.when_rendering_to_string do |t2|
20
+ t2.add_text " "
21
+ end
22
+
23
+ # stree-ignore
24
+ t1.nested do |t2|
25
+ t2.insert_hash_inspection_of(object.to_hash)
26
+ end
27
+
28
+ # stree-ignore
29
+ t1.when_rendering_to_string do |t2|
30
+ t2.add_text " "
31
+ end
32
+
33
+ # stree-ignore
34
+ t1.as_lines_when_rendering_to_lines(
35
+ collection_bookend: :close
36
+ ) do |t2|
37
+ t2.add_text "}>"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,14 @@
1
+ module SuperDiff
2
+ module ActiveSupport
3
+ module InspectionTreeBuilders
4
+ autoload(
5
+ :HashWithIndifferentAccess,
6
+ "super_diff/active_support/inspection_tree_builders/hash_with_indifferent_access"
7
+ )
8
+ autoload(
9
+ :OrderedOptions,
10
+ "super_diff/active_support/inspection_tree_builders/ordered_options"
11
+ )
12
+ end
13
+ end
14
+ end
@@ -1,10 +1,22 @@
1
1
  module SuperDiff
2
2
  module ActiveSupport
3
3
  module ObjectInspection
4
- autoload(
5
- :InspectionTreeBuilders,
6
- "super_diff/active_support/object_inspection/inspection_tree_builders"
7
- )
4
+ module InspectionTreeBuilders
5
+ def self.const_missing(missing_const_name)
6
+ if ActiveSupport::InspectionTreeBuilders.const_defined?(
7
+ missing_const_name
8
+ )
9
+ warn <<~EOT
10
+ WARNING: SuperDiff::ActiveSupport::ObjectInspection::InspectionTreeBuilders::#{missing_const_name} is deprecated and will be removed in the next major release.
11
+ Please use SuperDiff::ActiveSupport::InspectionTreeBuilders::#{missing_const_name} instead.
12
+ #{caller_locations.join("\n")}
13
+ EOT
14
+ ActiveSupport::InspectionTreeBuilders.const_get(missing_const_name)
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
8
20
  end
9
21
  end
10
22
  end
@@ -1,7 +1,7 @@
1
1
  module SuperDiff
2
2
  module ActiveSupport
3
3
  module OperationTreeBuilders
4
- class HashWithIndifferentAccess < SuperDiff::OperationTreeBuilders::Hash
4
+ class HashWithIndifferentAccess < Basic::OperationTreeBuilders::Hash
5
5
  def self.applies_to?(expected, actual)
6
6
  (
7
7
  expected.is_a?(::HashWithIndifferentAccess) && actual.is_a?(::Hash)
@@ -1,7 +1,7 @@
1
1
  module SuperDiff
2
2
  module ActiveSupport
3
3
  module OperationTreeFlatteners
4
- class HashWithIndifferentAccess < SuperDiff::OperationTreeFlatteners::Hash
4
+ class HashWithIndifferentAccess < Basic::OperationTreeFlatteners::Hash
5
5
  protected
6
6
 
7
7
  def open_token