disposable 0.0.9 → 0.1.0
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 +4 -4
- data/.travis.yml +2 -5
- data/CHANGES.md +4 -0
- data/Gemfile +1 -1
- data/README.md +154 -1
- data/database.sqlite3 +0 -0
- data/disposable.gemspec +7 -7
- data/gemfiles/Gemfile.rails-3.0.lock +10 -8
- data/gemfiles/Gemfile.rails-3.2.lock +9 -7
- data/gemfiles/Gemfile.rails-4.0.lock +9 -7
- data/gemfiles/Gemfile.rails-4.1.lock +10 -8
- data/lib/disposable.rb +6 -7
- data/lib/disposable/callback.rb +174 -0
- data/lib/disposable/composition.rb +21 -58
- data/lib/disposable/expose.rb +49 -0
- data/lib/disposable/twin.rb +85 -38
- data/lib/disposable/twin/builder.rb +12 -30
- data/lib/disposable/twin/changed.rb +50 -0
- data/lib/disposable/twin/collection.rb +95 -0
- data/lib/disposable/twin/composition.rb +43 -15
- data/lib/disposable/twin/option.rb +1 -1
- data/lib/disposable/twin/persisted.rb +20 -0
- data/lib/disposable/twin/property_processor.rb +29 -0
- data/lib/disposable/twin/representer.rb +42 -14
- data/lib/disposable/twin/save.rb +19 -34
- data/lib/disposable/twin/schema.rb +31 -0
- data/lib/disposable/twin/setup.rb +38 -0
- data/lib/disposable/twin/sync.rb +114 -0
- data/lib/disposable/version.rb +1 -1
- data/test/api_semantics_test.rb +263 -0
- data/test/callback_group_test.rb +222 -0
- data/test/callbacks_test.rb +450 -0
- data/test/example.rb +40 -0
- data/test/expose_test.rb +92 -0
- data/test/persisted_test.rb +101 -0
- data/test/test_helper.rb +64 -0
- data/test/twin/benchmarking.rb +33 -0
- data/test/twin/builder_test.rb +32 -0
- data/test/twin/changed_test.rb +108 -0
- data/test/twin/collection_test.rb +223 -0
- data/test/twin/composition_test.rb +56 -25
- data/test/twin/expose_test.rb +73 -0
- data/test/twin/feature_test.rb +61 -0
- data/test/twin/from_test.rb +37 -0
- data/test/twin/inherit_test.rb +57 -0
- data/test/twin/option_test.rb +27 -0
- data/test/twin/readable_test.rb +57 -0
- data/test/twin/save_test.rb +192 -0
- data/test/twin/schema_test.rb +69 -0
- data/test/twin/setup_test.rb +139 -0
- data/test/twin/skip_unchanged_test.rb +64 -0
- data/test/twin/struct_test.rb +168 -0
- data/test/twin/sync_option_test.rb +228 -0
- data/test/twin/sync_test.rb +128 -0
- data/test/twin/twin_test.rb +49 -128
- data/test/twin/writeable_test.rb +56 -0
- metadata +106 -20
- data/STUFF +0 -4
- data/lib/disposable/twin/finders.rb +0 -29
- data/lib/disposable/twin/new.rb +0 -30
- data/lib/disposable/twin/save_.rb +0 -21
- data/test/composition_test.rb +0 -102
data/STUFF
DELETED
@@ -1,4 +0,0 @@
|
|
1
|
-
USE CASE:
|
2
|
-
|
3
|
-
<% client.invoices.outstanding.each do |invoice| %>
|
4
|
-
<%= link_to invoice.invoice_number, {:controller => "party", :action => "invoice_show", :id => invoice.id, :entity_instance_id => client.party, :entity_type_id => EntityType::PARTY}, :onclick => "event.cancelBubble=true;" %> <%= number_to_currency(invoice.balance_out)
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Disposable::Twin::Finders
|
2
|
-
def find(*args)
|
3
|
-
finders.find(*args)
|
4
|
-
end
|
5
|
-
|
6
|
-
# Use Song::Twin.finders.where(..) or whatever finder/scope is defined in the model.
|
7
|
-
# It will return each model wrapped in a Twin.
|
8
|
-
def finders
|
9
|
-
FinderBuilder.new(self, _model)
|
10
|
-
end
|
11
|
-
|
12
|
-
class FinderBuilder
|
13
|
-
def initialize(*args)
|
14
|
-
@twin_class, @model_class = *args
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
def method_missing(*args, &block)
|
19
|
-
models = execute(*args, &block)
|
20
|
-
|
21
|
-
return @twin_class.new(models) unless models.respond_to?(:each) # sorry for all the magic, but that's how ActiveRecord works.
|
22
|
-
models.collect { |mdl| @twin_class.new(mdl) }
|
23
|
-
end
|
24
|
-
|
25
|
-
def execute(*args, &block)
|
26
|
-
@model_class.send(*args, &block)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
data/lib/disposable/twin/new.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module Disposable
|
2
|
-
class Twin
|
3
|
-
# transform incoming model into twin API hash.
|
4
|
-
def self.new_representer
|
5
|
-
representer = Class.new(representer_class) # inherit configuration
|
6
|
-
|
7
|
-
# wrap incoming nested model in its Twin.
|
8
|
-
representer.representable_attrs.
|
9
|
-
find_all { |attr| attr[:twin] }.
|
10
|
-
each { |attr| attr.merge!(
|
11
|
-
:prepare => lambda { |object, args|
|
12
|
-
if twin = args.user_options[:object_map][object]
|
13
|
-
twin
|
14
|
-
else
|
15
|
-
args.binding[:twin].evaluate(nil).new(object, args.user_options[:object_map])
|
16
|
-
end
|
17
|
-
}) }
|
18
|
-
|
19
|
-
# song_title => model.title
|
20
|
-
representer.representable_attrs.each do |attr|
|
21
|
-
attr.merge!(
|
22
|
-
:getter => lambda { |args|
|
23
|
-
args.represented.send("#{args.binding[:private_name]}") }, # DISCUSS: can't we do that with representable's mechanics?
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
|
-
representer
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Disposable
|
2
|
-
class Twin
|
3
|
-
# hash for #update_attributes (model API): {title: "Future World", album: <Album>}
|
4
|
-
def self.save_representer
|
5
|
-
# TODO: do that only at compile-time!
|
6
|
-
save = Class.new(write_representer) # inherit configuration
|
7
|
-
save.representable_attrs.
|
8
|
-
find_all { |attr| attr[:twin] }.
|
9
|
-
each { |attr| attr.merge!(
|
10
|
-
:representable => true,
|
11
|
-
:serialize => lambda { |obj, args| obj.send(:model) }) }
|
12
|
-
|
13
|
-
save.representable_attrs.each do |attr|
|
14
|
-
attr.merge!(:as => attr[:private_name])
|
15
|
-
end
|
16
|
-
|
17
|
-
save
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
data/test/composition_test.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class CompositionTest < MiniTest::Spec
|
4
|
-
module Model
|
5
|
-
Band = Struct.new(:id, :title)
|
6
|
-
Album = Struct.new(:id, :name, :album)
|
7
|
-
end
|
8
|
-
|
9
|
-
module Twin
|
10
|
-
class Album #< Disposable::Twin
|
11
|
-
include Disposable::Composition
|
12
|
-
|
13
|
-
map( {:album => [[:id], [:name], [:album]],
|
14
|
-
:band => [[:id, :band_id], [:title]]
|
15
|
-
} )
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
let (:band) { Model::Band.new(1, "Frenzal Rhomb") }
|
20
|
-
let (:album) { Model::Album.new(2, "Dick Sandwich", "For the Term of Their Unnatural Lives") }
|
21
|
-
subject { Twin::Album.new(:album => album, :band => band) }
|
22
|
-
|
23
|
-
describe "readers" do
|
24
|
-
it { subject.id.must_equal 2 }
|
25
|
-
it { subject.band_id.must_equal 1 }
|
26
|
-
it { subject.name.must_equal "Dick Sandwich" }
|
27
|
-
it { subject.album.must_equal "For the Term of Their Unnatural Lives" }
|
28
|
-
it { subject.title.must_equal "Frenzal Rhomb" }
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
describe "writers" do
|
33
|
-
before do
|
34
|
-
subject.id = 3
|
35
|
-
subject.band_id = 4
|
36
|
-
subject.name = "Eclipse"
|
37
|
-
subject.title = "Yngwie J. Malmsteen"
|
38
|
-
subject.album = "Best Of"
|
39
|
-
end
|
40
|
-
|
41
|
-
it { subject.id.must_equal 3 }
|
42
|
-
it { album.id.must_equal 3 }
|
43
|
-
it { subject.band_id.must_equal 4 }
|
44
|
-
it { band.id.must_equal 4 }
|
45
|
-
it { subject.name.must_equal "Eclipse" }
|
46
|
-
it { subject.title.must_equal "Yngwie J. Malmsteen" }
|
47
|
-
it { album.name.must_equal "Eclipse" }
|
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" }
|
51
|
-
end
|
52
|
-
# it { subject.save }
|
53
|
-
|
54
|
-
it "raises when non-mapped property" do
|
55
|
-
assert_raises NoMethodError do
|
56
|
-
subject.raise_an_exception
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
|
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.
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
describe "#each" do
|
70
|
-
it "what" do
|
71
|
-
results = []
|
72
|
-
subject.each { |mdl| results << mdl.object_id }
|
73
|
-
results.must_equal([album.object_id, band.object_id])
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
describe "#_models" do
|
79
|
-
it { subject.send(:_models).must_equal([album, band]) }
|
80
|
-
it { Twin::Album.new(:album => album).send(:_models).must_equal([album]) }
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
describe "@map" do
|
85
|
-
let (:composition) {
|
86
|
-
Class.new do
|
87
|
-
include Disposable::Composition
|
88
|
-
|
89
|
-
map( {:album => [["id"], [:name]],
|
90
|
-
"band" => [[:id, "band_id"], [:title]]
|
91
|
-
} )
|
92
|
-
end
|
93
|
-
}
|
94
|
-
|
95
|
-
# yepp, a private test WITH interface violation, as this is still a semi-public concept.
|
96
|
-
it { composition.instance_variable_get(:@map).must_equal({
|
97
|
-
:id => {:method=>:id, :model=>:album},
|
98
|
-
:name => {:method=>:name, :model=>:album},
|
99
|
-
:band_id => {:method=>:id, :model=>:band},
|
100
|
-
:title => {:method=>:title, :model=>:band}}) }
|
101
|
-
end
|
102
|
-
end
|