disposable 0.0.3 → 0.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3028d579eaa9e41a6d3591c069809c98940bd7a1
4
- data.tar.gz: 12371d78cdf1c2bfe046021f45ffb0a1dbd4ccff
3
+ metadata.gz: 9f223895880d3cf7e132a9fc7fe289d2364cda94
4
+ data.tar.gz: f6fb9b0b50ab1f76f6a76c233bc6a7b764d715c0
5
5
  SHA512:
6
- metadata.gz: 2af96f209c219622ac48b55d86798cd392fd83cb73e14463319d965c20a01824e4354ff5f09e9b71bddc21caeb64e369cb265478c77572226c1245297a7f25bc
7
- data.tar.gz: e58b5545c50a104ca16ae784cb48a2280dc60a407f35345dcccf78e867756380993826be1e6d4ce5f442475f0fd1311fddc4f2079f467cf5d1b774ce05b44c07
6
+ metadata.gz: b419406d81071ac149d0bb88a4b4165763b752be5530125ddb4a2165b05ffb704087cc5502d37bde78ef75b132bf49b101d9b7ec475ef3754904619f5039cae9
7
+ data.tar.gz: 8f18dd625473e5880a7a600698bb36eef37cf1791df67ed59e91c9f0179e168d16a32e201002afa8d3bbb85f75d426b88fb5c28f7958d19404d8a8b1878112a9
data/CHANGES.md ADDED
@@ -0,0 +1,3 @@
1
+ # 0.0.4
2
+
3
+ * Added `Composition#[]` to access contained models in favor of reader methods to models. The latter got removed. This allows mapping methods with the same name than the contained object.
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  why?
5
5
  because i want this to fuckin work: Wallpaper.find(51).update_attributes(enabled:false)
6
-
6
+ i want to see my fields when opening the class file, a la DataMapper.
7
7
 
8
8
  ## Twin
9
9
 
data/database.sqlite3 CHANGED
Binary file
@@ -2,6 +2,7 @@ require 'forwardable'
2
2
 
3
3
  module Disposable
4
4
  # Composition delegates accessors to models as per configuration.
5
+ #
5
6
  # Composition doesn't know anything but methods (readers and writers) to expose and the mappings to
6
7
  # the internal models. Optionally, it knows about renamings such as mapping `#song_id` to `song.id`.
7
8
  #
@@ -14,6 +15,8 @@ module Disposable
14
15
  # album = Album.new(cd: CD.find(1), band: Band.new)
15
16
  # album.id #=> 1
16
17
  # album.title = "Ten Foot Pole"
18
+ #
19
+ # It allows accessing the contained models using the `#[]` reader.
17
20
  module Composition
18
21
  def self.included(base)
19
22
  base.extend(Forwardable)
@@ -26,8 +29,6 @@ module Disposable
26
29
  @map = {}
27
30
 
28
31
  options.each do |mdl, meths|
29
- attr_reader mdl
30
-
31
32
  meths.each do |mtd| # [[:title], [:id, :song_id]]
32
33
  create_accessors(mdl, mtd)
33
34
  add_to_map(mdl, mtd)
@@ -37,8 +38,8 @@ module Disposable
37
38
 
38
39
  private
39
40
  def create_accessors(model, methods)
40
- def_instance_delegator model, *methods # reader
41
- def_instance_delegator model, *methods.map { |m| "#{m}=" } # writer
41
+ def_instance_delegator "@#{model}", *methods # reader
42
+ def_instance_delegator "@#{model}", *methods.map { |m| "#{m}=" } # writer
42
43
  end
43
44
 
44
45
  def add_to_map(model, methods)
@@ -58,12 +59,17 @@ module Disposable
58
59
  @_models = models.values
59
60
  end
60
61
 
62
+ # Allows accessing the contained models.
63
+ def [](name)
64
+ instance_variable_get(:"@#{name}")
65
+ end
66
+
61
67
  # Allows multiplexing method calls to all composed models.
62
68
  def each(&block)
63
69
  _models.each(&block)
64
70
  end
65
71
 
66
72
  private
67
- attr_reader:_models
73
+ attr_reader :_models
68
74
  end
69
75
  end
@@ -32,14 +32,18 @@ module Disposable
32
32
  end
33
33
 
34
34
  def self.property(name, options={}, &block)
35
- options[:public_name] = options.delete(:as) || name
35
+ options[:private_name] = options.delete(:as) || name
36
36
  options[:pass_options] = true
37
37
 
38
38
  representer_class.property(name, options, &block).tap do |definition|
39
- attr_accessor definition[:public_name]
39
+ attr_accessor name
40
40
  end
41
41
  end
42
42
 
