disposable 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c253349d4d314ee180fd275bf708c5d1dc3fcc2
4
- data.tar.gz: 76b13c0d6262f330cc183c2498ab60f8cb0bf127
3
+ metadata.gz: c3ede9bea8a77d3c3ca49a1d8d30e4d85174064b
4
+ data.tar.gz: bc8db041e0b26ce6520db6c0d647ad04f3fdffb4
5
5
  SHA512:
6
- metadata.gz: 5d5f2a357dac409f5d1c89dd20a2dc66d6de8526bc27f62a9b7b290291d8ff2d7073cc3c06b74722ceba3be6ed9289de47ed1ac08b63ea81b50ef620999b7927
7
- data.tar.gz: 8d21e16cf85e61cec5cc2591386b1879642588b5afe48d41f490f7880b1467f3259004155407a5d582d00c3c79ff86990b0abd270489e9918db200b936665c5a
6
+ metadata.gz: 241f8a98b1db05b79d6df1a725081648317c9eb913fca3bef48d487c8b8214d3089913285a1b6a0c581a8c7f778528924cf60ca8cc675143a3130603c959b13e
7
+ data.tar.gz: bb406f4d2550786497c0d3dc80b77ec69b97643f68adcba6ad2a9c78ef54121206a882edcf8363357ee5f325b0f8b60d70310efce9f829433d12de85a8f1c2b5
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.1.4
2
+
3
+ * Add `Twin::Coercion`.
4
+
1
5
  # 0.1.3
2
6
 
3
7
  * Fix `Composition#save`, it now returns true only if all models could be saved.
data/README.md CHANGED
@@ -173,6 +173,39 @@ You can also specify nested objects with an explicit class.
173
173
  property :artist, twin: TwinArtist
