declarative 0.0.2 → 0.0.3

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: 778527256a4ef370815476115d8ac7b563f30ec6
4
- data.tar.gz: 630a578c3c0e63c3a390a2147651e1020c249be2
3
+ metadata.gz: 2f743b248235864a196f81afcba519e36856edad
4
+ data.tar.gz: 1c53f46fbefe9d256f7f06d39327413b01f8c2d6
5
5
  SHA512:
6
- metadata.gz: 6759dca249034da2ed5695308e37192a8b5d6f870a1797341617469e8df3de34785853d8b239ef6a233583f1182733719b9ffbc55a52a024fc2edbf6a708057d
7
- data.tar.gz: 4ac48558621fe5afa9c003292559c52dce7c37f105165ceb8a3c6cdeee85344f2f8bcb5f1b9a39f88d49153416a3f25a0a4d521048ab33ce28c708a36e5bfa29
6
+ metadata.gz: 69271f1ac66235fd31c267665a9da238211f7d97518a0b3dc6945f5a2d845048456386d5bf7e4d969d58ad37c26ba7ea7e31eeccbaad361917717179f5f6a81a
7
+ data.tar.gz: eb72aec864a51461c98774eedfa138aefd1591b8b7b7655d6e6d342465f66c37386c5f00f3c085f15bd94f7178d76a31c98f3a1e8da5e17a67f0bd7aa07372e0
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.0.3
2
+
3
+ * Internals, only.
4
+
1
5
  # 0.0.2
2
6
 
3
- * First usable version with `Declarative::Schema` and friends.
7
+ * First usable version with `Declarative::Schema` and friends.
8
+
9
+ TODO: default_nested_class RM
data/README.md CHANGED
@@ -16,6 +16,93 @@ Add this line to your application's Gemfile:
16
16
  gem 'declarative'