43
+ def self.collection(name, options={}, &block)
44
+ property(name, options.merge(:collection => true), &block)
45
+ end
46
+
43
47
  def self.from(model) # TODO: private.
44
48
  new(model)
45
49
  end
@@ -64,7 +68,7 @@ module Disposable
64
68
  :serialize => lambda { |obj, args| obj.send(:model) }) }
65
69
 
66
70
  save.representable_attrs.each do |attr|
67
- attr.merge!(:as => attr.name)
71
+ attr.merge!(:as => attr[:private_name])
68
72
  end
69
73
 
70
74
  save
@@ -78,11 +82,13 @@ module Disposable
78
82
  representer.representable_attrs.
79
83
  find_all { |attr| attr[:twin] }.
80
84
  each { |attr| attr.merge!(
81
- :prepare => lambda { |object, args| args.binding[:twin].new(object) }) }
85
+ :prepare => lambda { |object, args| args.binding[:twin].call.new(object) }) }
82
86
 
83
87
  # song_title => model.title
84
88
  representer.representable_attrs.each do |attr|
85
- attr.merge!(:as => attr[:public_name])
89
+ attr.merge!(
90
+ :getter => lambda { |args| send("#{args.binding[:private_name]}") },
91
+ )
86
92
  end
87
93
 
88
94
  representer
@@ -91,16 +97,6 @@ module Disposable
91
97
  # read/write to twin using twin's API (e.g. #record= not #album=).
92
98
  def self.write_representer
93
99
  representer = Class.new(representer_class) # inherit configuration
94
- representer.representable_attrs.
95
- each { |attr| attr.merge!(
96
- # use the alias name (as:) when writing attributes in new.
97
- # DISCUSS: attr.name = public_name would be simpler.
98
- :as => attr[:public_name],
99
- :getter => lambda { |args| send("#{args.binding[:public_name]}") },
100
- :setter => lambda { |value, args| send("#{args.binding[:public_name]}=", value) }
101
- )}
102
-
103
- representer
104
100
  end
105
101
 
106
102
  # call save on all nested twins.
@@ -1,3 +1,3 @@
1
1
  module Disposable
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -3,27 +3,28 @@ require 'test_helper'
3
3
  class CompositionTest < MiniTest::Spec
4
4
  module Model
5
5
  Band = Struct.new(:id, :title,)
6
- Album = Struct.new(:id, :name)
6
+ Album = Struct.new(:id, :name, :album)
7
7
  end
8
8
 
9
9
  module Twin
10
10
  class Album #< Disposable::Twin
11
11
  include Disposable::Composition
12
12
 
