disposable 0.1.3 → 0.1.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: 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