Skip to content

Commit 89b7b77

Browse files
committed
Fix formatting diffs between two non-custom objects
When comparing different versions of the same non-custom object — that is, an object which does not have an `attributes_for_super_diff` method — the way that we present the diff between the two versions needs to match the way that that object is deep-inspected. This commit fixes this by splitting Object at each level into CustomObject and DefaultObject.
1 parent 1cf3bc3 commit 89b7b77

File tree

26 files changed

+177
-166
lines changed

26 files changed

+177
-166
lines changed

lib/super_diff/active_record/operational_sequencers/active_record_model.rb

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module SuperDiff
22
module ActiveRecord
33
module OperationalSequencers
4-
class ActiveRecordModel < SuperDiff::OperationalSequencers::Object
4+
class ActiveRecordModel < SuperDiff::OperationalSequencers::CustomObject
55
def self.applies_to?(expected, actual)
66
expected.is_a?(::ActiveRecord::Base) &&
77
actual.is_a?(::ActiveRecord::Base) &&
@@ -13,18 +13,6 @@ def self.applies_to?(expected, actual)
1313
def attribute_names
1414
["id"] + (expected.attributes.keys.sort - ["id"])
1515
end
16-
17-
private
18-
19-
def establish_expected_and_actual_attributes
20-
@expected_attributes = attribute_names.reduce({}) do |hash, name|
21-
hash.merge(name => expected.read_attribute(name))
22-
end
23-
24-
@actual_attributes = attribute_names.reduce({}) do |hash, name|
25-
hash.merge(name => actual.read_attribute(name))
26-
end
27-
end
2816
end
2917
end
3018
end

lib/super_diff/diff_formatters.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ module DiffFormatters
33
autoload :Array, "super_diff/diff_formatters/array"
44
autoload :Base, "super_diff/diff_formatters/base"
55
autoload :Collection, "super_diff/diff_formatters/collection"
6+
autoload :CustomObject, "super_diff/diff_formatters/custom_object"
7+
autoload :DefaultObject, "super_diff/diff_formatters/default_object"
68
autoload :Hash, "super_diff/diff_formatters/hash"
79
autoload :MultilineString, "super_diff/diff_formatters/multiline_string"
8-
autoload :Object, "super_diff/diff_formatters/object"
910

11+
# TODO: Why doesn't this include CustomObject and DefaultObject?
1012
DEFAULTS = [Array, Hash, MultilineString].freeze
1113
end
1214
end
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module SuperDiff
2+
module DiffFormatters
3+
class CustomObject < DefaultObject
4+
def self.applies_to?(operations)
5+
operations.is_a?(OperationSequences::CustomObject)
6+
end
7+
8+
def call
9+
Collection.call(
10+
open_token: "#<#{value_class} {",
11+
close_token: "}>",
12+
collection_prefix: collection_prefix,
13+
build_item_prefix: -> (operation) {
14+
key =
15+
if operation.respond_to?(:left_key)
16+
operation.left_key
17+
else
18+
operation.key
19+
end
20+
21+
"#{key}: "
22+
},
23+
operations: operations,
24+
indent_level: indent_level,
25+
add_comma: add_comma?,
26+
)
27+
end
28+
end
29+
end
30+
end

lib/super_diff/diff_formatters/object.rb renamed to lib/super_diff/diff_formatters/default_object.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
module SuperDiff
22
module DiffFormatters
3-
class Object < Base
3+
class DefaultObject < Base
44
def self.applies_to?(operations)
5-
operations.is_a?(OperationSequences::Object)
5+
operations.is_a?(OperationSequences::DefaultObject)
66
end
77

88
def initialize(operations, value_class: nil, **rest)
@@ -24,7 +24,7 @@ def call
2424
operation.key
2525
end
2626

27-
"#{key}: "
27+
"@#{key}="
2828
},
2929
operations: operations,
3030
indent_level: indent_level,

