declarative 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +15 -0
- data/declarative.gemspec +1 -1
- data/lib/declarative.rb +1 -0
- data/lib/declarative/deep_dup.rb +2 -2
- data/lib/declarative/defaults.rb +22 -19
- data/lib/declarative/definitions.rb +2 -2
- data/lib/declarative/schema.rb +18 -1
- data/lib/declarative/testing.rb +11 -1
- data/lib/declarative/variables.rb +38 -0
- data/lib/declarative/version.rb +1 -1
- data/test/defaults_test.rb +21 -10
- data/test/variables_test.rb +65 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e5c86877c99e99dfa9ce880df46435218fcc7a0
|
4
|
+
data.tar.gz: e4b808d37b26399bade9158a92040fb882a3c840
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92ec08dc8dcbe1939a657112edc880b977f16e5b786722a0af007f895399d28d9370415f3db81c2c71e5f270f5be6eeaa10d6b0bcf654f64683113ebe76d639a
|
7
|
+
data.tar.gz: e56d957d4b9b29695b861a7e3852cd66aac31f8f3fe0a01dfa343e054a38f6b4c98aa39dcce5f6e61157ac9a055a6d7cee1730ba8f804d003283db611ef280c1
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# 0.0.10
|
2
|
+
|
3
|
+
* `Defaults.merge!` will now deprecate non-wrapped `Array` values. The following code is no longer valid (but still works).
|
4
|
+
|
5
|
+
defaults.merge!( list: [1,2] )
|
6
|
+
|
7
|
+
Instead, you need to wrap it in a command like `Variables::Append`.
|
8
|
+
|
9
|
+
defaults.merge!( list: Declarative::Variables::Append( [1,2] ) )
|
10
|
+
|
11
|
+
The reason for this change is to allow all kinds of operations with defaults variables, such as merges, overrides, append, prepend, and so on.
|
12
|
+
|
13
|
+
* Introduce `Declarative::Variables.merge` to merge two sets of variables.
|
14
|
+
* `Defaults` now uses `Variables` for merge/overide operations.
|
15
|
+
|
1
16
|
# 0.0.9
|
2
17
|
|
3
18
|
* Removing `uber` dependency.
|
data/declarative.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.email = ["apotonick@gmail.com"]
|
10
10
|
spec.summary = %q{DSL for nested schemas.}
|
11
11
|
spec.description = %q{DSL for nested generic schemas with inheritance and refining.}
|
12
|
-
spec.homepage = ""
|
12
|
+
spec.homepage = "https://github.com/apotonick/declarative"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
data/lib/declarative.rb
CHANGED
data/lib/declarative/deep_dup.rb
CHANGED
@@ -2,7 +2,7 @@ module Declarative
|
|
2
2
|
class DeepDup
|
3
3
|
def self.call(args)
|
4
4
|
return Array[*dup_items(args)] if args.is_a?(Array)
|
5
|
-
return Hash[dup_items(args)] if args.is_a?(Hash)
|
5
|
+
return ::Hash[dup_items(args)] if args.is_a?(::Hash)
|
6
6
|
args
|
7
7
|
end
|
8
8
|
|
@@ -11,4 +11,4 @@ module Declarative
|
|
11
11
|
arr.to_a.collect { |v| call(v) }
|
12
12
|
end
|
13
13
|
end
|
14
|
-
end
|
14
|
+
end
|
data/lib/declarative/defaults.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
module Declarative
|
2
|
+
# {Defaults} is a mutable DSL object that collects default directives via #merge!.
|
3
|
+
# Internally, it uses {Variables} to implement the merging of defaults.
|
2
4
|
class Defaults
|
3
5
|
def initialize
|
4
6
|
@static_options = {}
|
5
|
-
@dynamic_options = ->(*) {
|
7
|
+
@dynamic_options = ->(*) { {} }
|
6
8
|
end
|
7
9
|
|
8
10
|
# Set default values. Usually called in Schema::defaults.
|
9
11
|
# This can be called multiple times and will "deep-merge" arrays, e.g. `_features: []`.
|
10
12
|
def merge!(hash={}, &block)
|
11
|
-
@static_options
|
12
|
-
|
13
|
+
@static_options = Variables.merge( @static_options, handle_array_and_deprecate(hash) )
|
13
14
|
@dynamic_options = block if block_given?
|
15
|
+
|
14
16
|
self
|
15
17
|
end
|
16
18
|
|
@@ -19,24 +21,25 @@ module Declarative
|
|
19
21
|
# TODO: allow to receive rest of options/block in dynamic block. or, rather, test it as it was already implemented.
|
20
22
|
evaluated_options = @dynamic_options.(name, given_options)
|
21
23
|
|
22
|
-
options =
|
23
|
-
options =
|
24
|
+
options = Variables.merge( @static_options, handle_array_and_deprecate(evaluated_options) )
|
25
|
+
options = Variables.merge( options, handle_array_and_deprecate(given_options) ) # FIXME: given_options is not tested!
|
26
|
+
end
|
27
|
+
|
28
|
+
def handle_array_and_deprecate(variables)
|
29
|
+
wrapped = Defaults.wrap_arrays(variables)
|
30
|
+
|
31
|
+
warn "[Declarative] Defaults#merge! and #call still accept arrays and automatically prepend those. This is now deprecated, you should replace `ary` with `Declarative::Variables::Append(ary)`." if wrapped.any?
|
32
|
+
|
33
|
+
variables.merge(wrapped)
|
24
34
|
end
|
25
35
|
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
a[k] = v and next unless a.has_key?(k)
|
34
|
-
a[k] = v and next unless a[k].is_a?(Array)
|
35
|
-
a[k] = a[k] += v # only for arrays.
|
36
|
-
end
|
37
|
-
|
38
|
-
a
|
39
|
-
end
|
36
|
+
# Wrap arrays in `variables` with Variables::Append so they get appended to existing
|
37
|
+
# same-named arrays.
|
38
|
+
def self.wrap_arrays(variables)
|
39
|
+
Hash[ variables.
|
40
|
+
find_all { |k,v| v.instance_of?(Array) }.
|
41
|
+
collect { |k,v| [k, Variables::Append(v)] }
|
42
|
+
]
|
40
43
|
end
|
41
44
|
end
|
42
45
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Declarative
|
2
|
-
class Definitions < Hash
|
2
|
+
class Definitions < ::Hash
|
3
3
|
class Definition
|
4
4
|
def initialize(name, options={}, &block)
|
5
5
|
@options = options.dup
|
@@ -71,4 +71,4 @@ module Declarative
|
|
71
71
|
options[:_nested_builder].(options)
|
72
72
|
end
|
73
73
|
end
|
74
|
-
end
|
74
|
+
end
|
data/lib/declarative/schema.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "declarative/definitions"
|
2
2
|
require "declarative/defaults"
|
3
|
+
require "declarative/variables"
|
3
4
|
require "declarative/heritage"
|
4
5
|
|
5
6
|
module Declarative
|
@@ -27,6 +28,10 @@ module Declarative
|
|
27
28
|
def defaults(options={}, &block)
|
28
29
|
heritage.record(:defaults, options, &block)
|
29
30
|
|
31
|
+
# Always convert arrays to Variables::Append instructions.
|
32
|
+
options = options.merge( Defaults.wrap_arrays(options) )
|
33
|
+
block = wrap_arrays_from_block(block) if block_given?
|
34
|
+
|
30
35
|
_defaults.merge!(options, &block)
|
31
36
|
end
|
32
37
|
|
@@ -45,6 +50,8 @@ module Declarative
|
|
45
50
|
default_options[:_defaults] = _defaults
|
46
51
|
default_options[:_nested_builder] = nested_builder if block
|
47
52
|
|
53
|
+
# options = options.merge( Defaults.wrap_arrays(options) )
|
54
|
+
|
48
55
|
definitions.add(name, default_options.merge(options), &block)
|
49
56
|
end
|
50
57
|
|
@@ -62,6 +69,16 @@ module Declarative
|
|
62
69
|
class_eval(&options[:_block])
|
63
70
|
end
|
64
71
|
end
|
72
|
+
|
73
|
+
# When called, executes `block` and wraps all array values in Variables::Append.
|
74
|
+
# This is the default behavior in older versions and allows to provide arrays for
|
75
|
+
# default values that will be prepended.
|
76
|
+
def wrap_arrays_from_block(block)
|
77
|
+
->(*args) {
|
78
|
+
options = block.(*args)
|
79
|
+
options.merge( Defaults.wrap_arrays( options ) )
|
80
|
+
}
|
81
|
+
end
|
65
82
|
end
|
66
83
|
|
67
84
|
module Feature
|
@@ -78,7 +95,7 @@ module Declarative
|
|
78
95
|
def register_feature(mod)
|
79
96
|
heritage.record(:register_feature, mod) # this is only for inheritance between decorators and modules!!! ("horizontal and vertical")
|
80
97
|
|
81
|
-
defaults.merge!(_features: [mod])
|
98
|
+
defaults.merge!( _features: Variables::Append([mod]) )
|
82
99
|
end
|
83
100
|
end
|
84
101
|
end
|
data/lib/declarative/testing.rb
CHANGED
@@ -1,4 +1,14 @@
|
|
1
1
|
module Declarative
|
2
|
+
def self.Inspect(obj)
|
3
|
+
string = obj.inspect
|
4
|
+
|
5
|
+
if obj.is_a?(Proc)
|
6
|
+
elements = string.split("/")
|
7
|
+
string = "#{elements.first}#{elements.last}"
|
8
|
+
end
|
9
|
+
string.gsub(/0x\w+/, "")
|
10
|
+
end
|
11
|
+
|
2
12
|
module Inspect
|
3
13
|
def inspect
|
4
14
|
string = super
|
@@ -35,4 +45,4 @@ module Declarative
|
|
35
45
|
super.extend(Declarative::Inspect)
|
36
46
|
end
|
37
47
|
end
|
38
|
-
end
|
48
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Declarative
|
2
|
+
# Implements the pattern of maintaining a hash of key/values (usually "defaults")
|
3
|
+
# that are mutated several times by user and library code (override defaults).
|
4
|
+
#
|
5
|
+
# The Variables instance then represents the configuration data to be processed by the
|
6
|
+
# using library (e.g. Representable or Trailblazer).
|
7
|
+
class Variables
|
8
|
+
class Proc < ::Proc
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return Hash hash where `overrides` is merged onto `defaults` respecting Merge, Append etc.
|
12
|
+
def self.merge(defaults, overrides)
|
13
|
+
defaults = defaults.merge({}) # todo: use our DeepDup. # TODO: or how could we provide immutability?
|
14
|
+
|
15
|
+
overrides.each do |k, v|
|
16
|
+
if v.is_a?(Variables::Proc)
|
17
|
+
defaults[k] = v.( defaults[k] )
|
18
|
+
else
|
19
|
+
defaults[k] = v
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
defaults
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.Merge(merged_hash)
|
27
|
+
Variables::Proc.new do |original|
|
28
|
+
(original || {}).merge( merged_hash )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.Append(appended_array)
|
33
|
+
Variables::Proc.new do |original|
|
34
|
+
(original || []) + appended_array
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end # Variables
|
38
|
+
end
|
data/lib/declarative/version.rb
CHANGED
data/test/defaults_test.rb
CHANGED
@@ -63,26 +63,37 @@ class DefaultsOptionsTest < Minitest::Spec
|
|
63
63
|
describe "multiple Defaults#merge!" do
|
64
64
|
it "merges arrays automatically" do
|
65
65
|
defaults.merge!(a: 1, b: 2)
|
66
|
-
defaults.merge!( b: 3, _features: ["A"])
|
67
|
-
defaults.merge!( _features: ["B", "C"])
|
66
|
+
defaults.merge!( b: 3, _features: Declarative::Variables::Append(["A"]) )
|
67
|
+
defaults.merge!( _features: Declarative::Variables::Append(["B", "C"]) )
|
68
68
|
defaults.(nil, {}).inspect.must_equal "{:a=>1, :b=>3, :_features=>[\"A\", \"B\", \"C\"]}"
|
69
69
|
end
|
70
70
|
|
71
71
|
it "what" do
|
72
|
-
defaults.merge!(_features: ["A"]) do |name, options|
|
73
|
-
{ _features: ["B", "D"] }
|
72
|
+
defaults.merge!( _features: Declarative::Variables::Append(["A"]) ) do |name, options|
|
73
|
+
{ _features: Declarative::Variables::Append( ["B", "D"] ) }
|
74
74
|
end
|
75
75
|
|
76
76
|
defaults.(nil, {}).inspect.must_equal "{:_features=>[\"A\", \"B\", \"D\"]}"
|
77
77
|
end
|
78
78
|
end
|
79
|
-
end
|
80
79
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
describe "deprecation" do
|
81
|
+
require 'stringio'
|
82
|
+
before do
|
83
|
+
@old_stderr = $stderr
|
84
|
+
$stderr = StringIO.new
|
85
|
+
end
|
86
|
+
|
87
|
+
after { $stderr = @old_stderr }
|
88
|
+
|
89
|
+
it "prints deprecation twice" do
|
90
|
+
defaults.merge!( _features: ["A"] ) do |name, options|
|
91
|
+
{ _features: ["B", "D"] }
|
92
|
+
end
|
85
93
|
|
86
|
-
|
94
|
+
defaults.(nil, {}).inspect.must_equal "{:_features=>[\"A\", \"B\", \"D\"]}"
|
95
|
+
|
96
|
+
$stderr.string.must_equal %{[Declarative] Defaults#merge! and #call still accept arrays and automatically prepend those. This is now deprecated, you should replace `ary` with `Declarative::Variables::Append(ary)`.\n}*2
|
97
|
+
end
|
87
98
|
end
|
88
99
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class DSLOptionsTest < Minitest::Spec
|
4
|
+
let(:defaults) { { id: 1, connections: { first: 1, second: 2 }, list: [3] } }
|
5
|
+
|
6
|
+
Variables = Declarative::Variables
|
7
|
+
|
8
|
+
after do
|
9
|
+
Declarative::Inspect(defaults).must_equal %{{:id=>1, :connections=>{:first=>1, :second=>2}, :list=>[3]}}
|
10
|
+
end
|
11
|
+
|
12
|
+
#- Merge
|
13
|
+
it "merges Merge over original" do
|
14
|
+
options = Variables.merge(
|
15
|
+
defaults,
|
16
|
+
connections: Variables::Merge( second: 3, third: 4 )
|
17
|
+
)
|
18
|
+
|
19
|
+
options.must_equal( { id: 1, connections: { first: 1, second: 3, third: 4 }, :list=>[3] } )
|
20
|
+
end
|
21
|
+
|
22
|
+
it "accepts Procs" do
|
23
|
+
options = Variables.merge(
|
24
|
+
defaults,
|
25
|
+
connections: proc = ->(*) { raise }
|
26
|
+
)
|
27
|
+
|
28
|
+
options.must_equal( { id: 1, connections: proc, :list=>[3] } )
|
29
|
+
end
|
30
|
+
|
31
|
+
it "overrides original without Merge" do
|
32
|
+
options = Variables.merge(
|
33
|
+
defaults, connections: { second: 3, third: 4 } )
|
34
|
+
|
35
|
+
options.must_equal( { id: 1, connections: { second: 3, third: 4 }, :list=>[3] } )
|
36
|
+
end
|
37
|
+
|
38
|
+
it "creates new hash if original not existent" do
|
39
|
+
options = Variables.merge(
|
40
|
+
defaults,
|
41
|
+
bla: Variables::Merge( second: 3, third: 4 )
|
42
|
+
)
|
43
|
+
|
44
|
+
options.must_equal( {:id=>1, :connections=>{:first=>1, :second=>2}, :list=>[3], :bla=>{:second=>3, :third=>4}} )
|
45
|
+
end
|
46
|
+
|
47
|
+
#- Append
|
48
|
+
it "appends to Array" do
|
49
|
+
options = Variables.merge(
|
50
|
+
defaults,
|
51
|
+
list: Variables::Append( [3, 4, 5] )
|
52
|
+
)
|
53
|
+
|
54
|
+
options.must_equal( { id: 1, connections: { first: 1, second: 2 }, :list=>[3, 3, 4, 5] } )
|
55
|
+
end
|
56
|
+
|
57
|
+
it "creates new array if original not existent" do
|
58
|
+
options = Variables.merge(
|
59
|
+
defaults,
|
60
|
+
another_list: Variables::Append( [3, 4, 5] )
|
61
|
+
)
|
62
|
+
|
63
|
+
options.must_equal( { id: 1, connections: { first: 1, second: 2 }, :list=>[3], :another_list=>[3, 4, 5] } )
|
64
|
+
end
|
65
|
+
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.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -74,13 +74,15 @@ files:
|
|
74
74
|
- lib/declarative/heritage.rb
|
75
75
|
- lib/declarative/schema.rb
|
76
76
|
- lib/declarative/testing.rb
|
77
|
+
- lib/declarative/variables.rb
|
77
78
|
- lib/declarative/version.rb
|
78
79
|
- test/defaults_test.rb
|
79
80
|
- test/definitions_test.rb
|
80
81
|
- test/heritage_test.rb
|
81
82
|
- test/schema_test.rb
|
82
83
|
- test/test_helper.rb
|
83
|
-
|
84
|
+
- test/variables_test.rb
|
85
|
+
homepage: https://github.com/apotonick/declarative
|
84
86
|
licenses:
|
85
87
|
- MIT
|
86
88
|
metadata: {}
|
@@ -100,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
102
|
version: '0'
|
101
103
|
requirements: []
|
102
104
|
rubyforge_project:
|
103
|
-
rubygems_version: 2.6.
|
105
|
+
rubygems_version: 2.6.8
|
104
106
|
signing_key:
|
105
107
|
specification_version: 4
|
106
108
|
summary: DSL for nested schemas.
|
@@ -110,3 +112,4 @@ test_files:
|
|
110
112
|
- test/heritage_test.rb
|
111
113
|
- test/schema_test.rb
|
112
114
|
- test/test_helper.rb
|
115
|
+
- test/variables_test.rb
|