disposable 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module Disposable
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
data/test/test_helper.rb CHANGED
@@ -10,6 +10,6 @@ class Track
10
10
  end
11
11
 
12
12
 
13
- require 'active_record'
14
- require 'database_cleaner'
15
- DatabaseCleaner.strategy = :truncation
13
+ # require 'active_record'
14
+ # require 'database_cleaner'
15
+ # DatabaseCleaner.strategy = :truncation
@@ -1,37 +1,45 @@
1
- # require 'test_helper'
1
+ require 'test_helper'
2
2
 
3
- # class TwinCompositionTest < MiniTest::Spec
4
- # class Request < Disposable::Twin::Composition
5
- # property :title, :on => :song, :as => :song_title
6
- # property :id, :on => :song, :as => :song_id
3
+ require 'disposable/twin/composition'
7
4
 
8
- # property :name, :on => :requester
5
+ class TwinCompositionTest < MiniTest::Spec
6
+ class Request < Disposable::Twin::Composition
7
+ property :song_title, :on => :song, :as => :title
8
+ property :song_id, :on => :song, :as => :id
9
9
 
10
- # # map ...
11
- # end
10
+ property :name, :on => :requester
11
+ property :id, :on => :requester
12
12
 
13
- # module Model
14
- # Song = Struct.new(:id, :title, :album)
15
- # Requester = Struct.new(:id, :name)
16
- # end
13
+ # map ...
17
14
 
18
- # let (:requester) { Model::Requester.new(1, "Greg Howe") }
19
- # let (:song) { Model::Song.new(2, "Extraction") }
15
+ # def id
16
+ # make map(name, options)
17
+ # option :played?
18
+ end
20
19
 
21
- # let (:request) { Request.new([:song => song, :requester => requester]) }
20
+ module Model
21
+ Song = Struct.new(:id, :title, :album)
22
+ Requester = Struct.new(:id, :name)
23
+ end
22
24
 
23
- # it { request.song_title.must_equal "Extraction" }
24
- # it { request.name.must_equal "Greg Howe" }
25
+ let (:requester) { Model::Requester.new(1, "Greg Howe") }
26
+ let (:song) { Model::Song.new(2, "Extraction") }
25
27
 
28
+ let (:request) { Request.new(:song => song, :requester => requester) }
26
29
 
27
- # describe "setter" do
28
- # before do
29
- # request.song_title = "Tease"
30
- # request.name = "Wooten"
31
- # end
30
+ it { request.song_title.must_equal "Extraction" }
31
+ it { request.name.must_equal "Greg Howe" }
32
32
 
33
- # it { request.song_title.must_equal "Tease" }
34
- # it { song.title.must_equal "Tease" }
35
- # it { request.name.must_equal "Wooten" }
36
- # end
37
- # end
33
+
34
+ describe "setter" do
35
+ before do
36
+ request.song_title = "Tease"
37
+ request.name = "Wooten"
38
+ end
39
+
40
+ it { request.song_title.must_equal "Tease" }
41
+ # no writing to model.
42
+ it { song.title.must_equal "Extraction" }
43
+ it { request.name.must_equal "Wooten" }
44
+ end
45
+ end
@@ -9,69 +9,59 @@ class TwinTest < MiniTest::Spec
9
9
 
10
10
 
11
11
  module Twin
12
- class Song < Disposable::Twin
13
- end
14
-
15
12
  class Album < Disposable::Twin
16
13
  property :id # DISCUSS: needed for #save.
17
14
  property :name
18
15
  collection :songs, :twin => lambda { |*| Song }
19
16
 
20
- model Model::Album
17
+ # model Model::Album
21
18
  end
22
19
 
23
20
  class Song < Disposable::Twin
24
21
  property :id # DISCUSS: needed for #save.
25
- property :title
22
+ property :name, :as => :title
26
23
  property :album, :twin => Album
27
24
 
28
- model Model::Song
25
+ # model Model::Song
29
26
  end
30
27
  end
31
28
 
29
+ let (:song) { Model::Song.new(1, "Broken", nil) }
32
30
 
