require "test_helper" require "disposable/callback" require "pp" class CallbackGroupTest < MiniTest::Spec class Group < Disposable::Callback::Group attr_reader :output on_change :change! collection :songs do on_add :notify_album! on_add :reset_song! # on_delete :notify_deleted_author! # in Update! def notify_album!(twin, options) options[:content] << "notify_album!" end def reset_song!(twin, options) options[:content] << "reset_song!" end end on_change :rehash_name!, property: :title on_create :expire_cache! # on_change on_update :expire_cache! def change!(twin, options) @output = "Album has changed!" end end class AlbumTwin < Disposable::Twin feature Sync, Save feature Persisted, Changed property :name property :artist do property :name end collection :songs do property :title end end # empty. it do album = Album.new(songs: [Song.new(title: "Dead To Me"), Song.new(title: "Diesel Boy")]) twin = AlbumTwin.new(album) Group.new(twin).().invocations.must_equal [ [:on_change, :change!, []], [:on_add, :notify_album!, []], [:on_add, :reset_song!, []], [:on_change, :rehash_name!, []], [:on_create, :expire_cache!, []], [:on_update, :expire_cache!, []], ] end # trigger songs:on_add, and on_change. let (:content) { "" } it do twin = AlbumTwin.new(Album.new) twin.songs << Song.new(title: "Dead To Me") twin.songs << Song.new(title: "Diesel Boy") twin.name = "Dear Landlord" group = Group.new(twin).(content: content) group.invocations.must_equal [ [:on_change, :change!, [twin]], [:on_add, :notify_album!, [twin.songs[0], twin.songs[1]]], [:on_add, :reset_song!, [twin.songs[0], twin.songs[1]]], [:on_change, :rehash_name!, []], [:on_create, :expire_cache!, []], [:on_update, :expire_cache!, []], ] content.must_equal "notify_album!notify_album!reset_song!reset_song!" group.output.must_equal "Album has changed!" end # context. class Operation attr_reader :output def change!(twin, options) options[:content] << "Op: changed! [#{options[:context].class}]" end def notify_album!(twin, options) options[:content] << "Op: notify_album! [#{options[:context].class}]" end def reset_song!(twin, options) options[:content] << "Op: reset_song! [#{options[:context].class}]" end def rehash_name!(twin, options) options[:content] << "Op: rehash_name! [#{options[:context].class}]" end def expire_cache!(twin, options) options[:content] << "Op: expire_cache! [#{options[:context].class}]" end end it do twin = AlbumTwin.new(Album.new) twin.songs << Song.new(title: "Dead To Me") twin.name = "Dear Landlord" group = Group.new(twin).(context: context = Operation.new, content: content) # Disposable::Callback::Dispatch.new(twin).on_change{ |twin| puts twin;puts } # pp group.invocations group.invocations.must_equal [ [:on_change, :change!, [twin]], [:on_add, :notify_album!, [twin.songs[0]]], [:on_add, :reset_song!, [twin.songs[0]]], [:on_change, :rehash_name!, []], [:on_create, :expire_cache!, []], [:on_update, :expire_cache!, []], ] content.must_equal "Op: changed! [CallbackGroupTest::Operation]Op: notify_album! [CallbackGroupTest::Operation]Op: reset_song! [CallbackGroupTest::Operation]" end end class CallbackGroupInheritanceTest < MiniTest::Spec class Group < Disposable::Callback::Group on_change :change! collection :songs do on_add :notify_album! on_add :reset_song! end on_change :rehash_name!, property: :title property :artist do on_change :sing! end end it do Group.hooks.size.must_equal 4 Group.hooks[0].to_s.must_equal "[:on_change, :change!, {}]" # Group.hooks[1][1][:nested].hooks.to_s.must_equal "[[:on_add, [:notify_album!]],[:on_add, [:reset_song!]]]" Group.hooks[2].to_s.must_equal "[:on_change, :rehash_name!, {:property=>:title}]" Group.definitions.get(Group.hooks[3][1])[:nested].hooks.to_s.must_equal "[[:on_change, :sing!, {}]]" end class EmptyGroup < Group end it do EmptyGroup.hooks.size.must_equal 4 # TODO: end class EnhancedGroup < Group on_change :redo! collection :songs do on_add :rewind! end end it do Group.hooks.size.must_equal 4 pp EnhancedGroup.hooks EnhancedGroup.hooks.size.must_equal 6 EnhancedGroup.definitions.get(EnhancedGroup.hooks[5][1])[:nested].hooks.to_s.must_equal "[[:on_add, :rewind!, {}]]" end class EnhancedWithInheritGroup < EnhancedGroup collection :songs, inherit: true do # finds first. on_add :eat! end property :artist, inherit: true do on_delete :yell! end end it do Group.hooks.size.must_equal 4 EnhancedGroup.hooks.size.must_equal 6 EnhancedGroup.definitions.get(EnhancedGroup.hooks[5][1])[:nested].hooks.to_s.must_equal "[[:on_add, :rewind!, {}]]" EnhancedWithInheritGroup.hooks.size.must_equal 6 EnhancedWithInheritGroup.definitions.get(EnhancedWithInheritGroup.hooks[1][1])[:nested].hooks.to_s.must_equal "[[:on_add, :rewind!, {}], [:on_add, :eat!, {}]]" EnhancedWithInheritGroup.definitions.get(EnhancedWithInheritGroup.hooks[3][1])[:nested].hooks.to_s.must_equal "[[:on_change, :sing!, {}], [:on_delete, :yell!, {}]]" end class RemovingInheritGroup < Group remove! :on_change, :change! collection :songs, inherit: true do # this will not change position remove! :on_add, :notify_album! end end # # puts "@@@@@ #{Group.hooks.object_id.inspect}" # # puts "@@@@@ #{EmptyGroup.hooks.object_id.inspect}" # puts "@@@@@ Group: #{Group.definitions.get(:songs)[:nested].hooks.inspect}" # puts "@@@@@ EnhancedGroup: #{EnhancedGroup.definitions.get(:songs)[:nested].hooks.inspect}" # puts "@@@@@ InheritGroup: #{EnhancedWithInheritGroup.definitions.get(:songs)[:nested].hooks.inspect}" # puts "@@@@@ RemovingGroup: #{RemovingInheritGroup.definitions.get(:songs)[:nested].hooks.inspect}" # # puts "@@@@@ #{EnhancedWithInheritGroup.definitions.get(:songs)[:nested].hooks.object_id.inspect}" # TODO: object_id tests for all nested representers. it do Group.hooks.size.must_equal 4 RemovingInheritGroup.hooks.size.must_equal 3 RemovingInheritGroup.definitions.get(RemovingInheritGroup.hooks[0][1])[:nested].hooks.to_s.must_equal "[[:on_add, :reset_song!, {}]]" RemovingInheritGroup.definitions.get(RemovingInheritGroup.hooks[2][1])[:nested].hooks.to_s.must_equal "[[:on_change, :sing!, {}]]" end # Group::clone ClonedGroup = Group.clone ClonedGroup.class_eval do remove! :on_change, :change! end it do Group.hooks.size.must_equal 4 ClonedGroup.hooks.size.must_equal 3 end end