Skip to content

Commit 4c305a2

Browse files
committed
Add support for diffing ActiveRecord objects
Introduce a new way of using the gem in Rails projects. Instead of saying: require "super_diff/rspec" you say: require "super_diff/rspec-rails" And this will give you support for ActiveRecord (and other Rails types of things in the future). Or you can say: require "super_diff/rspec" require "super_diff/active_record" if you're only interested in support for ActiveRecord.
1 parent 0ecef78 commit 4c305a2

36 files changed

+838
-304
lines changed

Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ source "https://rubygems.org"
44

55
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
66

7+
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
78
gem "childprocess"
9+
gem "jdbc-sqlite3", platform: :jruby
810
gem "pry-byebug", platform: :mri
911
gem "pry-nav", platform: :jruby
1012
gem "rake"
@@ -13,5 +15,6 @@ gem "rspec-expectations", github: "rspec/rspec-expectations"
1315
gem "rspec-mocks", github: "rspec/rspec-mocks"
1416
gem "rspec-support", github: "rspec/rspec-support"
1517
gem "rubocop"
18+
gem "sqlite3", platform: [:ruby, :mswin, :mingw]
1619

1720
gemspec

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ gem "super_diff"
101101
After running `bundle install`, add the following to your `rails_helper`:
102102

103103
``` ruby
104-
require "super_diff/rspec"
104+
require "super_diff/rspec-rails"
105105
```
106106

107107
You're done!

lib/super_diff/active_record.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module SuperDiff
2+
module ActiveRecord
3+
autoload(
4+
:ObjectInspection,
5+
"super_diff/active_record/object_inspection",
6+
)
7+
autoload(
8+
:OperationalSequencer,
9+
"super_diff/active_record/operational_sequencer",
10+
)
11+
end
12+
end
13+
14+
if defined?(SuperDiff::RSpec)
15+
SuperDiff::RSpec.configuration.add_extra_operational_sequencer_class(
16+
SuperDiff::ActiveRecord::OperationalSequencer,
17+
)
18+
end
19+
20+
SuperDiff::ObjectInspection.map.prepend(
21+
SuperDiff::ActiveRecord::ObjectInspection::MapExtension,
22+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module SuperDiff
2+
module ActiveRecord
3+
module ObjectInspection
4+
autoload(
5+
:Inspector,
6+
"super_diff/active_record/object_inspection/inspector",
7+
)
8+
autoload(
9+
:MapExtension,
10+
"super_diff/active_record/object_inspection/map_extension",
11+
)
12+
end
13+
end
14+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module SuperDiff
2+
module ActiveRecord
3+
module ObjectInspection
4+
Inspector = SuperDiff::ObjectInspection::InspectionTree.new do
5+
add_text do |object|
6+
"#<#{object.class} "
7+
end
8+
9+
when_multiline do
10+
add_text "{"
11+
end
12+
13+
nested do |object|
14+
add_break
15+
16+
insert_separated_list(
17+
["id"] + (object.attributes.keys.sort - ["id"]),
18+
separator: ",",
19+
) do |name|
20+
add_text name
21+
add_text ": "
22+
add_inspection_of object.read_attribute(name)
23+
end
24+
end
25+
26+
add_break
27+
28+
when_multiline do
29+
add_text "}"
30+
end
31+
32+
add_text ">"
33+
end
34+
end
35+
end
36+
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module SuperDiff
2+
module ActiveRecord
3+
module ObjectInspection
4+
module MapExtension
5+
def call(object)
6+
if object.is_a?(::ActiveRecord::Base)
7+
Inspector
8+
else
9+
super
10+
end
11+
end
12+
end
13+
end
14+
end
15+
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module SuperDiff
2+
module ActiveRecord
3+
class OperationalSequencer < SuperDiff::OperationalSequencers::Object
4+
def self.applies_to?(expected, actual)
5+
expected.is_a?(::ActiveRecord::Base) &&
6+
actual.is_a?(::ActiveRecord::Base) &&
7+
expected.class == actual.class
8+
end
9+
10+
protected
11+
12+
def attribute_names
13+
["id"] + (expected.attributes.keys.sort - ["id"])
14+
end
15+
16+
private
17+
18+
def establish_expected_and_actual_attributes
19+
@expected_attributes = attribute_names.reduce({}) do |hash, name|
20+
hash.merge(name => expected.read_attribute(name))
21+
end
22+
23+
@actual_attributes = attribute_names.reduce({}) do |hash, name|
24+
hash.merge(name => actual.read_attribute(name))
25+
end
26+
end
27+
end
28+
end
29+
end

lib/super_diff/object_inspection.rb

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
11
module SuperDiff
22
module ObjectInspection
33
autoload :InspectionTree, "super_diff/object_inspection/inspection_tree"
4-
autoload(
5-
:InspectorFinder,
6-
"super_diff/object_inspection/inspector_finder",
7-
)
84
autoload :Inspectors, "super_diff/object_inspection/inspectors"
5+
autoload :Map, "super_diff/object_inspection/map"
96
autoload :Nodes, "super_diff/object_inspection/nodes"
107

118
class << self
12-
attr_accessor :inspector_finder
9+
attr_accessor :map
1310
end
1411

1512
def self.inspect(object, as_single_line:, indent_level: 0)
16-
inspector_finder.call(object).evaluate(
13+
map.call(object).evaluate(
1714
object,
1815
as_single_line: as_single_line,
1916
indent_level: indent_level,
2017
)
2118
end
2219

23-
self.inspector_finder = InspectorFinder
20+
self.map = Map.new
2421
end
2522
end

lib/super_diff/object_inspection/inspector_finder.rb renamed to lib/super_diff/object_inspection/map.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
module SuperDiff
22
module ObjectInspection
3-
class InspectorFinder
4-
def self.call(object)
3+
class Map
4+
def prepend(mod)
5+
singleton_class.prepend(mod)
6+
end
7+
8+
def call(object)
59
if object.respond_to?(:attributes_for_super_diff)
610
Inspectors::CustomObject
711
else
@@ -13,8 +17,7 @@ def self.call(object)
1317
when String
1418
Inspectors::String
1519
when true, false, nil, Symbol, Numeric, Regexp
16-
Inspectors::Primitive
17-
else
20+
Inspectors::Primitive else
1821
Inspectors::DefaultObject
1922
end
2023
end

lib/super_diff/rails.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require "super_diff/active_record"

0 commit comments

Comments
 (0)