disposable 0.1.15 → 0.2.0.rc1

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: af71c707fe20d98b1c391731fdcf9364c1817132
4
- data.tar.gz: faae48ac6f616ebe485d7c9c4557cfe103ba9bb1
3
+ metadata.gz: a33b386392c77411ef19323562c9f0bb3b31761c
4
+ data.tar.gz: 789982e39d11feb8a4550e93452ca8d9ba91ac07
5
5
  SHA512:
6
- metadata.gz: af47c88b1c74259f7903ef82e5cd480e40b0437796d421c2cfa43065ed6d19a83fc4361fd679460490b3b722100146b95baaea7712f49af81147385093636fda
7
- data.tar.gz: 56482ea426fdb444826fca0240c97e0c615f155dc7bc7300c6e223f0f852484d7419d504fa7e8e55d5b73b1709212f3d0cce3d193fa0881b7034909dcf38ae80
6
+ metadata.gz: eb94a6c5097a5b380011f9a6cf6f6b02081b058842751110beec5b2f82cc37fc088f08d8b3ea2b8fb3d87e8607c9e44acc446d52470394f4ca27736cf8c29891
7
+ data.tar.gz: d11e58f841ecccfb165f6c48e6ddeb65eb3e9fe8b4aade955b6fc906bd056abc63589c9d42f05c1a35effb45becd6d0a6a616a171c81797d28fce1ac871895cf
data/.travis.yml CHANGED
@@ -1,8 +1,9 @@
1
1
  language: ruby
2
+ sudo: false
2
3
  rvm:
3
4
  - 2.2.0
4
5
  - 2.1.2
5
6
  - 2.0.0
6
7
  - 1.9.3
7
8
  gemfile:
8
- - Gemfile
9
+ - Gemfile
data/CHANGES.md CHANGED
@@ -1,6 +1,9 @@
1
- # 0.1.15
1
+ # 0.2.0
2
2
 
