declarative 0.0.9 → 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 -6
- data/CHANGES.md +15 -0
- data/LICENSE.txt +1 -1
- data/declarative.gemspec +7 -5
- data/lib/declarative/deep_dup.rb +13 -6
- data/lib/declarative/defaults.rb +22 -19
- data/lib/declarative/definitions.rb +4 -4
- data/lib/declarative/heritage.rb +7 -7
- data/lib/declarative/schema.rb +22 -4
- data/lib/declarative/testing.rb +19 -7
- data/lib/declarative/variables.rb +38 -0
- data/lib/declarative/version.rb +1 -1
- data/lib/declarative.rb +1 -0
- metadata +11 -21
- data/test/defaults_test.rb +0 -88
- data/test/definitions_test.rb +0 -95
- data/test/heritage_test.rb +0 -49
- data/test/schema_test.rb +0 -115
- data/test/test_helper.rb +0 -4
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,8 +1,12 @@
|
|
1
1
|
language: ruby
|
2
|
+
before_install: gem install bundler
|
3
|
+
cache: bundler
|
2
4
|
rvm:
|
3
|
-
-
|
4
|
-
-
|
5
|
-
|
6
|
-
-
|
7
|
-
|
8
|
-
|
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,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/LICENSE.txt
CHANGED
data/declarative.gemspec
CHANGED
@@ -9,15 +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.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "rake"
|
21
23
|
spec.add_development_dependency "minitest"
|
22
24
|
spec.add_development_dependency "minitest-line"
|
23
25
|
end
|
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,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
|
-
|
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)
|
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,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
@@ -13,13 +13,6 @@ module Declarative
|
|
13
13
|
each { |cfg| call!(inheritor, cfg, &block) }
|
14
14
|
end
|
15
15
|
|
16
|
-
private
|
17
|
-
def call!(inheritor, cfg)
|
18
|
-
yield cfg if block_given? # allow messing around with recorded arguments.
|
19
|
-
|
20
|
-
inheritor.send(cfg[:method], *cfg[:args], &cfg[:block])
|
21
|
-
end
|
22
|
-
|
23
16
|
module DSL
|
24
17
|
def heritage
|
25
18
|
@heritage ||= Heritage.new
|
@@ -41,5 +34,12 @@ module Declarative
|
|
41
34
|
heritage.(mod)
|
42
35
|
end
|
43
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
|
44
44
|
end
|
45
45
|
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
|
|
@@ -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
|
|
@@ -62,6 +70,16 @@ module Declarative
|
|
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,7 +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.merge!(_features: [mod])
|
99
|
+
defaults.merge!( _features: Variables::Append([mod]) )
|
82
100
|
end
|
83
101
|
end
|
84
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
data/lib/declarative.rb
CHANGED
metadata
CHANGED
@@ -1,29 +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
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,13 +74,9 @@ 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/definitions_test.rb
|
80
|
-
- test/heritage_test.rb
|
81
|
-
- test/schema_test.rb
|
82
|
-
- test/test_helper.rb
|
83
|
-
homepage: ''
|
79
|
+
homepage: https://github.com/apotonick/declarative
|
84
80
|
licenses:
|
85
81
|
- MIT
|
86
82
|
metadata: {}
|
@@ -92,21 +88,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
88
|
requirements:
|
93
89
|
- - ">="
|
94
90
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
91
|
+
version: 2.3.0
|
96
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
93
|
requirements:
|
98
94
|
- - ">="
|
99
95
|
- !ruby/object:Gem::Version
|
100
96
|
version: '0'
|
101
97
|
requirements: []
|
102
|
-
|
103
|
-
rubygems_version: 2.6.3
|
98
|
+
rubygems_version: 3.0.3
|
104
99
|
signing_key:
|
105
100
|
specification_version: 4
|
106
101
|
summary: DSL for nested schemas.
|
107
|
-
test_files:
|
108
|
-
- test/defaults_test.rb
|
109
|
-
- test/definitions_test.rb
|
110
|
-
- test/heritage_test.rb
|
111
|
-
- test/schema_test.rb
|
112
|
-
- test/test_helper.rb
|
102
|
+
test_files: []
|
data/test/defaults_test.rb
DELETED
@@ -1,88 +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
|
-
|
62
|
-
|
63
|
-
describe "multiple Defaults#merge!" do
|
64
|
-
it "merges arrays automatically" do
|
65
|
-
defaults.merge!(a: 1, b: 2)
|
66
|
-
defaults.merge!( b: 3, _features: ["A"])
|
67
|
-
defaults.merge!( _features: ["B", "C"])
|
68
|
-
defaults.(nil, {}).inspect.must_equal "{:a=>1, :b=>3, :_features=>[\"A\", \"B\", \"C\"]}"
|
69
|
-
end
|
70
|
-
|
71
|
-
it "what" do
|
72
|
-
defaults.merge!(_features: ["A"]) do |name, options|
|
73
|
-
{ _features: ["B", "D"] }
|
74
|
-
end
|
75
|
-
|
76
|
-
defaults.(nil, {}).inspect.must_equal "{:_features=>[\"A\", \"B\", \"D\"]}"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
class DefaultsMergeTest < Minitest::Spec
|
82
|
-
it do
|
83
|
-
a = { a: "a", features: ["b"] }
|
84
|
-
b = { a: "a", features: ["c", "d"], b: "b" }
|
85
|
-
|
86
|
-
Declarative::Defaults::Merge.(a, b).must_equal({:a=>"a", :features=>["b", "c", "d"], :b=>"b"})
|
87
|
-
end
|
88
|
-
end
|
data/test/definitions_test.rb
DELETED
@@ -1,95 +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
|
-
end
|
24
|
-
|
25
|
-
it "overwrites old when called twice" do
|
26
|
-
schema.add :id
|
27
|
-
schema.add :id, cool: true
|
28
|
-
schema.inspect.must_equal '{"id"=>#<Declarative::Definitions::Definition: @options={:cool=>true, :name=>"id"}>}'
|
29
|
-
end
|
30
|
-
|
31
|
-
it "#add with block" do
|
32
|
-
schema.add :artist, _nested_builder: NestedBuilder do
|
33
|
-
add :name
|
34
|
-
add :band, _nested_builder: NestedBuilder do
|
35
|
-
add :location
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
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"}>}'
|
40
|
-
end
|
41
|
-
|
42
|
-
it "#add with :nested instead of block" do
|
43
|
-
nested_schema = Declarative::Definitions.new(Declarative::Definitions::Definition)
|
44
|
-
nested_schema.extend(Declarative::Definitions::Inspect)
|
45
|
-
|
46
|
-
nested_schema.add :name
|
47
|
-
|
48
|
-
schema.add :artist, nested: nested_schema
|
49
|
-
|
50
|
-
schema.inspect.must_equal '{"artist"=>#<Declarative::Definitions::Definition: @options={:nested=>{"name"=>#<Declarative::Definitions::Definition: @options={:name=>"name"}>}, :name=>"artist"}>}'
|
51
|
-
end
|
52
|
-
|
53
|
-
|
54
|
-
it "#add with inherit: true and block" do
|
55
|
-
schema.add :artist, cool: true, _nested_builder: NestedBuilder do
|
56
|
-
add :name
|
57
|
-
add :band, crazy: nil, _nested_builder: NestedBuilder do
|
58
|
-
add :location
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
schema.add :id, unique: true, value: 1
|
63
|
-
|
64
|
-
schema.add :artist, uncool: false, _nested_builder: NestedBuilder, inherit: true do
|
65
|
-
add :band, normal: false, _nested_builder: NestedBuilder, inherit: true do
|
66
|
-
add :genre
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
schema.add :id, unique: false, inherit: true
|
71
|
-
|
72
|
-
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"}>}'
|
73
|
-
end
|
74
|
-
|
75
|
-
it "#add with nested options followed by inherit: true" do
|
76
|
-
schema.add :id, deserializer: options = { render: false }
|
77
|
-
schema.add :id, inherit: true
|
78
|
-
|
79
|
-
schema.get(:id)[:deserializer][:parse] = true
|
80
|
-
|
81
|
-
options.must_equal(render: false)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
class DefinitionTest < Minitest::Spec
|
87
|
-
let (:definition) { Declarative::Definitions::Definition.new(:name) }
|
88
|
-
|
89
|
-
it "#merge does return deep copy" do
|
90
|
-
options = { render: false }
|
91
|
-
merged = definition.merge(options)
|
92
|
-
definition.merge!(render: true)
|
93
|
-
merged.must_equal(:name=>"name", render: false)
|
94
|
-
end
|
95
|
-
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,115 +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
|
-
InheritingConcrete.inspect.gsub(/\s/, "").must_equal 'Schema:{
|
60
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"LINKS",:name=>"links"}>,
|
61
|
-
"artist"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"ARTIST",:cool=>true,:nested=>Schema:{
|
62
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:name=>"links"}>,
|
63
|
-
"name"=>#<Declarative::Definitions::Definition:@options={:name=>"name"}>,
|
64
|
-
"band"=>#<Declarative::Definitions::Definition:@options={:crazy=>nil,:nested=>Schema:{
|
65
|
-
"links"=>#<Declarative::Definitions::Definition:@options={:name=>"links"}>,
|
66
|
-
"location"=>#<Declarative::Definitions::Definition:@options={:name=>"location"}>},:name=>"band"}>},:name=>"artist"}>,
|
67
|
-
"id"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"ID",:unique=>true,:value=>1,:name=>"id"}>,
|
68
|
-
"uuid"=>#<Declarative::Definitions::Definition:@options={:render_nil=>true,:as=>"UUID",:name=>"uuid"}>}
|
69
|
-
'.
|
70
|
-
gsub("\n", "").gsub(/\s/, "")
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
describe "::property still allows passing internal options" do
|
75
|
-
class ConcreteWithOptions < Decorator
|
76
|
-
defaults cool: true
|
77
|
-
|
78
|
-
# you can pass your own _nested_builder and it will still receive correct,
|
79
|
-
# defaultized options.
|
80
|
-
property :artist, _nested_builder: ->(options) { OpenStruct.new(cool: options[:cool]) }
|
81
|
-
end
|
82
|
-
|
83
|
-
it do
|
84
|
-
ConcreteWithOptions.extend(Declarative::Inspect::Schema).inspect.must_equal 'Schema: {"artist"=>#<Declarative::Definitions::Definition: @options={:cool=>true, :nested=>#<OpenStruct cool=true>, :name=>"artist"}>}'
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe "multiple ::defaults" do
|
89
|
-
class Twin < Decorator
|
90
|
-
module A; end
|
91
|
-
module B; end
|
92
|
-
module D; end
|
93
|
-
|
94
|
-
defaults a: "a", _features: [A] do |name|
|
95
|
-
{ first: 1, _features: [D] }
|
96
|
-
end
|
97
|
-
|
98
|
-
# DISCUSS: currently, we only allow one dynamic block.
|
99
|
-
defaults b: "b", _features: [B]# do |name, options|
|
100
|
-
# {}
|
101
|
-
#end
|
102
|
-
|
103
|
-
|
104
|
-
property :id do end
|
105
|
-
end
|
106
|
-
|
107
|
-
it do
|
108
|
-
Twin.extend(Declarative::Inspect::Schema).inspect.must_equal 'Schema: {"id"=>#<Declarative::Definitions::Definition: @options={:a=>"a", :b=>"b", :first=>1, :nested=>Schema: {}, :name=>"id"}>}'
|
109
|
-
# :_features get merged.
|
110
|
-
Twin.definitions.get(:id)[:nested].is_a? Twin::A
|
111
|
-
Twin.definitions.get(:id)[:nested].is_a? Twin::B
|
112
|
-
Twin.definitions.get(:id)[:nested].is_a? Twin::D
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
data/test/test_helper.rb
DELETED