declarative 0.0.6 → 0.0.20

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
- SHA1:
3
- metadata.gz: 9ab032b5544502fa2a01df856e3428cbe833c319
4
- data.tar.gz: 1fa86db96bf352a9c19077e9f873524556d7977f
2
+ SHA256:
3
+ metadata.gz: fc3dccaf0b8fa27ffd73acd1146949c5a79c1f950b72979038f20b34e751a516
4
+ data.tar.gz: f1744ace25a4cc4bb42ce3bb5d45a8ca09a993d8f5f7643e52bc747049674929
5
5
  SHA512:
6
- metadata.gz: 4ec13db2b7873e515bd79ecf88c666cb60ad0236f51f00c154a1fe26cd8a54f524a619821545fc4f543cd2109ff75899ef3abf635393c09fa5fe78a037cb03fd
7
- data.tar.gz: 144864e4b5ea0b6ae8d8429a61b28814ae3764dfa588c64224459c29e99d4f10dc5f944fbb84f1f8026a9ea4ab679d85d91376085d47082b501095eafb1eb30b
6
+ metadata.gz: bac6ff5ad4c34454f3f2212f478299c7c1c22ff94d333149ff73ba93e24792d4b3c33f7cd78f7359fbc3a008c67412abb486b67fd22b22cd1b097f03f2816983
7
+ data.tar.gz: 8544c6eaa0ff5ebe1cefa67e5d003b2c44ad7ba0a353c1c169ef971b8a1dc496f7faaa0db75be987b92d45151a8c0db05babdf0f9d9718052cbb407e5ca8e30c
@@ -1,10 +1,12 @@
1
1
  language: ruby
2
+ before_install: gem install bundler
3
+ cache: bundler
2
4
  rvm:
3
- - 2.2.3
4
- - 2.1.2
5
- - 2.0.0
6
- - 1.9.3
7
- gemfile:
8
- - Gemfile
9
- before_install:
10
- - gem install bundler
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.
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015 Nick Sutterer
1
+ Copyright (c) 2015-2020 Nick Sutterer
2
2
 
3
3
  MIT License
4
4
 
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
- include Declarative::Schema
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>
@@ -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
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
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_dependency "uber", ">= 0.0.15"
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
@@ -4,6 +4,7 @@ require "declarative/heritage"
4
4
  require "declarative/defaults"
5
5
  require "declarative/schema"
6
6
  require "declarative/deep_dup"
7
+ require "declarative/variables"
7
8
 
8
9
  module Declarative
9
10
  end
@@ -1,14 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Declarative
2
- class DeepDup
4
+ module DeepDup
3
5
  def self.call(args)
4
- return Array[*dup_items(args)] if args.is_a?(Array)
5
- return Hash[dup_items(args)] if args.is_a?(Hash)
6
- args
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
@@ -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
- def merge!(hash, &block)
10
- @static_options.merge!(hash) if hash.any?
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
- extend Uber::Delegates
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 = @static_options
21
- options = options.merge(dynamic_options(name, given_options))
22
- options = options.merge(given_options)
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
- private
26
- def dynamic_options(name, given_options)
27
- return {} if @dynamic_options.nil?
28
- @dynamic_options.call(name, given_options)
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={}, &block)
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
@@ -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
@@ -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
- default_options[:_base] = default_nested_class
45
- default_options[:_defaults] = _defaults
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
- base = Class.new(options[:_base]) do
61
- feature *options[:_features]
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[:_features] ||= []
82
- defaults[:_features] << mod
99
+ defaults.merge!( _features: Variables::Append([mod]) )
83
100
  end
84
101
  end
85
102
  end
@@ -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 { |dfn|
34
+ each do |dfn|
23
35
  dfn.extend(Declarative::Inspect)
24
36
 
25
- if dfn[:nested] && dfn[:nested].is_a?(Declarative::Schema::DSL)
37
+ if dfn[:nested]&.is_a?(Declarative::Schema::DSL)
26
38
  dfn[:nested].extend(Declarative::Inspect::Schema)
27
39
  else
28
- dfn[:nested].extend(Declarative::Definitions::Inspect) if 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
@@ -1,3 +1,3 @@
1
1
  module Declarative
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.20"
3
3
  end
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.6
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: 2016-03-21 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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
- - test/defaults_test.rb
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: '0'
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
- rubyforge_project:
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: []
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,5 +0,0 @@
1
- require "declarative"
2
- require "minitest/autorun"
3
- require "pp"
4
-
5
- require "declarative/testing"