3
- * Restrict to Representable < 2.4.
3
+ * Internally, use [Declarative](https://github.com/apotonick/declarative) now for schema creation, resulting in the following internal changes.
4
+ * `Twin::representer_class.representable_attrs` is now `Twin::definitions`.
5
+ * `Disposable::Twin::Schema` is now `Disposable::Rescheme`. Renamed its `:representer_from` option to `:definitions_from`.
6
+ * `twin: Twin::Song` is the only way to specify an external twin. To reduce complexity, I've removed the lambda version of `:twin`.
4
7
 
5
8
  # 0.1.14
6
9
 
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in disposable.gemspec
1
+ source "https://rubygems.org"
4
2
  gemspec
5
3
 
6
- # gem 'representable', path: '../representable'
4
+ # gem "representable", path: "../representable"
5
+ gem "representable", github: "apotonick/representable"
6
+ # gem "declarative", path: "../declarative"
7
+ # gem "declarative", github: "apotonick/declarative"
8
+ gem "minitest-line"
data/disposable.gemspec CHANGED
@@ -19,7 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "uber"
22
- spec.add_dependency "representable", ">= 2.2.3", "< 2.4.0"
22
+ spec.add_dependency "declarative", "~> 0.0.4"
23
+ spec.add_dependency "representable", ">= 2.4.0.rc1", "< 2.5.0"
23
24
 
24
25
  spec.add_development_dependency "bundler", "~> 1.3"
25
26
  spec.add_development_dependency "rake"
@@ -12,26 +12,16 @@ module Disposable::Callback
12
12
  # you can call collection :songs again, with :inherit. TODO: verify.
13
13
 
14
14
  class Group
15
- # TODO: make this easier via declarable.
16
- extend Uber::InheritableAttr
17
- inheritable_attr :representer_class
18
-
19
- # class << self
20
- # include Representable::Cloneable
21
- # end
22
- self.representer_class = Class.new(Representable::Decorator) do
23
- def self.default_inline_class
24
- Group.extend Representable::Cloneable
25
- end
15
+ extend Declarative::Schema
16
+
17
+ def self.default_nested_class
18
+ Group
26
19
  end
27
20
 
28
21
  def self.clone
29
22
  Class.new(self)
30
23
  end
31
24
 
32
- def self.feature(*args)
33
- end
34
-
35
25
  def self.collection(name, options={}, &block)
36
26
  property(name, options.merge(collection: true), &block)
37
27
  end
@@ -42,9 +32,9 @@ module Disposable::Callback
42
32
  # it should have a Definition per callback where the representer_module will be a nested Group or a Callback.
43
33
  inherit = options[:inherit] # FIXME: this is deleted in ::property.
44
34
 
45
- representer_class.property(name, options, &block).tap do |dfn|
35
+ super(name, options, &block).tap do |dfn|
46
36
  return if inherit
47
- hooks << ["property", dfn.name]
37
+ hooks << ["property", dfn[:name]]
48
38
  end
49
39
  end
50
40
 
@@ -60,12 +50,16 @@ module Disposable::Callback
60
50
 
61
51
  attr_reader :invocations
62
52
 
63
- inheritable_attr :hooks
64
- self.hooks = []
53
+ def self.hooks
54
+ @hooks ||= []
55
+ end
56
+
65
57
 
66
58
  class << self
67
59
  %w(on_add on_delete on_destroy on_update on_create on_change).each do |event|
68
60
  define_method event do |*args|
61
+ heritage.record(event, *args)
62
+
69
63
  hooks << [event.to_sym, args]
70
64
  end
71
65
  end
@@ -73,14 +67,13 @@ module Disposable::Callback
73
67
 
74
68
 
75
69
  def call(options={})
76
- self.class.hooks.each do |cfg|
77
- event, args = cfg
78
-
70
+ self.class.hooks.each do |event, args|
79
71
  if event == "property" # FIXME: make nicer.
80
- definition = self.class.representer_class.representable_attrs.get(args)
81
- twin = @twin.send(definition.getter) # album.songs
72
+ definition = self.class.definitions.get(args)
73
+ twin = @twin.send(definition[:name]) # album.songs
82
74
 
83
- @invocations += definition.representer_module.new(twin).(options).invocations # Group.new(twin).()
75
+ # recursively call nested group.
76
+ @invocations += definition[:nested].new(twin).(options).invocations # Group.new(twin).()
84
77
  next
85
78
  end
86
79
 
@@ -108,7 +101,7 @@ module Disposable::Callback
108
101
  # Implements the binding between the Callback API (on_change) and the underlying layer (twin/AR/etc.).
109
102
  class Dispatch
110
103
  def initialize(twins)
111
- @twins = twins.is_a?(Array) ? twins : [twins] # TODO: find that out with Collection.
104
+ @twins = Array(twins) # TODO: find that out with Collection.
112
105
  @invocations = []
113
106
  end
114
107
 
@@ -175,4 +168,4 @@ module Disposable::Callback
175
168
  end
176
169
  end
177
170
  end
178
- end
171
+ end
@@ -13,8 +13,8 @@ module Disposable
13
13
  # AlbumExpose.new(OpenStruct.new(title: "AFI")).name #=> "AFI"
14
14
  class Expose
15
15
  class << self
16
- def from(representer)
17
- representer.representable_attrs.each do |definition|
16
+ def from(schema)
17
+ schema.each do |definition|
18
18
  process_definition!(definition)
19
19
  end
20
20
  self
@@ -22,7 +22,7 @@ module Disposable
22
22
 
23
23
  private
24
24
  def process_definition!(definition)
25
- public_name = definition.name
25
+ public_name = definition[:name]
26
26
  private_name = definition[:private_name] || public_name
27
27
 
28
28
  accessors!(public_name, private_name, definition)
@@ -1,13 +1,13 @@
1
- # Schema::from allows to copy a representer structure. This will create "fresh" inline representers instead
1
+ # Rescheme::from allows to copy a schema structure. This will create "fresh" inline schemas instead
2
2
  # of inheriting/copying the original classes, making it a replication of the structure, only.
3
3
  #
4
- # Options allow to customize the copied representer.
4
+ # Options allow to customize the copied schema.
5
5
  #
6
6
  # +:exclude+: ignore options from original Definition when copying.
7
7
  #
8
8
  # Provided block is run per newly created Definition.
9
- # Schema.from(...) { |dfn| dfn[:readable] = true }
10
- class Disposable::Twin::Schema
9
+ # Rescheme.from(...) { |dfn| dfn[:readable] = true }
10
+ class Disposable::Rescheme
11
11
  def self.from(*args, &block)
12
12
  new.from(*args, &block)
13
13
  end
@@ -16,9 +16,9 @@ class Disposable::Twin::Schema
16
16
  def from(source_class, options, &block) # TODO: can we re-use this for all the decorator logic in #validate, etc?
17
17
  representer = build_representer(options)
18
18
 
19
- source_representer = options[:representer_from].call(source_class)
19
+ definitions = options[:definitions_from].call(source_class)
20
20
 
21
- source_representer.representable_attrs.each do |dfn|
21
+ definitions.each do |dfn|
22
22
  dfn = build_definition!(options, dfn, representer, &block)
23
23
  evaluate_block!(options, dfn, &block)
24
24
  end
@@ -41,7 +41,7 @@ private
41
41
  new_options.merge!(local_options)
42
42
 
43
43
  return from_scalar!(options, source_dfn, new_options, representer) if options[:recursive]==false
44
- return from_scalar!(options, source_dfn, new_options, representer) unless source_dfn[:extend]
44
+ return from_scalar!(options, source_dfn, new_options, representer) unless source_dfn[:nested]
45
45
  from_inline!(options, source_dfn, new_options, representer, &block)
46
46
  end
47
47
 
@@ -52,14 +52,14 @@ private
52
52
  end
53
53
 
54
54
  def from_scalar!(options, dfn, new_options, representer)
55
- representer.property(dfn.name, new_options)
55
+ representer.property(dfn[:name], new_options)
56
56
  end
57
57
 
58
58
  def from_inline!(options, dfn, new_options, representer, &block)
59
- nested = dfn[:extend].evaluate(nil) # nested now can be a Decorator, a representer module, a Form, a Twin.
60
- dfn_options = new_options.merge(extend: from(nested, options, &block))
59
+ nested = dfn[:nested]#.evaluate(nil) # nested now can be a Decorator, a representer module, a Form, a Twin.
60
+ dfn_options = new_options.merge(nested: from(nested, options, &block))
61
61
 
62
- representer.property(dfn.name, dfn_options)
62
+ representer.property(dfn[:name], dfn_options)
63
63
  end
64
64
 
65
65
  def evaluate_block!(options, definition)
@@ -44,7 +44,7 @@ private
44
44
  next unless twin = send(dfn.getter)
45
45
  next unless twin.changed?
46
46
 
47
- changes[dfn.name] = true
47
+ changes[dfn[:name]] = true
48
48
  end
49
49
  end
50
50
  end
@@ -6,7 +6,7 @@ module Disposable
6
6
  module Expose
7
7
  module ClassMethods
8
8
  def expose_class
9
- @expose_class ||= Class.new(Disposable::Expose).from(representer_class)
9
+ @expose_class ||= Class.new(Disposable::Expose).from(definitions.values)
10
10
  end
11
11
  end # ClassMethods.
12
12
 
@@ -26,7 +26,7 @@ module Disposable
26
26
  module Composition
27
27
  module ClassMethods
28
28
  def expose_class
29
- @expose_class ||= Class.new(Disposable::Composition).from(representer_class)
29
+ @expose_class ||= Class.new(Disposable::Composition).from(definitions.values)
30
30
  end
31
31
  end
32
32
 
@@ -39,7 +39,7 @@ module Disposable
39
39
  hash = {}
40
40
 
41
41
  @model.each do |name, model| # TODO: provide list of composee attributes in Composition.
42
- part_properties = self.class.representer_class.representable_attrs.find_all { |dfn| dfn[:on] == name }.collect(&:name).collect(&:to_sym)
42
+ part_properties = schema.find_all { |dfn| dfn[:on] == name }.collect{ |dfn| dfn[:name].to_sym }
43
43
  hash[name] = self.class.nested_hash_representer.new(self).to_hash(include: part_properties)
44
44
  end
45
45
 
@@ -0,0 +1,28 @@
1
+ class Disposable::Twin
2
+ class Definition < Declarative::Definitions::Definition
3
+ def getter
4
+ self[:name]
5
+ end
6
+
7
+ def setter
8
+ "#{self[:name]}="
9
+ end
10
+ end
11
+
12
+ module DefinitionsEach
13
+ def each(options={})
14
+ return self unless block_given?
15
+
16
+ super() do |dfn|
17
+ next if options[:exclude] and options[:exclude].include?(dfn[:name])
18
+ next if options[:scalar] and dfn[:collection]
19
+ next if options[:collection] and ! dfn[:collection]
20
+ next if options[:twin] and ! dfn[:nested]
21
+
22
+ yield dfn
23
+ end
24
+
25
+ self
26
+ end
27
+ end
28
+ end
@@ -24,8 +24,8 @@ module Disposable
24
24
 
25
25
  def setup_property!(dfn, options)
26
26
  value =
27
- if options.has_key?(name = dfn.name.to_sym)
28
- options[dfn.name.to_sym]
27
+ if options.has_key?(name = dfn[:name].to_sym)
28
+ options[dfn[:name].to_sym]
29
29
  else
30
30
  setup_value_for(dfn, options)
31
31
  end
@@ -39,17 +39,18 @@ module Disposable
39
39
  end
40
40
 
41
41
  def read_value_for(dfn, options)
42
- mapper.send(dfn.name) # model.title.
42
+ mapper.send(dfn[:name]) # model.title.
43
43
  end
44
44
 
45
45
  def setup_write!(dfn, value)
46
- send(dfn.setter, value)
46
+ # send(dfn.setter, value)
47
+ send("#{dfn[:name]}=", value) # FIXME!
47
48
  end
48
49
 
49
50
  # Including this will _not_ use the property's setter in Setup and allow you to override it.
50
51
  module SkipSetter
51
52
  def setup_write!(dfn, value)
52
- write_property(dfn.name, value, dfn)
53
+ write_property(dfn[:name], value, dfn)
53
54
  end
54
55
  end
55
56
  end # Setup
@@ -5,7 +5,7 @@
5
5
  # Twin.new(id: 1)
6
6
  module Struct
7
7
  def read_value_for(dfn, options)
8
- name = dfn.name
8
+ name = dfn[:name]
9
9
  @model[name.to_s] || @model[name.to_sym] # TODO: test sym vs. str.
10
10
  end
11
11
 
@@ -15,7 +15,7 @@
15
15
  prepare: lambda { |model, *| model },
16
16
  serialize: lambda { |model, *| model.sync! },
17
17
  representable: true
18
- ) if dfn[:twin]
18
+ ) if dfn[:nested]
19
19
  end
