disposable 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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