174
174
  ```
175
175
 
176
+ ## Features
177
+
178
+ You can simply `include` feature modules into twins. If you want a feature to be included into all inline twins of your schema, use `::feature`.
179
+
180
+ ```ruby
181
+ class AlbumTwin < Disposable::Twin
182
+ feature Coercion
183
+
184
+ property :artist do
185
+ # this will now include Coercion, too.
186
+ ```
187
+
188
+ ## Coercion
189
+
190
+ Twins can use [Virtus](https://github.com/solnic/virtus) coercion. This will override the setter in your twin, coerce the incoming value, and call the original setter. _Nothing more_ will happen.
191
+
192
+ ```ruby
193
+ class AlbumTwin < Disposable::Twin
194
+ feature Coercion
195
+ feature Setup::SkipSetter
196
+
197
+ property :id, type: Integer
198
+ ```
199
+
200
+ The `:type` option defines the coercion type. You may incluce `Setup::SkipSetter`, too, as otherwise the coercion will happen at initialization time and in the setter.
201
+
202
+ ```ruby
203
+ twin.id = "1"
204
+ twin.id #=> 1
205
+ ```
206
+
207
+ Again, coercion only happens in the setter.
208
+
176
209
  ## Collections
177
210
 
178
211
  Collections can be defined analogue to `property`. The exposed API is the `Array` API.
Binary file
@@ -26,5 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "minitest"
27
27
  spec.add_development_dependency "activerecord"
28
28
  spec.add_development_dependency "sqlite3"
29
+ spec.add_development_dependency "virtus"
29
30
  # spec.add_development_dependency "database_cleaner"
30
31
  end
@@ -0,0 +1,23 @@
1
+ require "virtus"
2
+
3
+ # confession: i love virtus' coercion.
4
+ module Disposable::Twin::Coercion
5
+ module ClassMethods
6
+ def property(name, options={}, &block)
7
+ super(name, options, &block).tap do
8
+ coercing_setter!(name, options[:type]) # define coercing setter after twin.
9
+ end
10
+ end
11
+
12
+ def coercing_setter!(name, type)
13
+ mod = Module.new do
14
+ define_method("#{name}=") { |value| super Virtus::Attribute.build(type).coerce(value) }
15
+ end
16
+ include mod
17
+ end
18
+ end
19
+
20
+ def self.included(includer)
21
+ includer.extend ClassMethods
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Disposable
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -0,0 +1,86 @@
1
+ require "test_helper"
2
+
3
+ require "disposable/twin/coercion"
4
+
5
+ class CoercionTest < MiniTest::Spec
6
+ Band = Struct.new(:label)
7
+
8
+ class Irreversible < Virtus::Attribute
9
+ def coerce(value)
10
+ value*2
11
+ end
12
+ end
13
+
14
+ class Twin < Disposable::Twin
15
+ feature Coercion
16
+ feature Setup::SkipSetter
17
+
18
+ property :id
19
+ property :released_at, :type => DateTime
20
+
21
+ property :hit do
22
+ property :length, :type => Integer
23
+ property :good, :type => Virtus::Attribute::Boolean
24
+ end
25
+
26
+ property :band do
27
+ property :label do
28
+ property :value, :type => Irreversible
29
+ end
30
+ end
31
+ end
32
+
33
+ subject do
34
+ Twin.new(album)
35
+ end
36
+
37
+ let (:album) {
38
+ OpenStruct.new(
39
+ id: 1,
40
+ :released_at => "31/03/1981",
41
+ :hit => OpenStruct.new(:length => "312"),
42
+ :band => Band.new(OpenStruct.new(:value => "9999.99"))
43
+ )
44
+ }
45
+
46
+ # it { subject.released_at.must_be_kind_of DateTime }
47
+ it { subject.released_at.must_equal "31/03/1981" } # NO coercion in setup.
48
+ it { subject.hit.length.must_equal "312" }
49
+ it { subject.band.label.value.must_equal "9999.99" }
50
+
51
+
52
+ it do
53
+ subject.id = Object
54
+ subject.released_at = "30/03/1981"
55
+ subject.hit.length = "312"
56
+ subject.band.label.value = "9999.99"
57
+
58
+ subject.id = Object
59
+ subject.released_at.must_be_kind_of DateTime
60
+ subject.released_at.must_equal DateTime.parse("30/03/1981")
61
+ subject.hit.length.must_equal 312
62
+ subject.hit.good.must_equal nil
63
+ subject.band.label.value.must_equal "9999.999999.99" # coercion happened once.
64
+ end
65
+ end
66
+
67
+
68
+ class CoercionWithoutSkipSetterTest < MiniTest::Spec
69
+ class Irreversible < Virtus::Attribute
70
+ def coerce(value)
71
+ value*2
72
+ end
73
+ end
74
+
75
+ class Twin < Disposable::Twin
76
+ feature Coercion
77
+ property :id, type: Irreversible
78
+ end
79
+
80
+ it do
81
+ twin = Twin.new(OpenStruct.new(id: "1"))
82
+ twin.id.must_equal "11" # coercion happens in Setup.
83
+ twin.id = "2"
84
+ twin.id.must_equal "22"
85
+ end
86
+ 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.1.3
4
+ version: 0.1.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: 2015-06-28 00:00:00.000000000 Z
11
+ date: 2015-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uber
@@ -114,6 +114,20 @@ dependencies:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: virtus
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
117
131
  description: Decorators on top of your ORM layer.
118
132
  email:
119
133
  - apotonick@gmail.com
@@ -147,6 +161,7 @@ files:
147
161
  - lib/disposable/twin.rb
148
162
  - lib/disposable/twin/builder.rb
149
163
  - lib/disposable/twin/changed.rb
164
+ - lib/disposable/twin/coercion.rb
150
165
  - lib/disposable/twin/collection.rb
151
166
  - lib/disposable/twin/composition.rb
152
167
  - lib/disposable/twin/option.rb
@@ -170,6 +185,7 @@ files:
170
185
  - test/twin/benchmarking.rb
171
186
  - test/twin/builder_test.rb
172
187
  - test/twin/changed_test.rb
188
+ - test/twin/coercion_test.rb
173
189
  - test/twin/collection_test.rb
174
190
  - test/twin/composition_test.rb
175
191
  - test/twin/expose_test.rb
@@ -224,6 +240,7 @@ test_files:
224
240
  - test/twin/benchmarking.rb
225
241
  - test/twin/builder_test.rb
226
242
  - test/twin/changed_test.rb
243
+ - test/twin/coercion_test.rb
227
244
  - test/twin/collection_test.rb
228
245
  - test/twin/composition_test.rb
229
246
  - test/twin/expose_test.rb