20
20
  end
21
21
 
@@ -5,12 +5,23 @@
5
5
  # Note: #sync currently implicitly saves AR objects with collections
6
6
  class Disposable::Twin
7
7
  module Sync
8
+ class Options < ::Hash
9
+ def exclude!(names)
10
+ excludes.push(*names)
11
+ self
12
+ end
13
+
14
+ def excludes
15
+ self[:exclude] ||= []
16
+ end
17
+ end
18
+
8
19
  # Creates a fresh copy of the internal representer and adds Representable::Hash.
9
20
  # This is used wherever a hash transformation is needed.
10
21
  def self.hash_representer(twin_class, &block)
11
- Schema.from(twin_class,
22
+ Disposable::Rescheme.from(twin_class,
12
23
  recursive: false,
13
- representer_from: lambda { |twin_class| twin_class.representer_class },
24
+ definitions_from: lambda { |twin_class| twin_class.definitions },
14
25
  superclass: Representable::Decorator,
15
26
  include: Representable::Hash,
16
27
  exclude_options: [:default], # TODO: TEST IN default_test.
@@ -25,19 +36,16 @@ class Disposable::Twin
25
36
  end
26
37
  alias_method :sync, :sync_models
27
38
 
28
- # reading from fields allows using readers in form for presentation
29
- # and writers still pass to fields in #validate????
30
-
31
39
  # Sync all scalar attributes, call sync! on nested and return model.
32
40
  def sync!(options) # semi-public.
33
41
  # TODO: merge this into Sync::Run or something and use in Struct, too, so we don't
34
42
  # need the representer anymore?
35
- options_for_sync = sync_options(Decorator::Options[options])
43
+ options_for_sync = sync_options(Options[options])
36
44
 
37
45
  schema.each(options_for_sync) do |dfn|
38
46
  property_value = sync_read(dfn) #
39
47
 
40
- unless dfn[:twin]
48
+ unless dfn[:nested]
41
49
  mapper.send(dfn.setter, property_value) # always sync the property
42
50
  next
43
51
  end
@@ -61,6 +69,7 @@ class Disposable::Twin
61
69
  send(definition.getter)
62
70
  end
63
71
 
72
+ # TODO: simplify that using a decent pipeline from Representable.
64
73
  module ToNestedHash
65
74
  def to_nested_hash(*)
66
75
  self.class.nested_hash_representer.new(nested_hash_source).to_hash
@@ -86,7 +95,7 @@ class Disposable::Twin
86
95
  dfn.merge!(
87
96
  prepare: lambda { |model, *| model }, # TODO: why do we need that here?
88
97
  serialize: lambda { |form, args| form.to_nested_hash },
89
- ) if dfn[:twin]
98
+ ) if dfn[:nested]
90
99
  end
91
100
  end # #build_nested_hash_representer
92
101
  end
@@ -107,7 +116,7 @@ class Disposable::Twin
107
116
  def sync_options(options)
108
117
  options = super
109
118
 
110
- protected_fields = schema.each.find_all { |d| d[:writeable] == false }.collect { |d| d.name }
119
+ protected_fields = schema.each.find_all { |d| d[:writeable] == false }.collect { |d| d[:name] }
111
120
  options.exclude!(protected_fields)
112
121
  end
113
122
  end
@@ -126,7 +135,7 @@ class Disposable::Twin
126
135
  def sync_options(options)
127
136
  # DISCUSS: we currently don't track if nested forms have changed (only their attributes). that's why i include them all here, which
128
137
  # is additional sync work/slightly wrong. solution: allow forms to form.changed? not sure how to do that with collections.
129
- scalars = schema.each(scalar: true).collect { |dfn| dfn.name }
138
+ scalars = schema.each(scalar: true).collect { |dfn| dfn[:name ]}
130
139
  unchanged = scalars - changed.keys
131
140
 
132
141
  # exclude unchanged scalars, nested forms and changed scalars still go in here!
@@ -139,7 +148,7 @@ class Disposable::Twin
139
148
  # Include this won't use the getter #title in #sync but read directly from @fields.
140
149
  module SkipGetter
141
150
  def sync_read(dfn)
142
- @fields[dfn.name]
151
+ @fields[dfn[:name]]
143
152
  end
144
153
 
145
154
  def nested_hash_source
@@ -1,19 +1,18 @@
1
- # DISCUSS: sync via @fields, not reader? allows overriding a la reform 1.
2
-
3
1
  require "uber/inheritable_attr"
4
-
5
- require "disposable/twin/representer"
2
+ require "declarative/schema"
3
+ require "disposable/twin/definitions"
6
4
  require "disposable/twin/collection"
7
5
  require "disposable/twin/setup"
8
6
  require "disposable/twin/sync"
9
7
  require "disposable/twin/save"
10
- require "disposable/twin/option"
11
8
  require "disposable/twin/builder"
12
9
  require "disposable/twin/changed"
13
10
  require "disposable/twin/property_processor"
14
11
  require "disposable/twin/persisted"
15
12
  require "disposable/twin/default"
16
13
 
14
+ require "representable/decorator"
15
+
17
16
  # Twin.new(model/composition hash/hash, options)
18
17
  # assign hash to @fields
19
18
  # write: write to @fields
@@ -21,29 +20,20 @@ require "disposable/twin/default"
21
20
 
22
21
  module Disposable
23
22
  class Twin
24
- extend Uber::InheritableAttr
25
-
26
- inheritable_attr :representer_class
27
- self.representer_class = Class.new(Decorator)
28
-
29
- # Returns an each'able array of all properties defined in this twin.
30
- # Allows to filter using
31
- # * collection: true
32
- # * twin: true
33
- # * scalar: true
34
- # * exclude: ["title", "email"]
35
- def schema
36
- self.class.representer_class
23
+ extend Declarative::Schema
24
+ def self.definition_class
25
+ Definition
37
26
  end
38
27
 
39
-
40
- extend Representable::Feature # imports ::feature, which calls ::register_feature.
41
- def self.register_feature(mod)
42
- representer_class.representable_attrs[:features][mod] = true
28
+ def schema
29
+ self.class.definitions.extend(DefinitionsEach)
43
30
  end
44
31
 
45
-
46
32
  class << self
33
+ def default_nested_class
34
+ Twin
35
+ end
36
+
47
37
  # TODO: move to Declarative, as in Representable and Reform.
48
38
  def property(name, options={}, &block)
49
39
  options[:private_name] = options.delete(:from) || name
@@ -52,18 +42,10 @@ module Disposable
52
42
  options[:writeable] = options[:readable] = false
53
43
  end
54
44
 
55
- options[:extend] = options[:twin] # e.g. property :album, twin: Album.
45
+ options[:nested] = options.delete(:twin) if options[:twin]
56
46
 
57
- representer_class.property(name, options, &block).tap do |definition|
47
+ super(name, options, &block).tap do |definition|
58
48
  create_accessors(name, definition)
59
-
60
- if definition[:extend] and !options[:twin]
61
- # This will soon be replaced with Declarative's API. # DISCUSS: could we use build_inline's api here to inject the name feature?
62
- nested_twin = definition[:extend].evaluate(nil)
63
- process_inline!(nested_twin, definition)
64
-
65
- definition.merge!(twin: nested_twin) # DISCUSS: where do we need this?
66
- end
67
49
  end
68
50
  end
69
51
 
@@ -80,14 +62,10 @@ module Disposable
80
62
  mod = Module.new do
81
63
  define_method(name) { @fields[name.to_s] }
82
64
  # define_method(name) { read_property(name) }
83
- define_method("#{name}=") { |value| write_property(name, value, definition) } # TODO: this is more like prototyping.
65
+ define_method("#{name}=") { |value| write_property(name, value, definition) }
84
66
  end
85
67
  include mod
86
68
  end
87
-
88
- # DISCUSS: this method might disappear or change pretty soon.
89
- def process_inline!(mod, definition)
90
- end
91
69
  end
92
70
 
93
71
  include Setup
@@ -97,8 +75,8 @@ module Disposable
97
75
  private
98
76
  # assumption: collections are always initialized from Setup since we assume an empty [] for "nil"/uninitialized collections.
99
77
  def write_property(name, value, dfn)
100
- if dfn[:twin] and value
101
- value = dfn.array? ? wrap_collection(dfn, value) : wrap_scalar(dfn, value)
78
+ if dfn[:nested] and value
79
+ value = dfn[:collection] ? wrap_collection(dfn, value) : wrap_scalar(dfn, value)
102
80
  end
103
81
 
104
82
  field_write(name, value)
@@ -124,24 +102,13 @@ module Disposable
124
102
  end
125
103
  include Accessors
126
104
 
127
-
128
- # FIXME: this is experimental.
129
- module ToS
130
- def to_s
131
- return super if self.class.name
132
- "#<Twin (inline):#{object_id}>"
133
- end
134
- end
135
- include ToS
136
-
137
-
138
105
  class Twinner
139
106
  def initialize(dfn)
140
107
  @dfn = dfn
141
108
  end
142
109
 
143
110
  def call(value)
144
- @dfn.twin_class.new(value)
111
+ @dfn[:nested].new(value)
145
112
  end
146
113
  end
147
114
 
@@ -152,7 +119,5 @@ module Disposable
152
119
  attr_reader :mapper
153
120
  end
154
121
  include ModelReaders
155
-
156
- include Option
157
122
  end
158
- end
123
+ end
@@ -1,3 +1,3 @@
1
1
  module Disposable
2
- VERSION = "0.1.15"
2
+ VERSION = "0.2.0.rc1"
3
3
  end
data/lib/disposable.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "disposable/version"
2
2
  require "disposable/twin"
3
+ require "disposable/rescheme"
3
4
 
4
5
  module Disposable
5
6
  class Twin
@@ -148,10 +148,10 @@ class CallbackGroupInheritanceTest < MiniTest::Spec
148
148
  it do
149
149
  Group.hooks.size.must_equal 4
150
150
  Group.hooks[0].to_s.must_equal "[:on_change, [:change!]]"
151
- # Group.hooks[1][1].representer_module.hooks.to_s.must_equal "[[:on_add, [:notify_album!]],[:on_add, [:reset_song!]]]"
151
+ # Group.hooks[1][1][:nested].hooks.to_s.must_equal "[[:on_add, [:notify_album!]],[:on_add, [:reset_song!]]]"
152
152
  Group.hooks[2].to_s.must_equal "[:on_change, [:rehash_name!, {:property=>:title}]]"
153
153
 
154
- Group.representer_class.representable_attrs.get(Group.hooks[3][1]).representer_module.hooks.to_s.must_equal "[[:on_change, [:sing!]]]"
154
+ Group.definitions.get(Group.hooks[3][1])[:nested].hooks.to_s.must_equal "[[:on_change, [:sing!]]]"
155
155
  end
156
156
 
157
157
  class EmptyGroup < Group
@@ -173,8 +173,9 @@ class CallbackGroupInheritanceTest < MiniTest::Spec
173
173
 
174
174
  it do
175
175
  Group.hooks.size.must_equal 4
176
+ pp EnhancedGroup.hooks
176
177
  EnhancedGroup.hooks.size.must_equal 6
177
- EnhancedGroup.representer_class.representable_attrs.get(EnhancedGroup.hooks[5][1]).representer_module.hooks.to_s.must_equal "[[:on_add, [:rewind!]]]"
178
+ EnhancedGroup.definitions.get(EnhancedGroup.hooks[5][1])[:nested].hooks.to_s.must_equal "[[:on_add, [:rewind!]]]"
178
179
  end
179
180
 
180
181
  class EnhancedWithInheritGroup < EnhancedGroup
@@ -190,10 +191,10 @@ class CallbackGroupInheritanceTest < MiniTest::Spec
190
191
  Group.hooks.size.must_equal 4
191
192
  EnhancedGroup.hooks.size.must_equal 6
192
193
 
193
- EnhancedGroup.representer_class.representable_attrs.get(EnhancedGroup.hooks[5][1]).representer_module.hooks.to_s.must_equal "[[:on_add, [:rewind!]]]"
194
+ EnhancedGroup.definitions.get(EnhancedGroup.hooks[5][1])[:nested].hooks.to_s.must_equal "[[:on_add, [:rewind!]]]"
194
195
  EnhancedWithInheritGroup.hooks.size.must_equal 6
195
- EnhancedWithInheritGroup.representer_class.representable_attrs.get(EnhancedWithInheritGroup.hooks[1][1]).representer_module.hooks.to_s.must_equal "[[:on_add, [:rewind!]], [:on_add, [:eat!]]]"
196
- EnhancedWithInheritGroup.representer_class.representable_attrs.get(EnhancedWithInheritGroup.hooks[3][1]).representer_module.hooks.to_s.must_equal "[[:on_change, [:sing!]], [:on_delete, [:yell!]]]"
196
+ EnhancedWithInheritGroup.definitions.get(EnhancedWithInheritGroup.hooks[1][1])[:nested].hooks.to_s.must_equal "[[:on_add, [:rewind!]], [:on_add, [:eat!]]]"
197
+ EnhancedWithInheritGroup.definitions.get(EnhancedWithInheritGroup.hooks[3][1])[:nested].hooks.to_s.must_equal "[[:on_change, [:sing!]], [:on_delete, [:yell!]]]"
197
198
  end
198
199
 
199
200
  class RemovingInheritGroup < Group
@@ -205,19 +206,19 @@ class CallbackGroupInheritanceTest < MiniTest::Spec
205
206
 
206
207
  # # puts "@@@@@ #{Group.hooks.object_id.inspect}"
207
208
  # # puts "@@@@@ #{EmptyGroup.hooks.object_id.inspect}"
208
- # puts "@@@@@ Group: #{Group.representer_class.representable_attrs.get(:songs).representer_module.hooks.inspect}"
209
- # puts "@@@@@ EnhancedGroup: #{EnhancedGroup.representer_class.representable_attrs.get(:songs).representer_module.hooks.inspect}"
210
- # puts "@@@@@ InheritGroup: #{EnhancedWithInheritGroup.representer_class.representable_attrs.get(:songs).representer_module.hooks.inspect}"
211
- # puts "@@@@@ RemovingGroup: #{RemovingInheritGroup.representer_class.representable_attrs.get(:songs).representer_module.hooks.inspect}"
212
- # # puts "@@@@@ #{EnhancedWithInheritGroup.representer_class.representable_attrs.get(:songs).representer_module.hooks.object_id.inspect}"
209
+ # puts "@@@@@ Group: #{Group.definitions.get(:songs)[:nested].hooks.inspect}"
210
+ # puts "@@@@@ EnhancedGroup: #{EnhancedGroup.definitions.get(:songs)[:nested].hooks.inspect}"
211
+ # puts "@@@@@ InheritGroup: #{EnhancedWithInheritGroup.definitions.get(:songs)[:nested].hooks.inspect}"
212
+ # puts "@@@@@ RemovingGroup: #{RemovingInheritGroup.definitions.get(:songs)[:nested].hooks.inspect}"
213
+ # # puts "@@@@@ #{EnhancedWithInheritGroup.definitions.get(:songs)[:nested].hooks.object_id.inspect}"
213
214
 
214
215
  # TODO: object_id tests for all nested representers.
215
216
 
216
217
  it do
217
218
  Group.hooks.size.must_equal 4
218
219
  RemovingInheritGroup.hooks.size.must_equal 3
219
- RemovingInheritGroup.representer_class.representable_attrs.get(RemovingInheritGroup.hooks[0][1]).representer_module.hooks.to_s.must_equal "[[:on_add, [:reset_song!]]]"
220
- RemovingInheritGroup.representer_class.representable_attrs.get(RemovingInheritGroup.hooks[2][1]).representer_module.hooks.to_s.must_equal "[[:on_change, [:sing!]]]"
220
+ RemovingInheritGroup.definitions.get(RemovingInheritGroup.hooks[0][1])[:nested].hooks.to_s.must_equal "[[:on_add, [:reset_song!]]]"
221
+ RemovingInheritGroup.definitions.get(RemovingInheritGroup.hooks[2][1])[:nested].hooks.to_s.must_equal "[[:on_change, [:sing!]]]"
221
222
  end
222
223
 
223
224
  # Group::clone
data/test/expose_test.rb CHANGED
@@ -16,7 +16,7 @@ class ExposeTest < MiniTest::Spec
16
16
  end
17
17
 
18
18
  class AlbumExpose < Disposable::Expose
19
- from Twin::Album.representer_class
19
+ from Twin::Album.definitions.values
20
20
  end
21
21
 
22
22
  let (:album) { Model::Album.new(1, "Dick Sandwich") }
@@ -59,7 +59,7 @@ class ExposeCompositionTest < MiniTest::Spec
59
59
  end
60
60
 
61
61
  class AlbumComposition < Disposable::Composition
62
- from Twin::Album.representer_class
62
+ from Twin::Album.definitions.values
63
63
  end
64
64
  end
65
65
 
@@ -1,8 +1,6 @@
1
1
  require "test_helper"
2
2
 
3
- require "disposable/twin/schema"
4
-
5
- class SchemaTest < MiniTest::Spec
3
+ class ReschemeTest < MiniTest::Spec
6
4
  module Representer
7
5
  include Representable
8
6
 
@@ -32,80 +30,80 @@ class SchemaTest < MiniTest::Spec
32
30
  end
33
31
 
34
32
  it do
35
- decorator = Disposable::Twin::Schema.from(Representer, superclass: Representable::Decorator,
36
- include: [Hello, Gday, Ciao], # Hello will win over Gday.
33
+ decorator = Disposable::Rescheme.from(Representer, superclass: Representable::Decorator,
34
+ include: [Representable::Hash, Hello, Gday, Ciao], # Hello will win over Gday.
37
35
  options_from: :deserializer,
38
- representer_from: lambda { |nested| nested }
36
+ definitions_from: lambda { |nested| nested.definitions }
39
37
  )
40
38
 
41
39
  # include: works.
42
40
  decorator.new(nil).hello.must_equal "hello"
43
41
  decorator.new(nil).ciao.must_equal "ciao"
44
42
 
45
- decorator.representable_attrs.get(:id).inspect.must_equal "#<Representable::Definition ==>id @options={:parse_filter=>[], :render_filter=>[], :as=>\"id\"}>"
46
- decorator.representable_attrs.get(:title).inspect.must_equal "#<Representable::Definition ==>title @options={:writeable=>false, :deserializer=>{:skip_parse=>\"skip lambda\"}, :parse_filter=>[], :render_filter=>[], :as=>\"title\", :skip_parse=>\"skip lambda\"}>"
43
+ decorator.representable_attrs.get(:id).inspect.must_equal "#<Representable::Definition ==>id @options={:name=>\"id\", :parse_filter=>[], :render_filter=>[]}>"
44
+ decorator.representable_attrs.get(:title).inspect.must_equal "#<Representable::Definition ==>title @options={:writeable=>false, :deserializer=>{:skip_parse=>\"skip lambda\"}, :name=>\"title\", :parse_filter=>[], :render_filter=>[], :skip_parse=>\"skip lambda\"}>"
47
45
 
48
46
  songs = decorator.representable_attrs.get(:songs)
49
47
  options = songs.instance_variable_get(:@options)
50
- nested_extend = options.delete(:extend)
51
- options.inspect.must_equal "{:readable=>false, :deserializer=>{:skip_parse=>\"another lambda\", :music=>true, :writeable=>false}, :parse_filter=>[], :render_filter=>[], :as=>\"songs\", :_inline=>true, :skip_parse=>\"another lambda\", :music=>true, :writeable=>false}"
48
+ options[:nested].extend(Declarative::Inspect)
49
+ options.inspect.must_equal "{:readable=>false, :deserializer=>{:skip_parse=>\"another lambda\", :music=>true, :writeable=>false}, :nested=>#<Class:>, :extend=>#<Class:>, :name=>\"songs\", :parse_filter=>[], :render_filter=>[], :skip_parse=>\"another lambda\", :music=>true, :writeable=>false}"
52
50
 
53
51
  # nested works.
54
- nested_extend.new(nil).hello.must_equal "hello"
55
- nested_extend.new(nil).ciao.must_equal "ciao"
52
+ options[:nested].new(nil).hello.must_equal "hello"
53
+ options[:nested].new(nil).ciao.must_equal "ciao"
56
54
 
57
- nested_extend.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :parse_filter=>[], :render_filter=>[], :skip_parse=>\"a crazy cool instance method\"}>"
55
+ options[:nested].representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :name=>\"name\", :parse_filter=>[], :render_filter=>[], :skip_parse=>\"a crazy cool instance method\"}>"
58
56
  end
59
57
 
60
58
  # :options_from and :include is optional
61
59
  it do
62
- decorator = Disposable::Twin::Schema.from(Representer, superclass: Representable::Decorator,
63
- representer_from: lambda { |nested| nested }
60
+ decorator = Disposable::Rescheme.from(Representer, superclass: Representable::Decorator, include: [Representable::Hash],
61
+ definitions_from: lambda { |nested| nested.definitions }
64
62
  )
65
63
 
66
- decorator.representable_attrs.get(:id).inspect.must_equal "#<Representable::Definition ==>id @options={:parse_filter=>[], :render_filter=>[], :as=>\"id\"}>"
67
- decorator.representable_attrs.get(:title).inspect.must_equal "#<Representable::Definition ==>title @options={:writeable=>false, :deserializer=>{:skip_parse=>\"skip lambda\"}, :parse_filter=>[], :render_filter=>[], :as=>\"title\"}>"
64
+ decorator.representable_attrs.get(:id).inspect.must_equal "#<Representable::Definition ==>id @options={:name=>\"id\", :parse_filter=>[], :render_filter=>[]}>"
65
+ decorator.representable_attrs.get(:title).inspect.must_equal "#<Representable::Definition ==>title @options={:writeable=>false, :deserializer=>{:skip_parse=>\"skip lambda\"}, :name=>\"title\", :parse_filter=>[], :render_filter=>[]}>"
68
66
  end
69
67
 
70
68
 
71
69
  # :exclude_options allows skipping particular options when copying.
72
70
  it do
73
- decorator = Disposable::Twin::Schema.from(Representer, superclass: Representable::Decorator,
74
- representer_from: lambda { |nested| nested },
71
+ decorator = Disposable::Rescheme.from(Representer, superclass: Representable::Decorator, include: [Representable::Hash],
72
+ definitions_from: lambda { |nested| nested.definitions },
75
73
  exclude_options: [:deserializer]
76
74
  )
77
75
 
78
- decorator.representable_attrs.get(:id).inspect.must_equal "#<Representable::Definition ==>id @options={:parse_filter=>[], :render_filter=>[], :as=>\"id\"}>"
79
- decorator.representable_attrs.get(:title).inspect.must_equal "#<Representable::Definition ==>title @options={:writeable=>false, :parse_filter=>[], :render_filter=>[], :as=>\"title\"}>"
80
- decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:as=>\"Name\", :parse_filter=>[], :render_filter=>[]}>"
76
+ decorator.representable_attrs.get(:id).inspect.must_equal "#<Representable::Definition ==>id @options={:name=>\"id\", :parse_filter=>[], :render_filter=>[]}>"
77
+ decorator.representable_attrs.get(:title).inspect.must_equal "#<Representable::Definition ==>title @options={:writeable=>false, :name=>\"title\", :parse_filter=>[], :render_filter=>[]}>"
78
+ decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:as=>\"Name\", :name=>\"name\", :parse_filter=>[], :render_filter=>[]}>"
81
79
  end
82
80
 
83
81
 
84
82
  it "::from with block allows customizing every definition and returns representer" do
85
- decorator = Disposable::Twin::Schema.from(Representer,
83
+ decorator = Disposable::Rescheme.from(Representer, include: [Representable::Hash],
86
84
  superclass: Representable::Decorator,
87
- representer_from: lambda { |nested| nested },
85
+ definitions_from: lambda { |nested| nested.definitions },
88
86
  ) { |dfn| dfn.merge!(amazing: true) }
89
87
 
90
- decorator.representable_attrs.get(:id).inspect.must_equal "#<Representable::Definition ==>id @options={:parse_filter=>[], :render_filter=>[], :as=>\"id\", :amazing=>true}>"
91
- decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :parse_filter=>[], :render_filter=>[], :amazing=>true}>"
88
+ decorator.representable_attrs.get(:id).inspect.must_equal "#<Representable::Definition ==>id @options={:name=>\"id\", :parse_filter=>[], :render_filter=>[], :amazing=>true}>"
89
+ decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :name=>\"name\", :parse_filter=>[], :render_filter=>[], :amazing=>true}>"
92
90
  end
93
91
 
94
92
  it "recursive: false only copies first level" do
95
- decorator = Disposable::Twin::Schema.from(Representer,
93
+ decorator = Disposable::Rescheme.from(Representer, include: [Representable::Hash],
96
94
  superclass: Representable::Decorator,
97
- representer_from: lambda { |nested| nested },
95
+ definitions_from: lambda { |nested| nested.definitions },
98
96
  recursive: false,
99
97
  exclude_options: [:deserializer]
100
98
  )
101
99
 
102
- decorator.representable_attrs.get(:title).inspect.must_equal "#<Representable::Definition ==>title @options={:writeable=>false, :parse_filter=>[], :render_filter=>[], :as=>\"title\"}>"
103
- decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :parse_filter=>[], :render_filter=>[]}>"
100
+ decorator.representable_attrs.get(:title).inspect.must_equal "#<Representable::Definition ==>title @options={:writeable=>false, :name=>\"title\", :parse_filter=>[], :render_filter=>[]}>"
101
+ decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :name=>\"name\", :parse_filter=>[], :render_filter=>[]}>"
104
102
  end
105
103
  end
106
104
 
107
105
 
108
- class TwinSchemaTest < MiniTest::Spec
106
+ class TwinReschemeTest < MiniTest::Spec
109
107
  class Artist < Disposable::Twin
110
108
  property :name
111
109
  end
@@ -115,15 +113,15 @@ class TwinSchemaTest < MiniTest::Spec
115
113
  end
116
114
 
117
115
  it do
118
- decorator = Disposable::Twin::Schema.from(Album, superclass: Representable::Decorator,
119
- representer_from: lambda { |nested| nested.representer_class }
116
+ decorator = Disposable::Rescheme.from(Album, superclass: Representable::Decorator, include: [Representable::Hash],
117
+ definitions_from: lambda { |nested| nested.definitions }
120
118
  )
121
119
 
122
120
  artist = decorator.representable_attrs.get(:artist)
123
121
  options = artist.instance_variable_get(:@options)
124
- nested_extend = options.delete(:extend)
125
- options.inspect.must_equal "{:twin=>TwinSchemaTest::Artist, :private_name=>:artist, :parse_filter=>[], :render_filter=>[], :as=>\"artist\"}"
122
+ nested_extend = options[:nested]
123
+ options.extend(Declarative::Inspect).inspect.must_equal "{:private_name=>:artist, :nested=>#<Class:>, :name=>\"artist\", :extend=>#<Class:>, :parse_filter=>[], :render_filter=>[]}"
126
124
  assert nested_extend < Representable::Decorator
127
- nested_extend.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:private_name=>:name, :parse_filter=>[], :render_filter=>[], :as=>\"name\"}>"
125
+ nested_extend.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:private_name=>:name, :name=>\"name\", :parse_filter=>[], :render_filter=>[]}>"
128
126
  end
129
127
  end
data/test/test_helper.rb CHANGED
@@ -1,7 +1,8 @@
1
- require 'disposable'
2
- require 'minitest/autorun'
1
+ require "disposable"
2
+ require "minitest/autorun"
3
3
  require "pp"
4
4
  require "representable/debug"
5
+ require "declarative/testing"
5
6
 
6
7
  class Track
7
8
  def initialize(options={})
@@ -16,13 +16,13 @@ class TwinCollectionTest < MiniTest::Spec
16
16
  class Song < Disposable::Twin
17
17
  property :id # DISCUSS: needed for #save.
18
18
  property :title
19
- property :album, :twin => Album
19
+ # property :album, twin: Album
20
20
  end
21
21
 
22
22
  class Album < Disposable::Twin
23
23
  property :id # DISCUSS: needed for #save.
24
24
  property :name
25
- collection :songs, :twin => lambda { |*| Song }
25
+ collection :songs, twin: Song
26
26
  end
27
27
  end
28
28
 
@@ -62,8 +62,8 @@ class TwinCollectionActiveRecordTest < MiniTest::Spec
62
62
  class Album < Disposable::Twin
63
63
  property :id # DISCUSS: needed for #save.
64
64
  property :name
65
- collection :songs, :twin => lambda { |*| Song }
66
- property :artist, twin: lambda { |*| Artist }
65
+ collection :songs, twin: Twin::Song
66
+ property :artist, twin: Twin::Artist
67
67
 
68
68
  include Sync
69
69
  include Save
@@ -208,7 +208,7 @@ class CollectionUnitTest < MiniTest::Spec
208
208
  Album = Struct.new(:id, :name, :songs, :artist)
209
209
  end
210
210
 
211
- let(:collection) { Disposable::Twin::Collection.new(Disposable::Twin::Twinner.new(Twin::Song.representer_class.representable_attrs.get(:album)), []) }
211
+ let(:collection) { Disposable::Twin::Collection.new(Disposable::Twin::Twinner.new(Twin::Song.definitions.get(:album)), []) }
212
212
 
213
213
  # #insert(index, model)
214
214
  it do
@@ -18,23 +18,19 @@ class FeatureTest < MiniTest::Spec
18
18
  end
19
19
 
20
20
  class AlbumForm < Disposable::Twin
21
- include Setup
22
21
  feature Date
23
22
  property :name
24
23
 
25
24
  collection :songs do
26
- include Setup
27
25
  property :title
28
26
 
29
27
  property :composer do
30
- include Setup
31
28
  feature Instrument
32
29
  property :name
33
30
  end
34
31
  end
35
32
 
36
33
  property :artist do
37
- include Setup
38
34
  property :name
39
35
  end
40
36
  end
@@ -40,8 +40,8 @@ class InheritTest < MiniTest::Spec
40
40
 
41
41
  # definitions are not shared.
42
42
  it do
43
- Twin::Album.representer_class.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:fromage=>:_name, :private_name=>:name, :parse_filter=>[], :render_filter=>[], :as=>\"name\"}>"
44
- Twin::Compilation.representer_class.representable_attrs.get(:name).inspect.must_equal "#<Representable::Definition ==>name @options={:fromage=>:_name, :private_name=>:name, :parse_filter=>[], :render_filter=>[], :as=>\"name\", :writeable=>false, :inherit=>true}>"
43
+ Twin::Album.definitions.get(:name).extend(Declarative::Inspect).inspect.must_equal "#<Disposable::Twin::Definition: @options={:fromage=>:_name, :private_name=>:name, :name=>\"name\"}>"
44
+ Twin::Compilation.definitions.get(:name).extend(Declarative::Inspect).inspect.must_equal "#<Disposable::Twin::Definition: @options={:fromage=>:_name, :private_name=>:name, :name=>\"name\", :writeable=>false}>" # FIXME: where did :inherit go?
45
45
  end
46
46
 
47
47
 
@@ -1,35 +1,35 @@
1
- require "test_helper"
1
+ # require "test_helper"
2
2
 
3
- class ProcessInlineTest < MiniTest::Spec
4
- Album = Struct.new(:artist, :composer, :recursive_composer)
3
+ # class ProcessInlineTest < MiniTest::Spec
4
+ # Album = Struct.new(:artist, :composer, :recursive_composer)
5
5
 
6
- module InlineTwin
7
- end
6
+ # module InlineTwin
7
+ # end
8
8
 
9
- class RecursiveComposerTwin < Disposable::Twin
10
- property :composer, twin: self
11
- end
9
+ # class RecursiveComposerTwin < Disposable::Twin
10
+ # property :composer, twin: self
11
+ # end
12
12
 
13
- class AlbumTwin < Disposable::Twin
14
- def self.process_inline!(inline_class, definition)
15
- inline_class.send :include, InlineTwin
16
- end
13
+ # class AlbumTwin < Disposable::Twin
14
+ # def self.process_inline!(inline_class, definition)
15
+ # inline_class.send :include, InlineTwin
16
+ # end
17
17
 
18
- property :artist do
19
- end
18
+ # property :artist do
19
+ # end
20
20
 
21
- property :composer, twin: ->{ ComposerTwin }
21
+ # property :composer, twin: ->{ ComposerTwin }
22
22
 
23
- property :recursive_composer, twin: RecursiveComposerTwin
24
- end
23
+ # property :recursive_composer, twin: RecursiveComposerTwin
24
+ # end
25
25
 
26
- class ComposerTwin < Disposable::Twin
27
- end
26
+ # class ComposerTwin < Disposable::Twin
27
+ # end
28
28
 
29
- it do
30
- twin = AlbumTwin.new(Album.new(Object, Object))
31
- assert ! (twin.class < InlineTwin)
32
- assert (twin.artist.class < InlineTwin)
33
- assert ! (twin.composer.class < InlineTwin)
34
- end
35
- end
29
+ # it do
30
+ # twin = AlbumTwin.new(Album.new(Object, Object))
31
+ # assert ! (twin.class < InlineTwin)
32
+ # assert (twin.artist.class < InlineTwin)
33
+ # assert ! (twin.composer.class < InlineTwin)
34
+ # end
35
+ # end
@@ -17,7 +17,7 @@ class TwinSetupTest < MiniTest::Spec
17
17
 
18
18
  class Song < Disposable::Twin
19
19
  property :id
20
- property :composer, twin: lambda { |*| Twin::Artist }
20
+ property :composer, twin: Twin::Artist
21
21
 
22
22
  include Setup
23
23
  end
@@ -25,8 +25,8 @@ class TwinSetupTest < MiniTest::Spec
25
25
  class Album < Disposable::Twin
26
26
  property :id
27
27
  property :name
28
- collection :songs, twin: lambda { |*| Twin::Song }
29
- property :artist, twin: lambda { |*| Twin::Artist }
28
+ collection :songs, twin: Twin::Song
29
+ property :artist, twin: Twin::Artist
30
30
 
31
31
  include Setup
32
32
  end
@@ -7,25 +7,24 @@ class TwinTest < MiniTest::Spec
7
7
  Artist = Struct.new(:id)
8
8
  end
9
9
 
10
-
10
+ # test twin: option
11
11
  module Twin
12
+ class Artist < Disposable::Twin
13
+ property :id
14
+
15
+ include Setup
16
+ end
17
+
12
18
  class Album < Disposable::Twin
13
19
  property :id # DISCUSS: needed for #save.
14
20
  property :name
15
- collection :songs, :twin => lambda { |*| Song }
16
- property :artist, :twin => lambda { |*| Artist }
21
+ property :artist, twin: Artist
17
22
  end
18
23
 
19
24
  class Song < Disposable::Twin
20
25
  property :id # DISCUSS: needed for #save.
21
26
  property :title
22
- property :album, :twin => Album
23
- end
24
-
25
- class Artist < Disposable::Twin
26
- property :id
27
-
28
- include Setup
27
+ property :album, twin: Album
29
28
  end
30
29
  end
31
30
 
@@ -91,20 +90,6 @@ class TwinTest < MiniTest::Spec
91
90
  # result.must_equal twin.album
92
91
  # end
93
92
  end
94
-
95
- # FIXME: experimental.
96
- describe "#to_s" do
97
- class HitTwin < Disposable::Twin
98
- include Setup
99
-
100
- property :song do
101
- end
102
- end
103
-
104
- let (:hit) { OpenStruct.new(song: song) }
105
- it { HitTwin.new(hit).to_s.must_match "#<TwinTest::HitTwin:" }
106
- it { HitTwin.new(hit).song.to_s.must_match "#<Twin (inline):" }
107
- end
108
93
  end
109
94
 
110
95
 
@@ -138,7 +123,7 @@ class TwinAsTest < MiniTest::Spec
138
123
 
139
124
  class Song < Disposable::Twin
140
125
  property :name, :from => :title
141
- property :record, :twin => Album, :from => :album
126
+ property :record, twin: Album, :from => :album
142
127
 
143
128
  # model Model::Song
144
129
  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.15
4
+ version: 0.2.0.rc1
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-11-27 00:00:00.000000000 Z
11
+ date: 2015-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uber
@@ -24,26 +24,40 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: declarative
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.4
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: representable
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: 2.2.3
47
+ version: 2.4.0.rc1
34
48
  - - "<"
35
49
  - !ruby/object:Gem::Version
36
- version: 2.4.0
50
+ version: 2.5.0
37
51
  type: :runtime
38
52
  prerelease: false
39
53
  version_requirements: !ruby/object:Gem::Requirement
40
54
  requirements:
41
55
  - - ">="
42
56
  - !ruby/object:Gem::Version
43
- version: 2.2.3
57
+ version: 2.4.0.rc1
44
58
  - - "<"
45
59
  - !ruby/object:Gem::Version
46
- version: 2.4.0
60
+ version: 2.5.0
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: bundler
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -152,6 +166,7 @@ files:
152
166
  - lib/disposable/callback.rb
153
167
  - lib/disposable/composition.rb
154
168
  - lib/disposable/expose.rb
169
+ - lib/disposable/rescheme.rb
155
170
  - lib/disposable/twin.rb
156
171
  - lib/disposable/twin/builder.rb
157
172
  - lib/disposable/twin/changed.rb
@@ -159,12 +174,10 @@ files:
159
174
  - lib/disposable/twin/collection.rb
160
175
  - lib/disposable/twin/composition.rb
161
176
  - lib/disposable/twin/default.rb
162
- - lib/disposable/twin/option.rb
177
+ - lib/disposable/twin/definitions.rb
163
178
  - lib/disposable/twin/persisted.rb
164
179
  - lib/disposable/twin/property_processor.rb
165
- - lib/disposable/twin/representer.rb
166
180
  - lib/disposable/twin/save.rb
167
- - lib/disposable/twin/schema.rb
168
181
  - lib/disposable/twin/setup.rb
169
182
  - lib/disposable/twin/struct.rb
170
183
  - lib/disposable/twin/sync.rb
@@ -175,6 +188,7 @@ files:
175
188
  - test/example.rb
176
189
  - test/expose_test.rb
177
190
  - test/persisted_test.rb
191
+ - test/rescheme_test.rb
178
192
  - test/skip_getter_test.rb
179
193
  - test/test_helper.rb
180
194
  - test/twin/benchmarking.rb
@@ -193,7 +207,6 @@ files:
193
207
  - test/twin/process_inline_test.rb
194
208
  - test/twin/readable_test.rb
195
209
  - test/twin/save_test.rb
196
- - test/twin/schema_test.rb
197
210
  - test/twin/setup_test.rb
198
211
  - test/twin/skip_unchanged_test.rb
199
212
  - test/twin/struct_test.rb
@@ -217,9 +230,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
217
230
  version: '0'
218
231
  required_rubygems_version: !ruby/object:Gem::Requirement
219
232
  requirements:
220
- - - ">="
233
+ - - ">"
221
234
  - !ruby/object:Gem::Version
222
- version: '0'
235
+ version: 1.3.1
223
236
  requirements: []
224
237
  rubyforge_project:
225
238
  rubygems_version: 2.4.8
@@ -234,6 +247,7 @@ test_files:
234
247
  - test/example.rb
235
248
  - test/expose_test.rb
236
249
  - test/persisted_test.rb
250
+ - test/rescheme_test.rb
237
251
  - test/skip_getter_test.rb
238
252
  - test/test_helper.rb
239
253
  - test/twin/benchmarking.rb
@@ -252,7 +266,6 @@ test_files:
252
266
  - test/twin/process_inline_test.rb
253
267
  - test/twin/readable_test.rb
254
268
  - test/twin/save_test.rb
255
- - test/twin/schema_test.rb
256
269
  - test/twin/setup_test.rb
257
270
  - test/twin/skip_unchanged_test.rb
258
271
  - test/twin/struct_test.rb
@@ -1,12 +0,0 @@
1
- module Disposable::Twin::Option
2
- def self.included(base)
3
- base.extend ClassMethods
4
- end
5
-
6
- module ClassMethods
7
- def option(name, options={})
8
- # default: nil will always set an option in the, even when not in the incoming options.
9
- property(name, options.merge(readable: false, writeable: false, default: nil))
10
- end
11
- end
12
- end
@@ -1,57 +0,0 @@
1
- require "representable/decorator"
2
- # require "representable/hash"
3
-
4
- module Disposable
5
- class Twin
6
- class Decorator < Representable::Decorator
7
- # Overrides representable's Definition class so we can add semantics in our representers.
8
- class Definition < Representable::Definition
9
- def dynamic_options
10
- super + [:twin]
11
- end
12
-
13
- def twin_class
14
- self[:twin].evaluate(nil) # FIXME: do we support the :twin option, and should it be wrapped?
15
- end
16
- end
17
-
18
- # FIXME: this is not properly used when inheriting - fix that in representable.
19
- def self.build_config
20
- Config.new(Definition)
21
- end
22
-
23
- def self.each(options={})
24
- return representable_attrs[:definitions].values unless block_given?
25
-
26
- definitions = representable_attrs
27
-
28
- definitions.each do |dfn|
29
- next if options[:exclude] and options[:exclude].include?(dfn.name)
30
- next if options[:scalar] and dfn[:collection]
31
- next if options[:collection] and ! dfn[:collection]
32
- next if options[:twin] and ! dfn[:twin]
33
-
34
- yield dfn
35
- end
36
-
37
- definitions
38
- end
39
-
40
- def self.default_inline_class
41
- Twin
42
- end
43
-
44
-
45
- class Options < ::Hash
46
- def exclude!(names)
47
- excludes.push(*names)
48
- self
49
- end
50
-
51
- def excludes
52
- self[:exclude] ||= []
53
- end
54
- end
55
- end # Decorator.
56
- end
57
- end