test/twin/twin_test.rb in disposable-0.0.6 vs test/twin/twin_test.rb in disposable-0.0.7
- old
+ new
@@ -7,73 +7,63 @@
Album = Struct.new(:id, :name, :songs)
end
module Twin
- class Song < Disposable::Twin
- end
-
class Album < Disposable::Twin
property :id # DISCUSS: needed for #save.
property :name
collection :songs, :twin => lambda { |*| Song }
- model Model::Album
+ # model Model::Album
end
class Song < Disposable::Twin
property :id # DISCUSS: needed for #save.
- property :title
+ property :name, :as => :title
property :album, :twin => Album
- model Model::Song
+ # model Model::Song
end
end
+ let (:song) { Model::Song.new(1, "Broken", nil) }
- describe "::new" do # TODO: this creates a new model!
- let(:album) { Twin::Album.new }
- let (:song) { Twin::Song.new }
+ describe "#initialize" do
+ it do
+ twin = Twin::Song.new(song)
+ song.id = 2
+ # :as maps public name
+ twin.name.must_equal "Broken" # public: #name
+ twin.id.must_equal 2
+ end
- it { album.name.must_equal nil }
- it { album.songs.must_equal nil }
- it { song.title.must_equal nil }
- it { song.album.must_equal nil }
- end
+ # override property with public name in constructor.
+ it do
+ # override twin's value...
+ Twin::Song.new(song, :name => "Kenny").name.must_equal "Kenny"
-
- describe "::new with arguments" do
- let (:talking) { Twin::Song.new("title" => "Talking") }
- let (:album) { Twin::Album.new(:name => "30 Years", :songs => [talking]) }
- subject { Twin::Song.new("title" => "Broken", "album" => album) }
-
- it { subject.title.must_equal "Broken" }
- it { subject.album.must_equal album }
- it { subject.album.name.must_equal "30 Years" }
- it { album.songs.must_equal [talking] }
+ # .. but do not write to the model!
+ song.title.must_equal "Broken"
+ end
end
+ describe "setter" do
+ let (:twin) { Twin::Song.new(song) }
- describe "::new with :symbols" do
- subject { Twin::Song.new(:title => "Broken") }
+ before do
+ twin.id = 3
+ twin.name = "Lucky"
+ end
- it { subject.title.must_equal "Broken" }
- it { subject.album.must_equal nil }
- end
+ # updates twin
+ it { twin.id.must_equal 3 }
+ it { twin.name.must_equal "Lucky" }
-
- # DISCUSS: make ::from private.
- describe "::from" do
- let (:song) { Model::Song.new(1, "Broken", album) }
- let (:album) { Model::Album.new(2, "The Process Of Belief", [Model::Song.new(3, "Dr. Stein")]) }
-
- subject {Twin::Song.from(song) }
-
- it { subject.title.must_equal "Broken" }
- it { subject.album.must_be_kind_of Twin::Album }
- it { subject.album.name.must_equal album.name }
- it { subject.album.songs.first.title.must_equal "Dr. Stein" } # TODO: more tests on collections and object identity (if we need that).
+ # DOES NOT update model
+ it { song.id.must_equal 1 }
+ it { song.title.must_equal "Broken" }
end
end
class OverridingAccessorsTest < TwinTest
@@ -84,27 +74,44 @@
def title
super.downcase
end
end
- it { Song.from(Model::Song.new(1, "A Tale That Wasn't Right")).title.must_equal "a tale that wasn't right" }
+ it { Song.new(Model::Song.new(1, "A Tale That Wasn't Right")).title.must_equal "a tale that wasn't right" }
end
class TwinDecoratorTest < MiniTest::Spec
subject { TwinTest::Twin::Song.representer_class.new(nil) }
it { subject.twin_names.must_equal [:album] }
end
-# from is as close to from_hash as possible
-# there should be #to in a perfect API, nothing else.
+require 'disposable/twin/struct'
+class TwinStructTest < MiniTest::Spec
+ class Song < Disposable::Twin
+ include Struct
+ property :number, :default => 1 # FIXME: this should be :default_if_nil so it becomes clear with a model.
+ option :cool?
+ end
-# should #new create empty associated models?
+ # empty hash
+ it { Song.new({}).number.must_equal 1 }
+ # model hash
+ it { Song.new(number: 2).number.must_equal 2 }
+ # with hash and options as one hash.
+ it { Song.new(number: 3, cool?: true).cool?.must_equal true }
+ it { Song.new(number: 3, cool?: true).number.must_equal 3 }
+ # with model hash and options hash separated.
+ it { Song.new({number: 3}, {cool?: true}).cool?.must_equal true }
+ it { Song.new({number: 3}, {cool?: true}).number.must_equal 3 }
+end
+
+
class TwinAsTest < MiniTest::Spec
module Model
Song = Struct.new(:title, :album)
Album = Struct.new(:name)
end
@@ -112,72 +119,46 @@
module Twin
class Album < Disposable::Twin
property :record_name, :as => :name
- model Model::Album
+ # model Model::Album
end
class Song < Disposable::Twin
property :name, :as => :title
property :record, :twin => Album, :as => :album
- model Model::Song
+ # model Model::Song
end
end
-
- let (:record) { Twin::Album.new(:record_name => "Veni Vidi Vicous") }
- subject { Twin::Song.new(:name => "Outsmarted", :record => record) }
-
-
- describe "::new" do # TODO: this creates a new model!
- # the Twin exposes the as: API.
- it { subject.name.must_equal "Outsmarted" }
- it { subject.record.must_equal record }
- end
-
- # DISCUSS: should we test saving without AR? is that worth the hustle?
- # describe "#save" do
- # before { subject.send(:model).instance_eval do
- # def update_attributes(*)
-
- # end
- # end
- # subject.save
- # }
-
-
-
- # # before { subject.save }
-
- # it { subject.name }
- # end
end
-require 'disposable/twin/option'
class TwinOptionTest < TwinTest
class Song < Disposable::Twin
- include Option
-
property :id # DISCUSS: needed for #save.
property :title
option :preview?
option :highlight?
end
+ let (:song) { Model::Song.new(1, "Broken") }
+ let (:twin) { Song.new(song, :preview? => false) }
- describe "::from" do
- let (:song) { Model::Song.new(1, "Broken") }
- let (:twin) { Song.from(song, :preview? => false) }
- it { twin.id.must_equal 1 }
- it { twin.title.must_equal "Broken" }
- it { twin.preview?.must_equal false }
+ # properties are read from model.
+ it { twin.id.must_equal 1 }
+ it { twin.title.must_equal "Broken" }
- it { Song.from(song, :preview? => true, :highlight => false).preview?.must_equal true }
- end
+ # option is not delegated to model.
+ it { twin.preview?.must_equal false }
+ # not passing option means zero.
+ it { twin.highlight?.must_equal nil }
+
+ # passing both options.
+ it { Song.new(song, preview?: true, highlight?: false).preview?.must_equal true }
end
# TODO: test coercion!
\ No newline at end of file