lib/super_diff/differs.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
module SuperDiff
22
module Differs
3-
autoload :Base, "super_diff/differs/base"
43
autoload :Array, "super_diff/differs/array"
4+
autoload :Base, "super_diff/differs/base"
5+
autoload :CustomObject, "super_diff/differs/custom_object"
6+
autoload :DefaultObject, "super_diff/differs/default_object"
57
autoload :Empty, "super_diff/differs/empty"
68
autoload :Hash, "super_diff/differs/hash"
79
autoload :MultilineString, "super_diff/differs/multiline_string"
8-
autoload :Object, "super_diff/differs/object"
910

10-
DEFAULTS = [Array, Hash, MultilineString, Object, Empty].freeze
11+
DEFAULTS = [
12+
Array,
13+
Hash,
14+
MultilineString,
15+
CustomObject,
16+
DefaultObject,
17+
Empty,
18+
].freeze
1119
end
1220
end

lib/super_diff/differs/object.rb renamed to lib/super_diff/differs/custom_object.rb

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
module SuperDiff
22
module Differs
3-
class Object < Base
3+
class CustomObject < Base
44
def self.applies_to?(expected, actual)
5-
expected.is_a?(::Object) && actual.is_a?(::Object)
5+
expected.respond_to?(:attributes_for_super_diff) &&
6+
actual.respond_to?(:attributes_for_super_diff)
67
end
78

89
def call
@@ -12,14 +13,7 @@ def call
1213
private
1314

1415
def operations
15-
OperationalSequencer.call(
16-
expected: expected,
17-
actual: actual,
18-
extra_classes: extra_operational_sequencer_classes,
19-
extra_diff_formatter_classes: extra_diff_formatter_classes,
20-
)
21-
rescue SuperDiff::NoOperationalSequencerAvailableError
22-
OperationalSequencers::Object.call(
16+
OperationalSequencers::CustomObject.call(
2317
expected: expected,
2418
actual: actual,
2519
extra_operational_sequencer_classes: extra_operational_sequencer_classes,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module SuperDiff
2+
module Differs
3+
class DefaultObject < Base
4+
def self.applies_to?(_expected, _actual)
5+
true
6+
end
7+
8+
def call
9+
operations.to_diff(indent_level: indent_level)
10+
end
11+
12+
private
13+
14+
def operations
15+
OperationalSequencer.call(
16+
expected: expected,
17+
actual: actual,
18+
all_or_nothing: true,
19+
extra_classes: extra_operational_sequencer_classes,
20+
extra_diff_formatter_classes: extra_diff_formatter_classes,
21+
)
22+
end
23+
end
24+
end
25+
end

lib/super_diff/equality_matchers/object.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def fail
3333
protected
3434

3535
def diff
36-
Differs::Object.call(
36+
Differ.call(
3737
expected,
3838
actual,
3939
indent_level: 0,

lib/super_diff/operation_sequences.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ module SuperDiff
22
module OperationSequences
33
autoload :Array, "super_diff/operation_sequences/array"
44
autoload :Base, "super_diff/operation_sequences/base"
5+
autoload :CustomObject, "super_diff/operation_sequences/custom_object"
6+
autoload :DefaultObject, "super_diff/operation_sequences/default_object"
57
autoload :Hash, "super_diff/operation_sequences/hash"
6-
autoload :Object, "super_diff/operation_sequences/object"
78
end
89
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module SuperDiff
2+
module OperationSequences
3+
class CustomObject < DefaultObject
4+
def to_diff(indent_level:, add_comma: false, collection_prefix: nil)
5+
DiffFormatters::CustomObject.call(
6+
self,
7+
indent_level: indent_level,
8+
collection_prefix: collection_prefix,
9+
add_comma: add_comma,
10+
value_class: value_class,
11+
)
12+
end
13+
end
14+
end
15+
end

0 commit comments

Comments
 (0)