declarative 0.0.6 → 0.0.20
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 +5 -5
- data/.travis.yml +10 -8
- data/CHANGES.md +28 -0
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/declarative.gemspec +7 -7
- data/lib/declarative.rb +1 -0
- data/lib/declarative/deep_dup.rb +13 -6
- data/lib/declarative/defaults.rb +31 -17
- data/lib/declarative/definitions.rb +4 -4
- data/lib/declarative/heritage.rb +9 -7
- data/lib/declarative/schema.rb +25 -8
- data/lib/declarative/testing.rb +19 -7
- data/lib/declarative/variables.rb +38 -0
- data/lib/declarative/version.rb +1 -1
- metadata +11 -35
- data/test/defaults_test.rb +0 -61
- data/test/definitions_test.rb +0 -102
- data/test/heritage_test.rb +0 -49
- data/test/schema_test.rb +0 -88
- data/test/test_helper.rb +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fc3dccaf0b8fa27ffd73acd1146949c5a79c1f950b72979038f20b34e751a516
|
|
4
|
+
data.tar.gz: f1744ace25a4cc4bb42ce3bb5d45a8ca09a993d8f5f7643e52bc747049674929
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bac6ff5ad4c34454f3f2212f478299c7c1c22ff94d333149ff73ba93e24792d4b3c33f7cd78f7359fbc3a008c67412abb486b67fd22b22cd1b097f03f2816983
|
|
7
|
+
data.tar.gz: 8544c6eaa0ff5ebe1cefa67e5d003b2c44ad7ba0a353c1c169ef971b8a1dc496f7faaa0db75be987b92d45151a8c0db05babdf0f9d9718052cbb407e5ca8e30c
|
data/.travis.yml
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
language: ruby
|
|
2
|
+
before_install: gem install bundler
|
|
3
|
+
cache: bundler
|
|
2
4
|
rvm:
|
|
3
|
-
-
|
|
4
|
-
- 2.
|
|
5
|
-
- 2.
|
|
6
|
-
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
- ruby-head
|
|
6
|
+
- 2.7
|
|
7
|
+
- 2.6
|
|
8
|
+
- 2.5
|
|
9
|
+
- 2.4
|
|
10
|
+
jobs:
|
|
11
|
+
allow_failures:
|
|
12
|
+
- rvm: ruby-head
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
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
|
+
|
|
16
|
+
# 0.0.9
|
|
17
|
+
|
|
18
|
+
* Removing `uber` dependency.
|
|
19
|
+
|
|
20
|
+
# 0.0.8
|
|
21
|
+
|
|
22
|
+
* When calling `Schema#defaults` (or `Defaults#merge!`) multiple times, same-named arrays will be joined instead of overridden. This fixes a common problem when merging different default settings.
|
|
23
|
+
* Remove `Defaults#[]` and `Defaults#[]=`. This now happens via `#merge!`.
|
|
24
|
+
|
|
25
|
+
# 0.0.7
|
|
26
|
+
|
|
27
|
+
* Simplify `Defaults` and remove a warning in Ruby 2.2.3.
|
|
28
|
+
|
|
1
29
|
# 0.0.6
|
|
2
30
|
|
|
3
31
|
* `Heritage#call` now accepts a block that allows processing the arguments for every recorded statement before replaying them. This provides a hook to inject or change parameters, e.g. to mark a replay as an inheritance.
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Normally, an abstract base class will define essential configuration.
|
|
|
24
24
|
|
|
25
25
|
```ruby
|
|
26
26
|
class Model
|
|
27
|
-
|
|
27
|
+
extend Declarative::Schema
|
|
28
28
|
|
|
29
29
|
def self.default_nested_class
|
|
30
30
|
Model
|
|
@@ -106,4 +106,4 @@ class Model
|
|
|
106
106
|
|
|
107
107
|
## Copyright
|
|
108
108
|
|
|
109
|
-
* Copyright (c) 2015 Nick Sutterer <apotonick@gmail.com>
|
|
109
|
+
* Copyright (c) 2015 Nick Sutterer <apotonick@gmail.com>
|
data/declarative.gemspec
CHANGED
|
@@ -9,17 +9,17 @@ 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
|
-
spec.files = `git ls-files -z`.split("\x0")
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
16
|
+
f.match(%r{^(test)/})
|
|
17
|
+
end
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test)/})
|
|
18
19
|
spec.require_paths = ["lib"]
|
|
20
|
+
spec.required_ruby_version = '>= 2.3.0'
|
|
19
21
|
|
|
20
|
-
spec.
|
|
21
|
-
|
|
22
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
|
22
|
+
spec.add_development_dependency "rake"
|
|
23
23
|
spec.add_development_dependency "minitest"
|
|
24
24
|
spec.add_development_dependency "minitest-line"
|
|
25
25
|
end
|
data/lib/declarative.rb
CHANGED
data/lib/declarative/deep_dup.rb
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Declarative
|
|
2
|
-
|
|
4
|
+
module DeepDup
|
|
3
5
|
def self.call(args)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
case args
|
|
7
|
+
when Array
|
|
8
|
+
Array[*dup_items(args)]
|
|
9
|
+
when ::Hash
|
|
10
|
+
::Hash[dup_items(args)]
|
|
11
|
+
else
|
|
12
|
+
args
|
|
13
|
+
|
|
14
|
+
end
|
|
7
15
|
end
|
|
8
16
|
|
|
9
|
-
private
|
|
10
17
|
def self.dup_items(arr)
|
|
11
18
|
arr.to_a.collect { |v| call(v) }
|
|
12
19
|
end
|
|
13
20
|
end
|
|
14
|
-
end
|
|
21
|
+
end
|
data/lib/declarative/defaults.rb
CHANGED
|
@@ -1,31 +1,45 @@
|
|
|
1
|
-
require "uber/delegates"
|
|
2
|
-
|
|
3
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.
|
|
4
4
|
class Defaults
|
|
5
5
|
def initialize
|
|
6
|
-
@static_options
|
|
6
|
+
@static_options = {}
|
|
7
|
+
@dynamic_options = ->(*) { {} }
|
|
7
8
|
end
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
# Set default values. Usually called in Schema::defaults.
|
|
11
|
+
# This can be called multiple times and will "deep-merge" arrays, e.g. `_features: []`.
|
|
12
|
+
def merge!(hash={}, &block)
|
|
13
|
+
@static_options = Variables.merge( @static_options, handle_array_and_deprecate(hash) )
|
|
11
14
|
@dynamic_options = block if block_given?
|
|
15
|
+
|
|
12
16
|
self
|
|
13
17
|
end
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
delegates :@static_options, :[], :[]= # mutuable API!
|
|
17
|
-
|
|
18
|
-
# TODO: allow to receive rest of options/block in dynamic block. or, rather, test it as it was already implemented.
|
|
19
|
+
# Evaluate defaults and merge given_options into them.
|
|
19
20
|
def call(name, given_options)
|
|
20
|
-
options
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
# TODO: allow to receive rest of options/block in dynamic block. or, rather, test it as it was already implemented.
|
|
22
|
+
evaluated_options = @dynamic_options.(name, given_options)
|
|
23
|
+
|
|
24
|
+
options = Variables.merge( @static_options, handle_array_and_deprecate(evaluated_options) )
|
|
25
|
+
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)
|
|
23
34
|
end
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
+
]
|
|
29
43
|
end
|
|
30
44
|
end
|
|
31
|
-
end
|
|
45
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Declarative
|
|
2
|
-
class Definitions < Hash
|
|
2
|
+
class Definitions < ::Hash
|
|
3
3
|
class Definition
|
|
4
|
-
def initialize(name, options={}
|
|
4
|
+
def initialize(name, options={})
|
|
5
5
|
@options = options.dup
|
|
6
6
|
@options[:name] = name.to_s
|
|
7
7
|
end
|
|
@@ -40,7 +40,7 @@ module Declarative
|
|
|
40
40
|
options = options[:_defaults].(name, options) if options[:_defaults] # FIXME: pipeline?
|
|
41
41
|
base = options[:_base]
|
|
42
42
|
|
|
43
|
-
if options.delete(:inherit) and parent_property = get(name)
|
|
43
|
+
if options.delete(:inherit) and (parent_property = get(name))
|
|
44
44
|
base = parent_property[:nested]
|
|
45
45
|
options = parent_property.merge(options) # TODO: Definition#merge
|
|
46
46
|
end
|
|
@@ -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/heritage.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "declarative/deep_dup"
|
|
2
|
+
|
|
1
3
|
module Declarative
|
|
2
4
|
class Heritage < Array
|
|
3
5
|
# Record inheritable assignments for replay in an inheriting class.
|
|
@@ -11,13 +13,6 @@ module Declarative
|
|
|
11
13
|
each { |cfg| call!(inheritor, cfg, &block) }
|
|
12
14
|
end
|
|
13
15
|
|
|
14
|
-
private
|
|
15
|
-
def call!(inheritor, cfg)
|
|
16
|
-
yield cfg if block_given? # allow messing around with recorded arguments.
|
|
17
|
-
|
|
18
|
-
inheritor.send(cfg[:method], *cfg[:args], &cfg[:block])
|
|
19
|
-
end
|
|
20
|
-
|
|
21
16
|
module DSL
|
|
22
17
|
def heritage
|
|
23
18
|
@heritage ||= Heritage.new
|
|
@@ -39,5 +34,12 @@ module Declarative
|
|
|
39
34
|
heritage.(mod)
|
|
40
35
|
end
|
|
41
36
|
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
def call!(inheritor, cfg)
|
|
40
|
+
yield cfg if block_given? # allow messing around with recorded arguments.
|
|
41
|
+
|
|
42
|
+
inheritor.send(cfg[:method], *cfg[:args], &cfg[:block])
|
|
43
|
+
end
|
|
42
44
|
end
|
|
43
45
|
end
|
data/lib/declarative/schema.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
require "declarative"
|
|
2
1
|
require "declarative/definitions"
|
|
3
2
|
require "declarative/defaults"
|
|
3
|
+
require "declarative/variables"
|
|
4
|
+
require "declarative/heritage"
|
|
4
5
|
|
|
5
6
|
module Declarative
|
|
6
7
|
# Include this to maintain inheritable, nested schemas with ::defaults and
|
|
@@ -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
|
|
|
@@ -40,11 +45,14 @@ module Declarative
|
|
|
40
45
|
|
|
41
46
|
private
|
|
42
47
|
def build_definition(name, options={}, &block)
|
|
43
|
-
default_options = {
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
default_options = {
|
|
49
|
+
_base: default_nested_class,
|
|
50
|
+
_defaults: _defaults
|
|
51
|
+
}
|
|
46
52
|
default_options[:_nested_builder] = nested_builder if block
|
|
47
53
|
|
|
54
|
+
# options = options.merge( Defaults.wrap_arrays(options) )
|
|
55
|
+
|
|
48
56
|
definitions.add(name, default_options.merge(options), &block)
|
|
49
57
|
end
|
|
50
58
|
|
|
@@ -57,11 +65,21 @@ module Declarative
|
|
|
57
65
|
end
|
|
58
66
|
|
|
59
67
|
NestedBuilder = ->(options) do
|
|
60
|
-
|
|
61
|
-
feature
|
|
68
|
+
Class.new(options[:_base]) do # base
|
|
69
|
+
feature(*options[:_features])
|
|
62
70
|
class_eval(&options[:_block])
|
|
63
71
|
end
|
|
64
72
|
end
|
|
73
|
+
|
|
74
|
+
# When called, executes `block` and wraps all array values in Variables::Append.
|
|
75
|
+
# This is the default behavior in older versions and allows to provide arrays for
|
|
76
|
+
# default values that will be prepended.
|
|
77
|
+
def wrap_arrays_from_block(block)
|
|
78
|
+
->(*args) {
|
|
79
|
+
options = block.(*args)
|
|
80
|
+
options.merge( Defaults.wrap_arrays( options ) )
|
|
81
|
+
}
|
|
82
|
+
end
|
|
65
83
|
end
|
|
66
84
|
|
|
67
85
|
module Feature
|
|
@@ -78,8 +96,7 @@ module Declarative
|
|
|
78
96
|
def register_feature(mod)
|
|
79
97
|
heritage.record(:register_feature, mod) # this is only for inheritance between decorators and modules!!! ("horizontal and vertical")
|
|
80
98
|
|
|
81
|
-
defaults
|
|
82
|
-
defaults[:_features] << mod
|
|
99
|
+
defaults.merge!( _features: Variables::Append([mod]) )
|
|
83
100
|
end
|
|
84
101
|
end
|
|
85
102
|
end
|
data/lib/declarative/testing.rb
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Declarative
|
|
4
|
+
def self.Inspect(obj)
|
|
5
|
+
string = obj.inspect
|
|
6
|
+
|
|
7
|
+
if obj.is_a?(Proc)
|
|
8
|
+
elements = string.split('/')
|
|
9
|
+
string = "#{elements.first}#{elements.last}"
|
|
10
|
+
end
|
|
11
|
+
string.gsub(/0x\w+/, '')
|
|
12
|
+
end
|
|
13
|
+
|
|
2
14
|
module Inspect
|
|
3
15
|
def inspect
|
|
4
16
|
string = super
|
|
5
17
|
if is_a?(Proc)
|
|
6
|
-
elements = string.split(
|
|
18
|
+
elements = string.split('/')
|
|
7
19
|
string = "#{elements.first}#{elements.last}"
|
|
8
20
|
end
|
|
9
|
-
string.gsub(/0x\w+/,
|
|
21
|
+
string.gsub(/0x\w+/, '')
|
|
10
22
|
end
|
|
11
23
|
|
|
12
24
|
module Schema
|
|
@@ -19,15 +31,15 @@ module Declarative
|
|
|
19
31
|
|
|
20
32
|
module Definitions::Inspect
|
|
21
33
|
def inspect
|
|
22
|
-
each
|
|
34
|
+
each do |dfn|
|
|
23
35
|
dfn.extend(Declarative::Inspect)
|
|
24
36
|
|
|
25
|
-
if dfn[:nested]
|
|
37
|
+
if dfn[:nested]&.is_a?(Declarative::Schema::DSL)
|
|
26
38
|
dfn[:nested].extend(Declarative::Inspect::Schema)
|
|
27
39
|
else
|
|
28
|
-
dfn[:nested]
|
|
40
|
+
dfn[:nested]&.extend(Declarative::Definitions::Inspect)
|
|
29
41
|
end
|
|
30
|
-
|
|
42
|
+
end
|
|
31
43
|
super
|
|
32
44
|
end
|
|
33
45
|
|
|
@@ -35,4 +47,4 @@ module Declarative
|
|
|
35
47
|
super.extend(Declarative::Inspect)
|
|
36
48
|
end
|
|
37
49
|
end
|
|
38
|
-
end
|
|
50
|
+
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
metadata
CHANGED
|
@@ -1,43 +1,29 @@
|
|
|
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.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nick Sutterer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-06-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: uber
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - ">="
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.0.15
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - ">="
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.0.15
|
|
27
13
|
- !ruby/object:Gem::Dependency
|
|
28
14
|
name: rake
|
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
|
30
16
|
requirements:
|
|
31
|
-
- - "
|
|
17
|
+
- - ">="
|
|
32
18
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
19
|
+
version: '0'
|
|
34
20
|
type: :development
|
|
35
21
|
prerelease: false
|
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
23
|
requirements:
|
|
38
|
-
- - "
|
|
24
|
+
- - ">="
|
|
39
25
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
26
|
+
version: '0'
|
|
41
27
|
- !ruby/object:Gem::Dependency
|
|
42
28
|
name: minitest
|
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -88,13 +74,9 @@ files:
|
|
|
88
74
|
- lib/declarative/heritage.rb
|
|
89
75
|
- lib/declarative/schema.rb
|
|
90
76
|
- lib/declarative/testing.rb
|
|
77
|
+
- lib/declarative/variables.rb
|
|
91
78
|
- lib/declarative/version.rb
|
|
92
|
-
|
|
93
|
-
- test/definitions_test.rb
|
|
94
|
-
- test/heritage_test.rb
|
|
95
|
-
- test/schema_test.rb
|
|
96
|
-
- test/test_helper.rb
|
|
97
|
-
homepage: ''
|
|
79
|
+
homepage: https://github.com/apotonick/declarative
|
|
98
80
|
licenses:
|
|
99
81
|
- MIT
|
|
100
82
|
metadata: {}
|
|
@@ -106,21 +88,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
106
88
|
requirements:
|
|
107
89
|
- - ">="
|
|
108
90
|
- !ruby/object:Gem::Version
|
|
109
|
-
version:
|
|
91
|
+
version: 2.3.0
|
|
110
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
93
|
requirements:
|
|
112
94
|
- - ">="
|
|
113
95
|
- !ruby/object:Gem::Version
|
|
114
96
|
version: '0'
|
|
115
97
|
requirements: []
|
|
116
|
-
|
|
117
|
-
rubygems_version: 2.4.8
|
|
98
|
+
rubygems_version: 3.0.3
|
|
118
99
|
signing_key:
|
|
119
100
|
specification_version: 4
|
|
120
101
|
summary: DSL for nested schemas.
|
|
121
|
-
test_files:
|
|
122
|
-
- test/defaults_test.rb
|
|
123
|
-
- test/definitions_test.rb
|
|
124
|
-
- test/heritage_test.rb
|
|
125
|
-
- test/schema_test.rb
|
|
126
|
-
- test/test_helper.rb
|
|
102
|
+
test_files: []
|
data/test/defaults_test.rb
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
require "test_helper"
|
|
2
|
-
|
|
3
|
-
class DefaultsOptionsTest < Minitest::Spec
|
|
4
|
-
let (:song) { Struct.new(:title, :author_name, :song_volume, :description).new("Revolution", "Some author", 20, nil) }
|
|
5
|
-
let (:schema) { Declarative::Definitions.new(Declarative::Definitions::Definition).extend Declarative::Definitions::Inspect }
|
|
6
|
-
let (:defaults) { Declarative::Defaults.new }
|
|
7
|
-
|
|
8
|
-
describe "hash options combined with dynamic options" do
|
|
9
|
-
it do
|
|
10
|
-
defaults.merge!(render_nil: true) do |name|
|
|
11
|
-
{ as: name.to_s.upcase }
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
schema.add :title, _defaults: defaults
|
|
15
|
-
schema.add :author_name
|
|
16
|
-
schema.add :description, _defaults: defaults
|
|
17
|
-
|
|
18
|
-
schema.inspect.must_equal '{"title"=>#<Declarative::Definitions::Definition: @options={:render_nil=>true, :as=>"TITLE", :name=>"title"}>, "author_name"=>#<Declarative::Definitions::Definition: @options={:name=>"author_name"}>, "description"=>#<Declarative::Definitions::Definition: @options={:render_nil=>true, :as=>"DESCRIPTION", :name=>"description"}>}'
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
describe "with only dynamic property options" do
|
|
23
|
-
it do
|
|
24
|
-
defaults.merge!({}) do |name|
|
|
25
|
-
{ as: name.to_s.upcase }
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
schema.add :title, _defaults: defaults
|
|
29
|
-
schema.add :author_name
|
|
30
|
-
schema.add :description, _defaults: defaults
|
|
31
|
-
|
|
32
|
-
schema.inspect.must_equal '{"title"=>#<Declarative::Definitions::Definition: @options={:as=>"TITLE", :name=>"title"}>, "author_name"=>#<Declarative::Definitions::Definition: @options={:name=>"author_name"}>, "description"=>#<Declarative::Definitions::Definition: @options={:as=>"DESCRIPTION", :name=>"description"}>}'
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
describe "with only hashes" do
|
|
37
|
-
it do
|
|
38
|
-
defaults.merge!(render_nil: true)
|
|
39
|
-
|
|
40
|
-
schema.add :title, _defaults: defaults
|
|
41
|
-
schema.add :author_name
|
|
42
|
-
schema.add :description, _defaults: defaults
|
|
43
|
-
|
|
44
|
-
schema.inspect.must_equal '{"title"=>#<Declarative::Definitions::Definition: @options={:render_nil=>true, :name=>"title"}>, "author_name"=>#<Declarative::Definitions::Definition: @options={:name=>"author_name"}>, "description"=>#<Declarative::Definitions::Definition: @options={:render_nil=>true, :name=>"description"}>}'
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
describe "#add options win" do
|
|
49
|
-
it do
|
|
50
|
-
defaults.merge!(render_nil: true) do |name|
|
|
51
|
-
{ as: name.to_s.upcase }
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
schema.add :title, as: "Title", _defaults: defaults
|
|
55
|
-
schema.add :author_name
|
|
56
|
-
schema.add :description, _defaults: defaults
|
|
57
|
-
|
|
58
|
-
schema.inspect.must_equal '{"title"=>#<Declarative::Definitions::Definition: @options={:render_nil=>true, :as=>"Title", :name=>"title"}>, "author_name"=>#<Declarative::Definitions::Definition: @options={:name=>"author_name"}>, "description"=>#<Declarative::Definitions::Definition: @options={:render_nil=>true, :as=>"DESCRIPTION", :name=>"description"}>}'
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
data/test/definitions_test.rb
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
require "test_helper"
|
|
2
|
-
|
|
3
|
-
class DefinitionsTest < Minitest::Spec
|
|
4
|
-
NestedBuilder = ->(options) {
|
|
5
|
-
base = options[:_base] || Declarative::Definitions.new(Declarative::Definitions::Definition)
|
|
6
|
-
base.instance_exec(&options[:_block])
|
|
7
|
-
base
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let (:schema) { Declarative::Definitions.new(Declarative::Definitions::Definition).extend(Declarative::Definitions::Inspect) }
|
|
11
|
-
|
|
12
|
-
it "what" do
|
|
13
|
-
# #add works with name
|
|
14
|
-
schema.add :id
|
|
15
|
-
# get works with symbol
|
|
16
|
-
schema.get(:id).inspect.must_equal '#<Declarative::Definitions::Definition: @options={:name=>"id"}>'
|
|
17
|
-
# get works with string
|
|
18
|
-
schema.get("id").inspect.must_equal '#<Declarative::Definitions::Definition: @options={:name=>"id"}>'
|
|
19
|
-
|
|
20
|
-
# #add with name and options
|
|
21
|
-
schema.add(:id, unique: true)
|
|
22
|
-
schema.get(:id).inspect.must_equal '#<Declarative::Definitions::Definition: @options={:unique=>true, :name=>"id"}>'
|
|
23
|
-
|
|
24
|
-
pp schema
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "overwrites old when called twice" do
|
|
28
|
-
schema.add :id
|
|
29
|
-
schema.add :id, cool: true
|
|
30
|
-
schema.inspect.must_equal '{"id"=>#<Declarative::Definitions::Definition: @options={:cool=>true, :name=>"id"}>}'
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "#add with block" do
|
|
34
|
-
schema.add :artist, _nested_builder: NestedBuilder do
|
|
35
|
-
add :name
|
|
36
|
-
add :band, _nested_builder: NestedBuilder do
|
|
37
|
-
add :location
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
schema.inspect.must_equal '{"artist"=>#<Declarative::Definitions::Definition: @options={:nested=>{"name"=>#<Declarative::Definitions::Definition: @options={:name=>"name"}>, "band"=>#<Declarative::Definitions::Definition: @options={:nested=>{"location"=>#<Declarative::Definitions::Definition: @options={:name=>"location"}>}, :name=>"band"}>}, :name=>"artist"}>}'
|
|
42
|
-
|
|
43
|
-
pp schema
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "#add with :nested instead of block" do
|
|
47
|
-
nested_schema = Declarative::Definitions.new(Declarative::Definitions::Definition)
|
|
48
|
-
nested_schema.extend(Declarative::Definitions::Inspect)
|
|
49
|
-
|
|
50
|
-
nested_schema.add :name
|
|
51
|
-
|
|
52
|
-
schema.add :artist, nested: nested_schema
|
|
53
|
-
|
|
54
|
-
schema.inspect.must_equal '{"artist"=>#<Declarative::Definitions::Definition: @options={:nested=>{"name"=>#<Declarative::Definitions::Definition: @options={:name=>"name"}>}, :name=>"artist"}>}'
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
it "#add with inherit: true and block" do
|
|
59
|
-
schema.add :artist, cool: true, _nested_builder: NestedBuilder do
|
|
60
|
-
add :name
|
|
61
|
-
add :band, crazy: nil, _nested_builder: NestedBuilder do
|
|
62
|
-
add :location
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
schema.add :id, unique: true, value: 1
|
|
67
|
-
|
|
68
|
-
schema.add :artist, uncool: false, _nested_builder: NestedBuilder, inherit: true do
|
|
69
|
-
add :band, normal: false, _nested_builder: NestedBuilder, inherit: true do
|
|
70
|
-
add :genre
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
schema.add :id, unique: false, inherit: true
|
|
75
|
-
|
|
76
|
-
pp schema
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
schema.inspect.must_equal '{"artist"=>#<Declarative::Definitions::Definition: @options={:cool=>true, :nested=>{"name"=>#<Declarative::Definitions::Definition: @options={:name=>"name"}>, "band"=>#<Declarative::Definitions::Definition: @options={:crazy=>nil, :nested=>{"location"=>#<Declarative::Definitions::Definition: @options={:name=>"location"}>, "genre"=>#<Declarative::Definitions::Definition: @options={:name=>"genre"}>}, :name=>"band", :normal=>false}>}, :name=>"artist", :uncool=>false}>, "id"=>#<Declarative::Definitions::Definition: @options={:unique=>false, :value=>1, :name=>"id"}>}'
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it "#add with nested options followed by inherit: true" do
|
|
83
|
-
schema.add :id, deserializer: options = { render: false }
|
|
84
|
-
schema.add :id, inherit: true
|
|
85
|
-
|
|
86
|
-
schema.get(:id)[:deserializer][:parse] = true
|
|
87
|
-
|
|
88
|
-
options.must_equal(render: false)
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
class DefinitionTest < Minitest::Spec
|
|
94
|
-
let (:definition) { Declarative::Definitions::Definition.new(:name) }
|
|
95
|
-
|
|
96
|
-
it "#merge does return deep copy" do
|
|
97
|
-
options = { render: false }
|
|
98
|
-
merged = definition.merge(options)
|
|
99
|
-
definition.merge!(render: true)
|
|
100
|
-
merged.must_equal(:name=>"name", render: false)
|
|
101
|
-
end
|
|
102
|
-
end
|
data/test/heritage_test.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
require "test_helper"
|
|
2
|
-
|
|
3
|
-
class HeritageTest < Minitest::Spec
|
|
4
|
-
P = Proc.new{}.extend(Declarative::Inspect)
|
|
5
|
-
# #record
|
|
6
|
-
module RepresenterA
|
|
7
|
-
extend Declarative::Heritage::DSL
|
|
8
|
-
|
|
9
|
-
# one arg.
|
|
10
|
-
heritage.record(:representation_wrap=, true)
|
|
11
|
-
# 2 args.
|
|
12
|
-
heritage.record(:property, :name, enable: true)
|
|
13
|
-
# 3 args.
|
|
14
|
-
heritage.record(:property, :id, {}, &P)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it { RepresenterA.heritage.inspect.must_equal "[{:method=>:representation_wrap=, :args=>[true], :block=>nil}, {:method=>:property, :args=>[:name, {:enable=>true}], :block=>nil}, {:method=>:property, :args=>[:id, {}], :block=>#<Proc:@heritage_test.rb:4>}]" }
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
describe "dup of arguments" do
|
|
21
|
-
module B
|
|
22
|
-
extend Declarative::Heritage::DSL
|
|
23
|
-
|
|
24
|
-
options = {render: true, nested: {render: false}}
|
|
25
|
-
|
|
26
|
-
heritage.record(:property, :name, options, &P)
|
|
27
|
-
|
|
28
|
-
options[:parse] = true
|
|
29
|
-
options[:nested][:parse] = false
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it { B.heritage.inspect.must_equal "[{:method=>:property, :args=>[:name, {:render=>true, :nested=>{:render=>false}}], :block=>#<Proc:@heritage_test.rb:4>}]" }
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
describe "#call with block" do
|
|
36
|
-
let (:heritage) { Declarative::Heritage.new.record(:property, :id, {}) }
|
|
37
|
-
|
|
38
|
-
class CallWithBlock
|
|
39
|
-
def self.property(name, options)
|
|
40
|
-
@args = [name, options]
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it do
|
|
45
|
-
heritage.(CallWithBlock) { |cfg| cfg[:args].last.merge!(_inherited: true) }
|
|
46
|
-
CallWithBlock.instance_variable_get(:@args).must_equal [:id, {:_inherited=>true}]
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
data/test/schema_test.rb
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
require "test_helper"
|
|
2
|
-
|
|
3
|
-
class SchemaTest < Minitest::Spec
|
|
4
|
-
class Decorator
|
|
5
|
-
extend Declarative::Schema
|
|
6
|
-
|
|
7
|
-
def self.default_nested_class
|
|
8
|
-
Decorator
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
module AddLinks
|
|
13
|
-
def self.included(includer)
|
|
14
|
-
super
|
|
15
|
-
includer.property(:links)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
class Concrete < Decorator
|
|
20
|
-
defaults render_nil: true do |name|
|
|
21
|
-
{ as: name.to_s.upcase }
|
|
22
|
-
end
|
|
23
|
-
feature AddLinks
|
|
24
|
-
|
|
25
|
-
property :artist, cool: true do
|
|
26
|
-
property :name
|
|
27
|
-
property :band, crazy: nil do
|
|
28
|
-
property :location
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
property :id, unique: true, value: 1
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
it do
|
|
37
|
-
Concrete.extend(Declarative::Inspect::Schema)
|
|
38
|
-
Concrete.inspect
|
|
39
|
-
Concrete.inspect.gsub(/\s/, "").must_equal 'Schema:{
|
|
40
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"LINKS",:name=>"links"}>,
|
|
41
|
-
"artist"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"ARTIST",:cool=>true,:nested=>Schema:{
|
|
42
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:name=>"links"}>,
|
|
43
|
-
"name"=>#<Declarative::Definitions::Definition:@options={:name=>"name"}>,
|
|
44
|
-
"band"=>#<Declarative::Definitions::Definition:@options={:crazy=>nil,:nested=>Schema:{
|
|
45
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:name=>"links"}>,
|
|
46
|
-
"location"=>#<Declarative::Definitions::Definition:@options={:name=>"location"}>},:name=>"band"}>},:name=>"artist"}>,
|
|
47
|
-
"id"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"ID",:unique=>true,:value=>1,:name=>"id"}>}'.
|
|
48
|
-
gsub("\n", "").gsub(/\s/, "")
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
class InheritingConcrete < Concrete
|
|
52
|
-
property :uuid
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
it do
|
|
57
|
-
InheritingConcrete.extend(Declarative::Inspect::Schema)
|
|
58
|
-
InheritingConcrete.inspect
|
|
59
|
-
# pp InheritingConcrete.definitions.get(:artist)[:nested].definitions.get(:band)[:nested].definitions
|
|
60
|
-
InheritingConcrete.inspect.gsub(/\s/, "").must_equal 'Schema:{
|
|
61
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"LINKS",:name=>"links"}>,
|
|
62
|
-
"artist"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"ARTIST",:cool=>true,:nested=>Schema:{
|
|
63
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:name=>"links"}>,
|
|
64
|
-
"name"=>#<Declarative::Definitions::Definition:@options={:name=>"name"}>,
|
|
65
|
-
"band"=>#<Declarative::Definitions::Definition:@options={:crazy=>nil,:nested=>Schema:{
|
|
66
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:name=>"links"}>,
|
|
67
|
-
"location"=>#<Declarative::Definitions::Definition:@options={:name=>"location"}>},:name=>"band"}>},:name=>"artist"}>,
|
|
68
|
-
"id"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"ID",:unique=>true,:value=>1,:name=>"id"}>,
|
|
69
|
-
"uuid"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"UUID",:name=>"uuid"}>}
|
|
70
|
-
'.
|
|
71
|
-
gsub("\n", "").gsub(/\s/, "")
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
describe "::property still allows passing internal options" do
|
|
76
|
-
class ConcreteWithOptions < Decorator
|
|
77
|
-
defaults cool: true
|
|
78
|
-
|
|
79
|
-
# you can pass your own _nested_builder and it will still receive correct,
|
|
80
|
-
# defaultized options.
|
|
81
|
-
property :artist, _nested_builder: ->(options) { OpenStruct.new(cool: options[:cool]) }
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it do
|
|
85
|
-
ConcreteWithOptions.extend(Declarative::Inspect::Schema).inspect.must_equal 'Schema: {"artist"=>#<Declarative::Definitions::Definition: @options={:cool=>true, :nested=>#<OpenStruct cool=true>, :name=>"artist"}>}'
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|