dry-view 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -54
- data/LICENSE +20 -0
- data/README.md +19 -36
- data/dry-view.gemspec +24 -15
- data/lib/dry/view.rb +19 -12
- data/lib/dry/view/context.rb +3 -3
- data/lib/dry/view/decorated_attributes.rb +2 -1
- data/lib/dry/view/errors.rb +3 -1
- data/lib/dry/view/exposure.rb +21 -13
- data/lib/dry/view/exposures.rb +5 -3
- data/lib/dry/view/part.rb +15 -6
- data/lib/dry/view/part_builder.rb +8 -4
- data/lib/dry/view/path.rb +1 -1
- data/lib/dry/view/render_environment.rb +4 -4
- data/lib/dry/view/render_environment_missing.rb +4 -4
- data/lib/dry/view/rendered.rb +1 -1
- data/lib/dry/view/renderer.rb +1 -1
- data/lib/dry/view/scope.rb +21 -7
- data/lib/dry/view/scope_builder.rb +4 -4
- data/lib/dry/view/tilt.rb +1 -1
- data/lib/dry/view/tilt/erb.rb +1 -1
- data/lib/dry/view/tilt/erbse.rb +1 -1
- data/lib/dry/view/version.rb +1 -1
- metadata +46 -47
- data/.codeclimate.yml +0 -18
- data/.gitignore +0 -26
- data/.rspec +0 -2
- data/.travis.yml +0 -28
- data/.yardopts +0 -5
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -32
- data/LICENSE.md +0 -10
- data/Rakefile +0 -6
- data/bin/console +0 -7
- data/bin/setup +0 -5
- data/bin/setup_helpers.rb +0 -27
data/lib/dry/view/context.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/equalizer"
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
require_relative "decorated_attributes"
|
5
5
|
|
6
6
|
module Dry
|
@@ -43,7 +43,7 @@ module Dry
|
|
43
43
|
|
44
44
|
# @api private
|
45
45
|
def for_render_env(render_env)
|
46
|
-
return self if render_env ==
|
46
|
+
return self if render_env == _render_env
|
47
47
|
|
48
48
|
self.class.new(**_options.merge(render_env: render_env))
|
49
49
|
end
|
@@ -72,7 +72,7 @@ module Dry
|
|
72
72
|
def with(**new_options)
|
73
73
|
self.class.new(
|
74
74
|
render_env: _render_env,
|
75
|
-
**_options.merge(new_options)
|
75
|
+
**_options.merge(new_options)
|
76
76
|
)
|
77
77
|
end
|
78
78
|
end
|
@@ -27,7 +27,8 @@ module Dry
|
|
27
27
|
#
|
28
28
|
# @param names [Array<Symbol>] the attribute names
|
29
29
|
# @param options [Hash] the options to pass to the Part Builder
|
30
|
-
# @option options [Symbol, Class] :as an alternative name or class to use when finding a
|
30
|
+
# @option options [Symbol, Class] :as an alternative name or class to use when finding a
|
31
|
+
# matching Part
|
31
32
|
#
|
32
33
|
# @api public
|
33
34
|
def decorate(*names, **options)
|
data/lib/dry/view/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
class View
|
3
5
|
# Error raised when critical settings are not configured
|
@@ -17,7 +19,7 @@ module Dry
|
|
17
19
|
def initialize(template_name, lookup_paths)
|
18
20
|
msg = [
|
19
21
|
"Template +#{template_name}+ could not be found in paths:",
|
20
|
-
lookup_paths.map { |path| " - #{path}"}
|
22
|
+
lookup_paths.map { |path| " - #{path}" }
|
21
23
|
].join("\n\n")
|
22
24
|
|
23
25
|
super(msg)
|
data/lib/dry/view/exposure.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
class View
|
@@ -10,8 +10,8 @@ module Dry
|
|
10
10
|
class Exposure
|
11
11
|
include Dry::Equalizer(:name, :proc, :object, :options)
|
12
12
|
|
13
|
-
EXPOSURE_DEPENDENCY_PARAMETER_TYPES = [
|
14
|
-
INPUT_PARAMETER_TYPES = [
|
13
|
+
EXPOSURE_DEPENDENCY_PARAMETER_TYPES = %i[req opt].freeze
|
14
|
+
INPUT_PARAMETER_TYPES = %i[key keyreq keyrest].freeze
|
15
15
|
|
16
16
|
attr_reader :name
|
17
17
|
attr_reader :proc
|
@@ -26,7 +26,7 @@ module Dry
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def bind(obj)
|
29
|
-
self.class.new(name, proc, obj, options)
|
29
|
+
self.class.new(name, proc, obj, **options)
|
30
30
|
end
|
31
31
|
|
32
32
|
def dependency_names
|
@@ -76,23 +76,31 @@ module Dry
|
|
76
76
|
private
|
77
77
|
|
78
78
|
def call_proc(input, locals)
|
79
|
-
args = proc_args(input, locals)
|
80
|
-
|
81
|
-
if
|
82
|
-
proc.(
|
79
|
+
args, keywords = proc_args(input, locals)
|
80
|
+
|
81
|
+
if keywords.empty?
|
82
|
+
if proc.is_a?(Method)
|
83
|
+
proc.(*args)
|
84
|
+
else
|
85
|
+
object.instance_exec(*args, &proc)
|
86
|
+
end
|
83
87
|
else
|
84
|
-
|
88
|
+
if proc.is_a?(Method)
|
89
|
+
proc.(*args, **keywords)
|
90
|
+
else
|
91
|
+
object.instance_exec(*args, **keywords, &proc)
|
92
|
+
end
|
85
93
|
end
|
86
94
|
end
|
87
95
|
|
88
96
|
def proc_args(input, locals)
|
89
97
|
dependency_args = proc_dependency_args(locals)
|
90
|
-
|
98
|
+
keywords = proc_input_args(input)
|
91
99
|
|
92
|
-
if
|
93
|
-
dependency_args
|
100
|
+
if keywords.empty?
|
101
|
+
[dependency_args, {}]
|
94
102
|
else
|
95
|
-
dependency_args
|
103
|
+
[dependency_args, keywords]
|
96
104
|
end
|
97
105
|
end
|
98
106
|
|
data/lib/dry/view/exposures.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "tsort"
|
4
|
-
require "dry/equalizer"
|
4
|
+
require "dry/core/equalizer"
|
5
5
|
require "dry/view/exposure"
|
6
6
|
|
7
7
|
module Dry
|
@@ -30,7 +30,7 @@ module Dry
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def add(name, proc = nil, **options)
|
33
|
-
exposures[name] = Exposure.new(name, proc, options)
|
33
|
+
exposures[name] = Exposure.new(name, proc, **options)
|
34
34
|
end
|
35
35
|
|
36
36
|
def import(name, exposure)
|
@@ -46,8 +46,9 @@ module Dry
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def call(input)
|
49
|
+
# rubocop:disable Style/MultilineBlockChain
|
49
50
|
tsort.each_with_object({}) { |name, memo|
|
50
|
-
next unless exposure = self[name]
|
51
|
+
next unless (exposure = self[name])
|
51
52
|
|
52
53
|
value = exposure.(input, memo)
|
53
54
|
value = yield(value, exposure) if block_given?
|
@@ -56,6 +57,7 @@ module Dry
|
|
56
57
|
}.each_with_object({}) { |(name, value), memo|
|
57
58
|
memo[name] = value unless self[name].private?
|
58
59
|
}
|
60
|
+
# rubocop:enable Style/MultilineBlockChain
|
59
61
|
end
|
60
62
|
|
61
63
|
private
|
data/lib/dry/view/part.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/equalizer"
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
require_relative "decorated_attributes"
|
5
5
|
require_relative "render_environment_missing"
|
6
6
|
|
@@ -70,7 +70,11 @@ module Dry
|
|
70
70
|
# @param render_env [RenderEnvironment] render environment
|
71
71
|
#
|
72
72
|
# @api public
|
73
|
-
def initialize(
|
73
|
+
def initialize(
|
74
|
+
render_env: RenderEnvironmentMissing.new,
|
75
|
+
name: self.class.part_name(render_env.inflector),
|
76
|
+
value:
|
77
|
+
)
|
74
78
|
@_name = name
|
75
79
|
@_value = value
|
76
80
|
@_render_env = render_env
|
@@ -115,15 +119,18 @@ module Dry
|
|
115
119
|
# itself responds to `#render`.
|
116
120
|
#
|
117
121
|
# @param partial_name [Symbol, String] partial name
|
118
|
-
# @param as [Symbol] the name for the Part to assume in the partial's locals.
|
122
|
+
# @param as [Symbol] the name for the Part to assume in the partial's locals. Defaults to
|
123
|
+
# the Part's `_name`.
|
119
124
|
# @param locals [Hash<Symbol, Object>] other locals to provide the partial
|
120
125
|
#
|
121
126
|
# @return [String] rendered partial
|
122
127
|
#
|
123
128
|
# @api public
|
129
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
124
130
|
def _render(partial_name, as: _name, **locals, &block)
|
125
131
|
_render_env.partial(partial_name, _render_env.scope({as => self}.merge(locals)), &block)
|
126
132
|
end
|
133
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
127
134
|
|
128
135
|
# Builds a new scope with the part included in its locals.
|
129
136
|
#
|
@@ -133,7 +140,8 @@ module Dry
|
|
133
140
|
# A convenience alias for `#_scope`. Is available unless the value
|
134
141
|
# itself responds to `#scope`.
|
135
142
|
#
|
136
|
-
# @param scope_name [Symbol, nil] scope name, used by the scope builder to determine the
|
143
|
+
# @param scope_name [Symbol, nil] scope name, used by the scope builder to determine the
|
144
|
+
# scope class
|
137
145
|
# @param locals [Hash<Symbol, Object>] other locals to provide the partial
|
138
146
|
#
|
139
147
|
# @return [Dry::View::Scope] scope
|
@@ -168,12 +176,12 @@ module Dry
|
|
168
176
|
# @param options[Hash<Symbol, Object>] other options to provide when initializing the new part
|
169
177
|
#
|
170
178
|
# @api public
|
171
|
-
def new(klass =
|
179
|
+
def new(klass = self.class, name: _name, value: _value, **options)
|
172
180
|
klass.new(
|
173
181
|
name: name,
|
174
182
|
value: value,
|
175
183
|
render_env: _render_env,
|
176
|
-
**options
|
184
|
+
**options
|
177
185
|
)
|
178
186
|
end
|
179
187
|
|
@@ -199,6 +207,7 @@ module Dry
|
|
199
207
|
super
|
200
208
|
end
|
201
209
|
end
|
210
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
202
211
|
|
203
212
|
def respond_to_missing?(name, include_private = false)
|
204
213
|
CONVENIENCE_METHODS.include?(name) || _value.respond_to?(name, include_private) || super
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "dry/core/cache"
|
4
|
-
require "dry/equalizer"
|
4
|
+
require "dry/core/equalizer"
|
5
5
|
require_relative "part"
|
6
6
|
|
7
7
|
module Dry
|
@@ -54,7 +54,7 @@ module Dry
|
|
54
54
|
klass.new(
|
55
55
|
name: name,
|
56
56
|
value: value,
|
57
|
-
render_env: render_env
|
57
|
+
render_env: render_env
|
58
58
|
)
|
59
59
|
end
|
60
60
|
|
@@ -69,11 +69,13 @@ module Dry
|
|
69
69
|
build_part(name, arr, **options.merge(as: collection_as))
|
70
70
|
end
|
71
71
|
|
72
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
72
73
|
def collection_options(name:, **options)
|
73
74
|
collection_as = options[:as].is_a?(Array) ? options[:as].first : nil
|
74
75
|
|
75
76
|
options.merge(as: collection_as)
|
76
77
|
end
|
78
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
77
79
|
|
78
80
|
def collection_item_options(name:, **options)
|
79
81
|
singular_name = inflector.singularize(name).to_sym
|
@@ -90,7 +92,7 @@ module Dry
|
|
90
92
|
|
91
93
|
options.merge(
|
92
94
|
name: singular_name,
|
93
|
-
as: singular_as
|
95
|
+
as: singular_as
|
94
96
|
)
|
95
97
|
end
|
96
98
|
|
@@ -106,6 +108,7 @@ module Dry
|
|
106
108
|
end
|
107
109
|
end
|
108
110
|
|
111
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
109
112
|
def resolve_part_class(name:, fallback_class:)
|
110
113
|
return fallback_class unless namespace
|
111
114
|
|
@@ -114,7 +117,7 @@ module Dry
|
|
114
117
|
# Give autoloaders a chance to act
|
115
118
|
begin
|
116
119
|
klass = namespace.const_get(name)
|
117
|
-
rescue NameError
|
120
|
+
rescue NameError # rubocop:disable Lint/HandleExceptions
|
118
121
|
end
|
119
122
|
|
120
123
|
if !klass && namespace.const_defined?(name, false)
|
@@ -127,6 +130,7 @@ module Dry
|
|
127
130
|
fallback_class
|
128
131
|
end
|
129
132
|
end
|
133
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
130
134
|
|
131
135
|
def inflector
|
132
136
|
render_env.inflector
|
data/lib/dry/view/path.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/equalizer"
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
class View
|
@@ -12,7 +12,7 @@ module Dry
|
|
12
12
|
inflector: config.inflector,
|
13
13
|
context: context,
|
14
14
|
scope_builder: config.scope_builder.new(namespace: config.scope_namespace),
|
15
|
-
part_builder: config.part_builder.new(namespace: config.part_namespace)
|
15
|
+
part_builder: config.part_builder.new(namespace: config.part_namespace)
|
16
16
|
)
|
17
17
|
end
|
18
18
|
|
@@ -36,7 +36,7 @@ module Dry
|
|
36
36
|
part_builder.(name, value, **options)
|
37
37
|
end
|
38
38
|
|
39
|
-
def scope(name = nil, locals)
|
39
|
+
def scope(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
40
40
|
scope_builder.(name, locals)
|
41
41
|
end
|
42
42
|
|
@@ -54,7 +54,7 @@ module Dry
|
|
54
54
|
inflector: inflector,
|
55
55
|
context: context,
|
56
56
|
scope_builder: scope_builder,
|
57
|
-
part_builder: part_builder
|
57
|
+
part_builder: part_builder
|
58
58
|
)
|
59
59
|
end
|
60
60
|
end
|
@@ -20,19 +20,19 @@ module Dry
|
|
20
20
|
raise MissingEnvironmentError
|
21
21
|
end
|
22
22
|
|
23
|
-
def part(
|
23
|
+
def part(_name, _value, **_options)
|
24
24
|
raise MissingEnvironmentError
|
25
25
|
end
|
26
26
|
|
27
|
-
def scope(
|
27
|
+
def scope(_name = nil, _locals) # rubocop:disable Style/OptionalArguments
|
28
28
|
raise MissingEnvironmentError
|
29
29
|
end
|
30
30
|
|
31
|
-
def template(
|
31
|
+
def template(_name, _scope)
|
32
32
|
raise MissingEnvironmentError
|
33
33
|
end
|
34
34
|
|
35
|
-
def partial(
|
35
|
+
def partial(_name, _scope)
|
36
36
|
raise MissingEnvironmentError
|
37
37
|
end
|
38
38
|
|
data/lib/dry/view/rendered.rb
CHANGED
data/lib/dry/view/renderer.rb
CHANGED
data/lib/dry/view/scope.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/equalizer"
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
require "dry/core/constants"
|
5
5
|
require_relative "render_environment_missing"
|
6
6
|
|
@@ -59,7 +59,11 @@ module Dry
|
|
59
59
|
# @return [Scope]
|
60
60
|
#
|
61
61
|
# @api public
|
62
|
-
def initialize(
|
62
|
+
def initialize(
|
63
|
+
name: nil,
|
64
|
+
locals: Dry::Core::Constants::EMPTY_HASH,
|
65
|
+
render_env: RenderEnvironmentMissing.new
|
66
|
+
)
|
63
67
|
@_name = name
|
64
68
|
@_locals = locals
|
65
69
|
@_render_env = render_env
|
@@ -83,10 +87,16 @@ module Dry
|
|
83
87
|
# @api public
|
84
88
|
def render(partial_name = nil, **locals, &block)
|
85
89
|
partial_name ||= _name
|
86
|
-
raise ArgumentError, "+partial_name+ must be provided for unnamed scopes" unless partial_name
|
87
|
-
partial_name = _inflector.underscore(_inflector.demodulize(partial_name.to_s)) if partial_name.is_a?(Class)
|
88
90
|
|
89
|
-
|
91
|
+
unless partial_name
|
92
|
+
raise ArgumentError, "+partial_name+ must be provided for unnamed scopes"
|
93
|
+
end
|
94
|
+
|
95
|
+
if partial_name.is_a?(Class)
|
96
|
+
partial_name = _inflector.underscore(_inflector.demodulize(partial_name.to_s))
|
97
|
+
end
|
98
|
+
|
99
|
+
_render_env.partial(partial_name, _render_scope(**locals), &block)
|
90
100
|
end
|
91
101
|
|
92
102
|
# Build a new scope using a scope class matching the provided name
|
@@ -150,9 +160,13 @@ module Dry
|
|
150
160
|
super
|
151
161
|
end
|
152
162
|
end
|
163
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
153
164
|
|
154
165
|
def respond_to_missing?(name, include_private = false)
|
155
|
-
_locals.key?(name) ||
|
166
|
+
_locals.key?(name) ||
|
167
|
+
_render_env.context.respond_to?(name) ||
|
168
|
+
CONVENIENCE_METHODS.include?(name) ||
|
169
|
+
super
|
156
170
|
end
|
157
171
|
|
158
172
|
def _render_scope(**locals)
|
@@ -162,7 +176,7 @@ module Dry
|
|
162
176
|
self.class.new(
|
163
177
|
# FIXME: what about `name`?
|
164
178
|
locals: locals,
|
165
|
-
render_env: _render_env
|
179
|
+
render_env: _render_env
|
166
180
|
)
|
167
181
|
end
|
168
182
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "dry/core/cache"
|
4
|
-
require "dry/equalizer"
|
4
|
+
require "dry/core/equalizer"
|
5
5
|
require_relative "scope"
|
6
6
|
|
7
7
|
module Dry
|
@@ -46,11 +46,11 @@ module Dry
|
|
46
46
|
# @return [Dry::View::Scope]
|
47
47
|
#
|
48
48
|
# @api private
|
49
|
-
def call(name = nil, locals)
|
49
|
+
def call(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
50
50
|
scope_class(name).new(
|
51
51
|
name: name,
|
52
52
|
locals: locals,
|
53
|
-
render_env: render_env
|
53
|
+
render_env: render_env
|
54
54
|
)
|
55
55
|
end
|
56
56
|
|
@@ -76,7 +76,7 @@ module Dry
|
|
76
76
|
# Give autoloaders a chance to act
|
77
77
|
begin
|
78
78
|
klass = namespace.const_get(name)
|
79
|
-
rescue NameError
|
79
|
+
rescue NameError # rubocop:disable Lint/HandleExceptions
|
80
80
|
end
|
81
81
|
|
82
82
|
if !klass && namespace.const_defined?(name, false)
|