33
- describe "::new" do # TODO: this creates a new model!
34
- let(:album) { Twin::Album.new }
35
- let (:song) { Twin::Song.new }
36
-
37
- it { album.name.must_equal nil }
38
- it { album.songs.must_equal nil }
39
- it { song.title.must_equal nil }
40
- it { song.album.must_equal nil }
41
- end
42
-
43
-
44
- describe "::new with arguments" do
45
- let (:talking) { Twin::Song.new("title" => "Talking") }
46
- let (:album) { Twin::Album.new(:name => "30 Years", :songs => [talking]) }
47
- subject { Twin::Song.new("title" => "Broken", "album" => album) }
48
-
49
- it { subject.title.must_equal "Broken" }
50
- it { subject.album.must_equal album }
51
- it { subject.album.name.must_equal "30 Years" }
52
- it { album.songs.must_equal [talking] }
53
- end
54
-
31
+ describe "#initialize" do
32
+ it do
33
+ twin = Twin::Song.new(song)
34
+ song.id = 2
35
+ # :as maps public name
36
+ twin.name.must_equal "Broken" # public: #name
37
+ twin.id.must_equal 2
38
+ end
55
39
 
56
- describe "::new with :symbols" do
57
- subject { Twin::Song.new(:title => "Broken") }
40
+ # override property with public name in constructor.
41
+ it do
42
+ # override twin's value...
43
+ Twin::Song.new(song, :name => "Kenny").name.must_equal "Kenny"
58
44
 
59
- it { subject.title.must_equal "Broken" }
60
- it { subject.album.must_equal nil }
45
+ # .. but do not write to the model!
46
+ song.title.must_equal "Broken"
47
+ end
61
48
  end
62
49
 
50
+ describe "setter" do
51
+ let (:twin) { Twin::Song.new(song) }
63
52
 
64
- # DISCUSS: make ::from private.
65
- describe "::from" do
66
- let (:song) { Model::Song.new(1, "Broken", album) }
67
- let (:album) { Model::Album.new(2, "The Process Of Belief", [Model::Song.new(3, "Dr. Stein")]) }
53
+ before do
54
+ twin.id = 3
55
+ twin.name = "Lucky"
56
+ end
68
57
 
69
- subject {Twin::Song.from(song) }
58
+ # updates twin
59
+ it { twin.id.must_equal 3 }
60
+ it { twin.name.must_equal "Lucky" }
70
61
 
71
- it { subject.title.must_equal "Broken" }
72
- it { subject.album.must_be_kind_of Twin::Album }
73
- it { subject.album.name.must_equal album.name }
74
- it { subject.album.songs.first.title.must_equal "Dr. Stein" } # TODO: more tests on collections and object identity (if we need that).
62
+ # DOES NOT update model
63
+ it { song.id.must_equal 1 }
64
+ it { song.title.must_equal "Broken" }
75
65
  end
76
66
  end
77
67
 
@@ -86,7 +76,7 @@ class OverridingAccessorsTest < TwinTest
86
76
  end
87
77
  end
88
78
 
89
- it { Song.from(Model::Song.new(1, "A Tale That Wasn't Right")).title.must_equal "a tale that wasn't right" }
79
+ it { Song.new(Model::Song.new(1, "A Tale That Wasn't Right")).title.must_equal "a tale that wasn't right" }
90
80
  end
91
81
 
92
82
 
@@ -96,11 +86,28 @@ class TwinDecoratorTest < MiniTest::Spec
96
86
  it { subject.twin_names.must_equal [:album] }
97
87
  end
98
88
 
99
- # from is as close to from_hash as possible
100
- # there should be #to in a perfect API, nothing else.
101
89
 
90
+ require 'disposable/twin/struct'
91
+ class TwinStructTest < MiniTest::Spec
92
+ class Song < Disposable::Twin
93
+ include Struct
94
+ property :number, :default => 1 # FIXME: this should be :default_if_nil so it becomes clear with a model.
95
+ option :cool?
96
+ end
97
+
98
+ # empty hash
99
+ it { Song.new({}).number.must_equal 1 }
100
+ # model hash
101
+ it { Song.new(number: 2).number.must_equal 2 }
102
+
103
+ # with hash and options as one hash.
104
+ it { Song.new(number: 3, cool?: true).cool?.must_equal true }
105
+ it { Song.new(number: 3, cool?: true).number.must_equal 3 }
102
106
 