13
- map( {:album => [[:id], [:name]],
13
+ map( {:album => [[:id], [:name], [:album]],
14
14
  :band => [[:id, :band_id], [:title]]
15
15
  } )
16
16
  end
17
17
  end
18
18
 
19
19
  let (:band) { Model::Band.new(1, "Frenzal Rhomb") }
20
- let (:album) { Model::Album.new(2, "Dick Sandwhich") }
20
+ let (:album) { Model::Album.new(2, "Dick Sandwich", "For the Term of Their Unnatural Lives") }
21
21
  subject { Twin::Album.new(:album => album, :band => band) }
22
22
 
23
23
  describe "readers" do
24
24
  it { subject.id.must_equal 2 }
25
25
  it { subject.band_id.must_equal 1 }
26
- it { subject.name.must_equal "Dick Sandwhich" }
26
+ it { subject.name.must_equal "Dick Sandwich" }
27
+ it { subject.album.must_equal "For the Term of Their Unnatural Lives" }
27
28
  it { subject.title.must_equal "Frenzal Rhomb" }
28
29
  end
29
30
 
@@ -34,6 +35,7 @@ class CompositionTest < MiniTest::Spec
34
35
  subject.band_id = 4
35
36
  subject.name = "Eclipse"
36
37
  subject.title = "Yngwie J. Malmsteen"
38
+ subject.album = "Best Of"
37
39
  end
38
40
 
39
41
  it { subject.id.must_equal 3 }
@@ -44,6 +46,8 @@ class CompositionTest < MiniTest::Spec
44
46
  it { subject.title.must_equal "Yngwie J. Malmsteen" }
45
47
  it { album.name.must_equal "Eclipse" }
46
48
  it { band.title.must_equal "Yngwie J. Malmsteen" }
49
+ it { subject.album.must_equal "Best Of" }
50
+ it { album.album.must_equal "Best Of" }
47
51
  end
48
52
  # it { subject.save }
49
53
 
@@ -54,9 +58,11 @@ class CompositionTest < MiniTest::Spec
54
58
  end
55
59
 
56
60
 
57
- describe "readers to models" do
58
- it { subject.album.object_id.must_equal album.object_id }
59
- it { subject.band.object_id.must_equal band.object_id }
61
+ describe "#[]" do
62
+ it { subject[:album].object_id.must_equal album.object_id }
63
+ it { subject[:band].object_id.must_equal band.object_id }
64
+
65
+ it { assert_raises( NoMethodError) { subject.song } } # no reader to contained model.
60
66
  end
61
67
 
62
68
 
@@ -109,15 +109,15 @@ class TwinActiveRecordAsTest < MiniTest::Spec
109
109
  module Twin
110
110
  class Album < Disposable::Twin
111
111
  property :id
112
- property :name, :as => :album_name
112
+ property :album_name, :as => :name
113
113
 
114
114
  model ::Album
115
115
  end
116
116
 
117
117
  class Song < Disposable::Twin
118
118
  property :id
119
- property :title, :as => :song_title
120
- property :album, :twin => Album, :as => :record
119
+ property :song_title, :as => :title
120
+ property :record, :twin => Album, :as => :album
121
121
 
122
122
  model ::Song
123
123
  end
@@ -4,14 +4,18 @@ require 'test_helper'
4
4
  class TwinTest < MiniTest::Spec
5
5
  module Model
6
6
  Song = Struct.new(:id, :title, :album)
7
- Album = Struct.new(:id, :name)
7
+ Album = Struct.new(:id, :name, :songs)
8
8
  end
9
9
 
10
10
 
11
11
  module Twin
12
+ class Song < Disposable::Twin
13
+ end
14
+
12
15
  class Album < Disposable::Twin
13
16
  property :id # DISCUSS: needed for #save.
14
17
  property :name
18
+ collection :songs, :twin => Song
15
19
 
16
20
  model Model::Album
17
21
  end
@@ -27,20 +31,25 @@ class TwinTest < MiniTest::Spec
27
31
 
28
32
 
29
33
  describe "::new" do # TODO: this creates a new model!
30
- subject { Twin::Song.new }
34
+ let(:album) { Twin::Album.new }
35
+ let (:song) { Twin::Song.new }
31
36
 
32
- it { subject.title.must_equal nil }
33
- it { subject.album.must_equal nil }
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 }
34
41
  end
35
42
 
36
43
 
37
44
  describe "::new with arguments" do
38
- let (:album) { Twin::Album.new(:name => "30 Years") }
45
+ let (:talking) { Twin::Song.new("title" => "Talking") }
46
+ let (:album) { Twin::Album.new(:name => "30 Years", :songs => [talking]) }
39
47
  subject { Twin::Song.new("title" => "Broken", "album" => album) }
40
48
 
41
49
  it { subject.title.must_equal "Broken" }
42
50
  it { subject.album.must_equal album }
43
51
  it { subject.album.name.must_equal "30 Years" }
52
+ it { album.songs.must_equal [talking] }
44
53
  end
45
54
 
46
55
 
@@ -55,13 +64,14 @@ class TwinTest < MiniTest::Spec
55
64
  # DISCUSS: make ::from private.
56
65
  describe "::from" do
57
66
  let (:song) { Model::Song.new(1, "Broken", album) }
58
- let (:album) { Model::Album.new(2, "The Process Of Belief") }
67
+ let (:album) { Model::Album.new(2, "The Process Of Belief", [Model::Song.new(3, "Dr. Stein")]) }
59
68
 
60
69
  subject {Twin::Song.from(song) }
61
70
 
62
71
  it { subject.title.must_equal "Broken" }
63
72
  it { subject.album.must_be_kind_of Twin::Album }
64
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).
65
75
  end
66
76
  end
67
77
 
@@ -88,14 +98,14 @@ class TwinAsTest < MiniTest::Spec
88
98
 
89
99
  module Twin
90
100
  class Album < Disposable::Twin
91
- property :name, :as => :record_name
101
+ property :record_name, :as => :name
92
102
 
93
103
  model Model::Album
94
104
  end
95
105
 
96
106
  class Song < Disposable::Twin
97
- property :title, :as => :name
98
- property :album, :twin => Album, :as => :record
107
+ property :name, :as => :title
108
+ property :record, :twin => Album, :as => :album
99
109
 
100
110
  model Model::Song
101
111
  end
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.3
4
+ version: 0.0.4
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-04-30 00:00:00.000000000 Z
11
+ date: 2014-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uber
@@ -117,6 +117,7 @@ extra_rdoc_files: []
117
117
  files:
118
118
  - ".gitignore"
119
119
  - ".travis.yml"
120
+ - CHANGES.md
120
121
  - Gemfile
121
122
  - LICENSE.txt
122
123
  - README.md