Files
prism/test/test_orm_dirty.rb

124 lines
3.9 KiB
Ruby

require 'minitest/autorun'
require 'prism'
require 'tmpdir'
class OrmDirtyTest < Minitest::Test
def setup
@dir = Dir.mktmpdir('prism-dirty-store')
@store = Prism::Orm::Store.new(File.join(@dir, 'test.pstore'))
@store.create_table(:widgets, %w[id name notes])
widget_class = Class.new(Prism::Orm::Model) do
table_name :widgets
end
widget_class.store = @store
Object.const_set(:Widget, widget_class)
end
def teardown
FileUtils.remove_entry(@dir)
Object.send(:remove_const, :Widget) if Object.const_defined?(:Widget)
end
def test_new_record_shows_assigned_attributes_as_changed
widget = Widget.new(name: 'gizmo')
assert widget.changed?
assert_includes widget.changed, 'name'
assert_equal [nil, 'gizmo'], widget.changes['name']
end
def test_persisted_record_is_clean_right_after_load
widget = Widget.create!(name: 'gizmo')
refute widget.changed?
reloaded = Widget.find(widget.id)
refute reloaded.changed?
assert_empty reloaded.changes
end
def test_setting_an_attribute_marks_it_changed_with_old_and_new_value
widget = Widget.create!(name: 'gizmo')
widget.name = 'sprocket'
assert widget.changed?
assert widget.attribute_changed?(:name)
assert_equal 'gizmo', widget.attribute_was(:name)
assert_equal %w[gizmo sprocket], widget.attribute_change(:name)
refute widget.attribute_changed?(:notes)
end
def test_setting_an_attribute_back_to_its_original_value_clears_the_change
widget = Widget.create!(name: 'gizmo')
widget.name = 'sprocket'
widget.name = 'gizmo'
refute widget.changed?
refute widget.attribute_changed?(:name)
end
def test_restore_attributes_reverts_unsaved_changes
widget = Widget.create!(name: 'gizmo', notes: 'first')
widget.name = 'sprocket'
widget.notes = 'second'
widget.restore_attributes(['name'])
assert_equal 'gizmo', widget.name
assert_equal 'second', widget.notes
assert widget.changed?
widget.restore_attributes
refute widget.changed?
assert_equal 'first', widget.notes
end
def test_save_clears_current_changes_and_populates_saved_changes
widget = Widget.create!(name: 'gizmo')
widget.name = 'sprocket'
widget.save!
refute widget.changed?
assert widget.saved_change_to_attribute?('name')
assert_equal %w[gizmo sprocket], widget.saved_change_to_attribute('name')
assert_equal %w[gizmo sprocket], widget.saved_changes['name']
end
def test_saved_changes_on_create_shows_nil_to_assigned_value
widget = Widget.create!(name: 'gizmo')
assert_equal [nil, 'gizmo'], widget.saved_changes['name']
end
def test_saving_with_no_changes_yields_empty_saved_changes
widget = Widget.create!(name: 'gizmo')
widget.save!
assert_empty widget.saved_changes
end
def test_update_only_reports_the_actually_different_attribute
widget = Widget.create!(name: 'gizmo', notes: 'first')
widget.update!(name: 'gizmo', notes: 'second')
assert_equal %w[notes], widget.saved_changes.keys
end
def test_reload_discards_unsaved_changes
widget = Widget.create!(name: 'gizmo')
widget.name = 'sprocket'
widget.reload
assert_equal 'gizmo', widget.name
refute widget.changed?
end
def test_before_save_callback_can_inspect_pending_changes
seen = []
widget_class = Class.new(Prism::Orm::Model) do
table_name :widgets
before_save { seen << attribute_changed?(:name) }
end
widget_class.store = @store
widget = widget_class.create!(name: 'gizmo')
widget.update!(name: 'sprocket')
widget.save!
assert_equal [true, true, false], seen
end
def test_touching_updated_at_column_is_itself_tracked_as_a_change
@store.create_table(:stamped, %w[id name updated_at])
stamped_class = Class.new(Prism::Orm::Model) { table_name :stamped }
stamped_class.store = @store
record = stamped_class.create!(name: 'a')
assert record.saved_change_to_attribute?('updated_at')
end
end