103
- # should #new create empty associated models?
107
+ # with model hash and options hash separated.
108
+ it { Song.new({number: 3}, {cool?: true}).cool?.must_equal true }
109
+ it { Song.new({number: 3}, {cool?: true}).number.must_equal 3 }
110
+ end
104
111
 
105
112
 
106
113
  class TwinAsTest < MiniTest::Spec
@@ -114,52 +121,22 @@ class TwinAsTest < MiniTest::Spec
114
121
  class Album < Disposable::Twin
115
122
  property :record_name, :as => :name
116
123
 
117
- model Model::Album
124
+ # model Model::Album
118
125
  end
119
126
 
120
127
  class Song < Disposable::Twin
121
128
  property :name, :as => :title
122
129
  property :record, :twin => Album, :as => :album
123
130
 
124
- model Model::Song
131
+ # model Model::Song
125
132
  end
126
133
  end
127
134
 
128
-
129
- let (:record) { Twin::Album.new(:record_name => "Veni Vidi Vicous") }
130
- subject { Twin::Song.new(:name => "Outsmarted", :record => record) }
131
-
132
-
133
- describe "::new" do # TODO: this creates a new model!
134
- # the Twin exposes the as: API.
135
- it { subject.name.must_equal "Outsmarted" }
136
- it { subject.record.must_equal record }
137
- end
138
-
139
- # DISCUSS: should we test saving without AR? is that worth the hustle?
140
- # describe "#save" do
141
- # before { subject.send(:model).instance_eval do
142
- # def update_attributes(*)
143
-
144
- # end
145
- # end
146
- # subject.save
147
- # }
148
-
149
-
150
-
151
- # # before { subject.save }
152
-
153
- # it { subject.name }
154
- # end
155
135
  end
156
136
 
157
137
 
158
- require 'disposable/twin/option'
159
138
  class TwinOptionTest < TwinTest
160
139
  class Song < Disposable::Twin
161
- include Option
162
-
163
140
  property :id # DISCUSS: needed for #save.
164
141
  property :title
165
142
 
@@ -167,17 +144,21 @@ class TwinOptionTest < TwinTest
167
144
  option :highlight?
168
145
  end
169
146
 
147
+ let (:song) { Model::Song.new(1, "Broken") }
148
+ let (:twin) { Song.new(song, :preview? => false) }
170
149
 
171
- describe "::from" do
172
- let (:song) { Model::Song.new(1, "Broken") }
173
- let (:twin) { Song.from(song, :preview? => false) }
174
150
 
175
- it { twin.id.must_equal 1 }
176
- it { twin.title.must_equal "Broken" }
177
- it { twin.preview?.must_equal false }
151
+ # properties are read from model.
152
+ it { twin.id.must_equal 1 }
153
+ it { twin.title.must_equal "Broken" }
178
154
 
179
- it { Song.from(song, :preview? => true, :highlight => false).preview?.must_equal true }
180
- end
155
+ # option is not delegated to model.
156
+ it { twin.preview?.must_equal false }
157
+ # not passing option means zero.
158
+ it { twin.highlight?.must_equal nil }
159
+
160
+ # passing both options.
161
+ it { Song.new(song, preview?: true, highlight?: false).preview?.must_equal true }
181
162
  end
182
163
 
183
164
  # TODO: test coercion!
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: disposable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-01 00:00:00.000000000 Z
11
+ date: 2014-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uber
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.0.3
33
+ version: '2.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.0.3
40
+ version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -70,58 +70,16 @@ dependencies:
70
70
  name: minitest
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: activerecord
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
73
+ - - '='
88
74
  - !ruby/object:Gem::Version
89
- version: '0'
75
+ version: 5.4.1
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: sqlite3
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
80
+ - - '='
102
81
  - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: database_cleaner
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
82
+ version: 5.4.1
125
83
  description: Domain-Oriented Refactoring Framework.
126
84
  email:
127
85
  - apotonick@gmail.com
@@ -152,12 +110,17 @@ files:
152
110
  - lib/disposable.rb
153
111
  - lib/disposable/composition.rb
154
112
  - lib/disposable/twin.rb
113
+ - lib/disposable/twin/composition.rb
155
114
  - lib/disposable/twin/finders.rb
