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 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"