17
17
  ```
18
18
 
19
+ ## Declarative::Schema
20
+
21
+ Include this into a class or module to allow defining nested schemas using the popular `::property` DSL.
22
+
23
+ Normally, an abstract base class will define essential configuration.
24
+
25
+ ```ruby
26
+ class Model
27
+ include Declarative::Schema
28
+
29
+ def self.default_nested_class
30
+ Model
31
+ end
32
+ end
33
+ ```
34
+
35
+ Concrete schema-users simply derive from the base class.
36
+
37
+ ```ruby
38
+ class Song < Model
39
+ property :id
40
+
41
+ property :artist do
42
+ property :id
43
+ property :name
44
+ end
45
+ end
46
+ ```
47
+
48
+ This won't do anything but populate the `::definitions` graph.
49
+
50
+ ```ruby
51
+ Song.definitions #=>
52
+
53
+ <Definition "id">
54
+ <Definition "artist" nested=..>
55
+ <Definition "id">
56
+ <Definition "name">
57
+ ```
58
+
59
+ The nested schema will be a subclass of `Model`.
60
+
61
+ ```ruby
62
+ Song.definitions.get(:artist) #=> <Anonymous:Model definitions=..>
63
+ ```
64
+
65
+ ## Overriding Nested Building
66
+
67
+ When declaring nested schemas, per default, Declarative will use its own `Schema::NestedBuilder` to create the nested schema composer.
68
+
69
+ Override `::nested_builder` to define your own way of doing that.
70
+
71
+ ```ruby
72
+ class Model
73
+ include Declarative::Schema
74
+
75
+ def self.default_nested_class
76
+ Model
77
+ end
78
+
79
+ def self.nested_builder
80
+ ->(options) do
81
+ Class.new(Model) do
82
+ class_eval &options[:_block] # executes `property :name` etc. on nested, fresh class.
83
+ end
84
+ end
85
+ end
86
+ end
87
+ ```
88
+
89
+ ## Features
90
+
91
+ You can automatically include modules into all nested schemas by using `::feature`.
92
+
93
+ ```ruby
94
+ class Model
95
+ include Declarative::Schema
96
+ feature Bla
97
+ ```
98
+
99
+ ## Defaults
100
+
101
+ ```ruby
102
+ class Model
103
+ include Declarative::Schema
104
+ defaults visible: true
105
+ ```
19
106
 
20
107
  ## Copyright
21
108
 
@@ -27,6 +27,7 @@ module Declarative
27
27
  # :_features
28
28
  # :_defaults
29
29
  # :_base
30
+ # :_nested_builder
30
31
  def add(name, options={}, &block)
31
32
  options = options[:_defaults].(name, options) if options[:_defaults] # FIXME: pipeline?
32
33
  base = options[:_base]
@@ -36,7 +37,7 @@ module Declarative
36
37
  options = parent_property.options.merge(options) # TODO: Definition#merge
37
38
  end
38
39
 
39
- if block
40
+ if options[:_nested_builder]
40
41
  options[:nested] = build_nested(
41
42
  options.merge(
42
43
  _base: base,
@@ -57,8 +58,9 @@ module Declarative
57
58
  end
58
59
 
59
60
  private
61
+ # Run builder to create nested schema (or twin, or representer, or whatever).
60
62
  def build_nested(options)
61
- nested = options[:_nested_builder].(options)
63
+ options[:_nested_builder].(options)
62
64
  end
63
65
  end
64
66
  end
@@ -7,19 +7,19 @@ module Declarative
7
7
  # ::feature the way we have it in Representable, Reform, and Disposable.
8
8
  #
9
9
  # The schema with its defnitions will be kept in ::definitions.
10
+ #
11
+ # Requirements to includer: ::default_nested_class, override building with ::nested_builder.
10
12
  module Schema
11
13
  module DSL
12
14
  def property(name, options={}, &block)
13
15
  heritage.record(:property, name, options, &block)
14
16
 
15
- options = {
16
- _base: default_nested_class,
17
- }.merge(options)
18
-
19
- options[:_nested_builder] = nested_builder if block
20
- options[:_defaults] = _defaults
17
+ default_options = {}
18
+ default_options[:_base] = default_nested_class
19
+ default_options[:_defaults] = _defaults
20
+ default_options[:_nested_builder] = nested_builder if block
21
21
 
22
- definitions.add(name, options, &block)
22
+ definitions.add(name, default_options.merge(options), &block)
23
23
  end
24
24
 
25
25
  def defaults(options={}, &block)
@@ -42,7 +42,14 @@ module Declarative
42
42
  end
43
43
 
44
44
  def nested_builder
45
- NestedBuilder
45
+ NestedBuilder # default implementation.
46
+ end
47
+
48
+ NestedBuilder = ->(options) do
49
+ base = Class.new(options[:_base]) do
50
+ feature *options[:_features]
51
+ class_eval(&options[:_block])
52
+ end
46
53
  end
47
54
  end
48
55
 
@@ -75,13 +82,5 @@ module Declarative
75
82
  defaults[:_features] << mod
76
83
  end
77
84
  end
78
-
79
-
80
- NestedBuilder = ->(options) do
81
- base = Class.new(options[:_base]) do
82
- feature *options[:_features]
83
- class_eval(&options[:_block])
84
- end
85
- end
86
85
  end
87
86
  end
@@ -1,3 +1,3 @@
1
1
  module Declarative
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -75,4 +75,19 @@ class SchemaTest < Minitest::Spec
75
75
  '.
76
76
  gsub("\n", "").gsub(/\s/, "")
77
77
  end
78
+
79
+
80
+ describe "::property still allows passing internal options" do
81
+ class ConcreteWithOptions < Decorator
82
+ defaults cool: true
83
+
84
+ # you can pass your own _nested_builder and it will still receive correct,
85
+ # defaultized options.
86
+ property :artist, _nested_builder: ->(options) { OpenStruct.new(cool: options[:cool]) }
87
+ end
88
+
89
+ it do
90
+ ConcreteWithOptions.extend(Declarative::Inspect::Schema).inspect.must_equal 'Schema: {"artist"=>#<Declarative::Definitions::Definition: @options={:cool=>true, :nested=>#<OpenStruct cool=true>, :name=>"artist"}>}'
91
+ end
92
+ end
78
93
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: declarative
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
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-10-30 00:00:00.000000000 Z
11
+ date: 2015-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uber