115
+ - lib/disposable/twin/new.rb
156
116
  - lib/disposable/twin/option.rb
117
+ - lib/disposable/twin/representer.rb
118
+ - lib/disposable/twin/save.rb
119
+ - lib/disposable/twin/save_.rb
120
+ - lib/disposable/twin/struct.rb
157
121
  - lib/disposable/version.rb
158
122
  - test/composition_test.rb
159
123
  - test/test_helper.rb
160
- - test/twin/active_record_test.rb
161
124
  - test/twin/composition_test.rb
162
125
  - test/twin/twin_test.rb
163
126
  homepage: ''
@@ -187,7 +150,6 @@ summary: Domain-Oriented Refactoring Framework.
187
150
  test_files:
188
151
  - test/composition_test.rb
189
152
  - test/test_helper.rb
190
- - test/twin/active_record_test.rb
191
153
  - test/twin/composition_test.rb
192
154
  - test/twin/twin_test.rb
193
155
  has_rdoc:
@@ -1,227 +0,0 @@
1
- require 'test_helper'
2
-
3
- class Album < ActiveRecord::Base
4
- has_many :songs
5
- end
6
-
7
- class Song < ActiveRecord::Base
8
- belongs_to :album
9
- end
10
-
11
- ActiveRecord::Base.establish_connection(
12
- :adapter => "sqlite3",
13
- :database => "#{Dir.pwd}/database.sqlite3"
14
- )
15
-
16
- # ActiveRecord::Schema.define do
17
- # create_table :songs do |table|
18
- # table.column :title, :string
19
- # table.column :album_id, :integer
20
- # table.timestamps
21
- # end
22
-
23
- # create_table :albums do |table|
24
- # table.column :name, :string
25
- # table.timestamps
26
- # end
27
- # end
28
-
29
-
30
- class TwinActiveRecordTest < MiniTest::Spec
31
- module Twin
32
- class Album < Disposable::Twin
33
- property :id
34
- property :name
35
- collection :songs, :twin => lambda { |*| Twin::Song }
36
-
37
- model ::Album
38
- end
39
-
40
- class Song < Disposable::Twin
41
- property :id
42
- property :title
43
- property :album, :twin => Album
44
-
45
- model ::Song
46
- end
47
- end
48
-
49
-
50
- # new models
51
- describe "::from, nested circular dependency" do
52
- let (:song) { ::Song.new(:title => "Broken", :album => album) }
53
- let (:album) { ::Album.new(:name => "The Process Of Belief") }
54
-
55
- before { album.songs = [song] } # circular dependency.
56
-
57
- let(:twin) { Twin::Song.from(song) }
58
-
59
- it { twin.album.songs.must_equal [twin] }
60
- end
61
-
62
- # existing, nested, models
63
- describe "::from existing models, nested circular dependency" do
64
- let (:song) { ::Song.create(:title => "Broken", :album => album) }
65
- let (:album) { ::Album.create(:name => "The Process Of Belief") }
66
-
67
- before { album.songs.must_equal [song] } # circular dependency.
68
-
69
- let(:twin) { Twin::Song.from(song) }
70
-
71
- it { twin.album.songs.must_equal [twin] }
72
-
73
- it do
74
- twin.save
75
- twin.album.songs.must_equal [twin]
76
- end
77
- end
78
-
79
-
80
- describe "::find" do
81
- let (:song_model) { ::Song.create(:title => "Savage") }
82
- subject { Twin::Song.find(song_model.id) }
83
-
84
- it { subject.id.must_equal song_model.id }
85
- it { subject.title.must_equal "Savage" }
86
- it { subject.album.must_equal nil }
87
- end
88
-
89
-
90
- describe "::finders" do
91
- before {
92
- DatabaseCleaner.clean
93
- savage
94
- starlight
95
- }
96
- let (:savage) { ::Song.create(:title => "Savage") }
97
- let (:starlight) { ::Song.create(:title => "Starlight") }
98
-
99
- describe "collections" do
100
- subject { Twin::Song.finders.all }
101
-
102
- it { subject.size.must_equal 2 }
103
-
104
- it { subject[0].must_be_kind_of Twin::Song }
105
- it { subject[0].id.must_equal savage.id }
106
- it { subject[0].title.must_equal "Savage" }
107
-
108
- it { subject[1].must_be_kind_of Twin::Song }
109
- it { subject[1].id.must_equal starlight.id }
110
- it { subject[1].title.must_equal "Starlight" }
111
- end
112
-
113
- describe "::where" do
114
- subject { Twin::Song.finders.where(:title => "Starlight") }
115
-
116
- it { subject.size.must_equal 1 }
117
-
118
- it { subject[0].must_be_kind_of Twin::Song }
119
- it { subject[0].id.must_equal starlight.id }
120
- it { subject[0].title.must_equal "Starlight" }
121
- end
122
- end
123
-
124
-
125
- describe "::save, nested not set" do
126
- let (:twin) { Twin::Song.new(:title => "1.80 Down") }
127
- before { twin.save }
128
- subject { ::Song.find(twin.id) }
129
-
130
- it { subject.attributes.slice("id", "title").
131
- must_equal({"id" => subject.id, "title" => "1.80 Down"}) }
132
-
133
- it { subject.album.must_equal nil }
134
- end
135
-
136
-
137
- describe "::save, nested present" do
138
- let (:song) { ::Song.new(:title => "Broken", :album => album) }
139
- let (:album) { ::Album.new(:name => "The Process Of Belief") }
140
-
141
- let(:twin) { Twin::Song.from(song) }
142
-
143
- before { twin.save } # propagate album.save
144
-
145
- subject { ::Song.find(twin.id) }
146
-
147
- it { subject.attributes.slice("id", "title").
148
- must_equal({"id" => subject.id, "title" => "Broken"}) }
149
-
150
- it { subject.album.must_equal album }
151
- it { subject.album.id.wont_equal nil } # FIXME: this only works because song is saved after album.
152
- end
153
-
154
-
155
- describe "::save, nested new" do
156
- let(:twin) { Twin::Song.new(:title => "How It Goes", :album => Twin::Album.new(:name => "Billy Talent")) }
157
-
158
- before { twin.save } # propagate album.save
159
-
160
- subject { ::Song.find(twin.id) }
161
-
162
- it {
163
- subject.attributes.slice("id", "title").
164
- must_equal({"id" => subject.id, "title" => "How It Goes"}) }
165
-
166
- it { subject.album.attributes.slice("name").must_equal("name" => "Billy Talent") }
167
- end
168
- end
169
-
170
-
171
- class TwinActiveRecordAsTest < MiniTest::Spec
172
- module Twin
173
- class Album < Disposable::Twin
174
- property :id
175
- property :album_name, :as => :name
176
-
177
- model ::Album
178
- end
179
-
180
- class Song < Disposable::Twin
181
- property :id
182
- property :song_title, :as => :title
183
- property :record, :twin => Album, :as => :album
184
-
185
- model ::Song
186
- end
187
- end
188
-
189
-
190
- describe "::from" do
191
- # (existing models)
192
- let (:song) { ::Song.new(:title => "Broken", :album => album) }
193
- let (:album) { ::Album.new(:name => "The Process Of Belief") }
194
-
195
- let(:twin) { Twin::Song.from(song) }
196
-
197
- it { twin.song_title.must_equal "Broken" }
198
- it { twin.record.album_name.must_equal "The Process Of Belief" }
199
- end
200
-
201
-
202
- describe "#save" do
203
- # existing models
204
- let (:song) { ::Song.new(:title => "Broken", :album => album) }
205
- let (:album) { ::Album.new(:name => "The Process Of Belief") }
206
-
207
- let(:twin) { Twin::Song.from(song) }
208
-
209
- before do
210
- twin.song_title = "Emo Boy"
211
- twin.record.album_name = "Rode Hard And Put Away Wet"
212
-
213
- twin.save
214
- end
215
-
216
- let (:ar_song) { ::Song.find(twin.id) }
217
- let (:ar_album) { ar_song.album }
218
-
219
- it { ar_song.attributes.slice("id", "title").
220
- must_equal({"id" => ar_song.id, "title" => "Emo Boy"}) }
221
-
222
- it { ar_album.must_equal album }
223
- it("xxx") { ar_album.name.must_equal "Rode Hard And Put Away Wet" }
224
- it { ar_album.id.wont_equal nil } # FIXME: this only works because song is saved after album.
225
- end
226
-
227
- end