dry-view 0.5.1 → 0.7.1
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 +4 -4
- data/CHANGELOG.md +143 -18
- data/LICENSE +20 -0
- data/README.md +22 -14
- data/dry-view.gemspec +29 -21
- data/lib/dry-view.rb +3 -1
- data/lib/dry/view.rb +514 -2
- data/lib/dry/view/context.rb +80 -0
- data/lib/dry/view/decorated_attributes.rb +82 -0
- data/lib/dry/view/errors.rb +29 -0
- data/lib/dry/view/exposure.rb +35 -14
- data/lib/dry/view/exposures.rb +18 -6
- data/lib/dry/view/part.rb +166 -53
- data/lib/dry/view/part_builder.rb +140 -0
- data/lib/dry/view/path.rb +35 -7
- data/lib/dry/view/render_environment.rb +62 -0
- data/lib/dry/view/render_environment_missing.rb +44 -0
- data/lib/dry/view/rendered.rb +55 -0
- data/lib/dry/view/renderer.rb +36 -29
- data/lib/dry/view/scope.rb +160 -14
- data/lib/dry/view/scope_builder.rb +98 -0
- data/lib/dry/view/tilt.rb +78 -0
- data/lib/dry/view/tilt/erb.rb +26 -0
- data/lib/dry/view/tilt/erbse.rb +21 -0
- data/lib/dry/view/tilt/haml.rb +26 -0
- data/lib/dry/view/version.rb +5 -2
- metadata +78 -115
- data/.gitignore +0 -26
- data/.rspec +0 -2
- data/.travis.yml +0 -23
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -22
- data/LICENSE.md +0 -10
- data/Rakefile +0 -6
- data/benchmarks/templates/button.html.erb +0 -1
- data/benchmarks/view.rb +0 -24
- data/bin/console +0 -7
- data/lib/dry/view/controller.rb +0 -155
- data/lib/dry/view/decorator.rb +0 -45
- data/lib/dry/view/missing_renderer.rb +0 -15
- data/spec/fixtures/templates/_hello.html.slim +0 -1
- data/spec/fixtures/templates/decorated_parts.html.slim +0 -4
- data/spec/fixtures/templates/edit.html.slim +0 -11
- data/spec/fixtures/templates/empty.html.slim +0 -1
- data/spec/fixtures/templates/greeting.html.slim +0 -2
- data/spec/fixtures/templates/hello.html.slim +0 -1
- data/spec/fixtures/templates/layouts/app.html.slim +0 -6
- data/spec/fixtures/templates/layouts/app.txt.erb +0 -3
- data/spec/fixtures/templates/parts_with_args.html.slim +0 -3
- data/spec/fixtures/templates/parts_with_args/_box.html.slim +0 -3
- data/spec/fixtures/templates/shared/_index_table.html.slim +0 -2
- data/spec/fixtures/templates/shared/_shared_hello.html.slim +0 -1
- data/spec/fixtures/templates/tasks.html.slim +0 -3
- data/spec/fixtures/templates/user.html.slim +0 -2
- data/spec/fixtures/templates/users.html.slim +0 -5
- data/spec/fixtures/templates/users.txt.erb +0 -3
- data/spec/fixtures/templates/users/_row.html.slim +0 -2
- data/spec/fixtures/templates/users/_tbody.html.slim +0 -5
- data/spec/fixtures/templates/users_with_count.html.slim +0 -5
- data/spec/fixtures/templates/users_with_count_inherit.html.slim +0 -6
- data/spec/fixtures/templates_override/_hello.html.slim +0 -1
- data/spec/fixtures/templates_override/users.html.slim +0 -5
- data/spec/integration/decorator_spec.rb +0 -80
- data/spec/integration/exposures_spec.rb +0 -392
- data/spec/integration/part/decorated_attributes_spec.rb +0 -157
- data/spec/integration/view_spec.rb +0 -133
- data/spec/spec_helper.rb +0 -46
- data/spec/unit/controller_spec.rb +0 -37
- data/spec/unit/decorator_spec.rb +0 -61
- data/spec/unit/exposure_spec.rb +0 -227
- data/spec/unit/exposures_spec.rb +0 -103
- data/spec/unit/part_spec.rb +0 -90
- data/spec/unit/renderer_spec.rb +0 -57
- data/spec/unit/scope_spec.rb +0 -53
@@ -1,133 +0,0 @@
|
|
1
|
-
RSpec.describe 'dry-view' do
|
2
|
-
let(:vc_class) do
|
3
|
-
Class.new(Dry::View::Controller) do
|
4
|
-
configure do |config|
|
5
|
-
config.paths = SPEC_ROOT.join('fixtures/templates')
|
6
|
-
config.layout = 'app'
|
7
|
-
config.template = 'users'
|
8
|
-
config.default_format = :html
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
let(:context) do
|
14
|
-
Struct.new(:title, :assets).new('dry-view rocks!', -> input { "#{input}.jpg" })
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'renders within a layout and makes the provided context available everywhere' do
|
18
|
-
vc = vc_class.new
|
19
|
-
|
20
|
-
users = [
|
21
|
-
{ name: 'Jane', email: 'jane@doe.org' },
|
22
|
-
{ name: 'Joe', email: 'joe@doe.org' }
|
23
|
-
]
|
24
|
-
|
25
|
-
expect(vc.(context: context, locals: {users: users})).to eql(
|
26
|
-
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><div class="users"><table><tbody><tr><td>Jane</td><td>jane@doe.org</td></tr><tr><td>Joe</td><td>joe@doe.org</td></tr></tbody></table></div><img src="mindblown.jpg" /></body></html>'
|
27
|
-
)
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'renders without a layout' do
|
31
|
-
vc = Class.new(vc_class) do
|
32
|
-
configure do |config|
|
33
|
-
config.layout = false
|
34
|
-
end
|
35
|
-
end.new
|
36
|
-
|
37
|
-
users = [
|
38
|
-
{ name: 'Jane', email: 'jane@doe.org' },
|
39
|
-
{ name: 'Joe', email: 'joe@doe.org' }
|
40
|
-
]
|
41
|
-
|
42
|
-
expect(vc.(context: context, locals: {users: users})).to eql(
|
43
|
-
'<div class="users"><table><tbody><tr><td>Jane</td><td>jane@doe.org</td></tr><tr><td>Joe</td><td>joe@doe.org</td></tr></tbody></table></div><img src="mindblown.jpg" />'
|
44
|
-
)
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'renders a view without locals' do
|
48
|
-
vc = Class.new(vc_class) do
|
49
|
-
configure do |config|
|
50
|
-
config.template = 'empty'
|
51
|
-
end
|
52
|
-
end.new
|
53
|
-
|
54
|
-
expect(vc.(context: context, locals: {})).to eq(
|
55
|
-
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><p>This is a view with no locals.</p></body></html>'
|
56
|
-
)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'renders a view with an alternative format and engine' do
|
60
|
-
vc = vc_class.new
|
61
|
-
|
62
|
-
users = [
|
63
|
-
{ name: 'Jane', email: 'jane@doe.org' },
|
64
|
-
{ name: 'Joe', email: 'joe@doe.org' }
|
65
|
-
]
|
66
|
-
|
67
|
-
expect(vc.(context: context, locals: {users: users}, format: 'txt').strip).to eql(
|
68
|
-
"# dry-view rocks!\n\n* Jane (jane@doe.org)\n* Joe (joe@doe.org)"
|
69
|
-
)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'renders a view with a template on another view path' do
|
73
|
-
vc = Class.new(vc_class) do
|
74
|
-
configure do |config|
|
75
|
-
config.paths = [SPEC_ROOT.join('fixtures/templates_override')] + Array(config.paths)
|
76
|
-
end
|
77
|
-
end.new
|
78
|
-
|
79
|
-
users = [
|
80
|
-
{ name: 'Jane', email: 'jane@doe.org' },
|
81
|
-
{ name: 'Joe', email: 'joe@doe.org' }
|
82
|
-
]
|
83
|
-
|
84
|
-
expect(vc.(context: context, locals: {users: users})).to eq(
|
85
|
-
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><h1>OVERRIDE</h1><div class="users"><table><tbody><tr><td>Jane</td><td>jane@doe.org</td></tr><tr><td>Joe</td><td>joe@doe.org</td></tr></tbody></table></div></body></html>'
|
86
|
-
)
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'renders a view that passes arguments to partials' do
|
90
|
-
vc = Class.new(vc_class) do
|
91
|
-
configure do |config|
|
92
|
-
config.template = 'parts_with_args'
|
93
|
-
end
|
94
|
-
end.new
|
95
|
-
|
96
|
-
users = [
|
97
|
-
{ name: 'Jane', email: 'jane@doe.org' },
|
98
|
-
{ name: 'Joe', email: 'joe@doe.org' }
|
99
|
-
]
|
100
|
-
|
101
|
-
expect(vc.(context: context, locals: {users: users})).to eq(
|
102
|
-
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><div class="users"><div class="box"><h2>Nombre</h2>Jane</div><div class="box"><h2>Nombre</h2>Joe</div></div></body></html>'
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
describe 'inheritance' do
|
107
|
-
let(:parent_view) do
|
108
|
-
klass = Class.new(Dry::View::Controller)
|
109
|
-
|
110
|
-
klass.setting :paths, SPEC_ROOT.join('fixtures/templates')
|
111
|
-
klass.setting :layout, 'app'
|
112
|
-
klass.setting :formats, {html: :slim}
|
113
|
-
|
114
|
-
klass
|
115
|
-
end
|
116
|
-
|
117
|
-
let(:child_view) do
|
118
|
-
Class.new(parent_view) do
|
119
|
-
configure do |config|
|
120
|
-
config.template = 'tasks'
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'renders within a parent class layout using provided context' do
|
126
|
-
vc = child_view.new
|
127
|
-
|
128
|
-
expect(vc.(context: context, locals: { tasks: [{ title: 'one' }, { title: 'two' }] })).to eql(
|
129
|
-
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ol><li>one</li><li>two</li></ol></body></html>'
|
130
|
-
)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
if RUBY_ENGINE == 'ruby'
|
2
|
-
require 'simplecov'
|
3
|
-
SimpleCov.start do
|
4
|
-
add_filter "/spec/"
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
begin
|
9
|
-
require 'pry-byebug'
|
10
|
-
rescue LoadError; end
|
11
|
-
|
12
|
-
SPEC_ROOT = Pathname(__FILE__).dirname
|
13
|
-
|
14
|
-
require 'erb'
|
15
|
-
require 'slim'
|
16
|
-
|
17
|
-
# Prefer plain ERB processor rather than erubis (which has problems on JRuby)
|
18
|
-
require 'tilt'
|
19
|
-
Tilt.register 'erb', Tilt::ERBTemplate
|
20
|
-
|
21
|
-
require 'dry-view'
|
22
|
-
|
23
|
-
module Test
|
24
|
-
def self.remove_constants
|
25
|
-
constants.each(&method(:remove_const))
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
RSpec.configure do |config|
|
30
|
-
config.disable_monkey_patching!
|
31
|
-
|
32
|
-
config.order = :random
|
33
|
-
Kernel.srand config.seed
|
34
|
-
|
35
|
-
config.after do
|
36
|
-
Test.remove_constants
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
RSpec::Matchers.define :part_including do |data|
|
41
|
-
match { |actual|
|
42
|
-
data.all? { |(key, val)|
|
43
|
-
actual._data[key] == val
|
44
|
-
}
|
45
|
-
}
|
46
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::View::Controller do
|
2
|
-
subject(:controller) {
|
3
|
-
Class.new(Dry::View::Controller) do
|
4
|
-
configure do |config|
|
5
|
-
config.paths = SPEC_ROOT.join('fixtures/templates')
|
6
|
-
config.layout = 'app'
|
7
|
-
config.template = 'user'
|
8
|
-
end
|
9
|
-
end.new
|
10
|
-
}
|
11
|
-
|
12
|
-
let(:page) do
|
13
|
-
double(:page, title: 'Test')
|
14
|
-
end
|
15
|
-
|
16
|
-
let(:options) do
|
17
|
-
{ context: page, locals: { user: { name: 'Jane' }, header: { title: 'User' } } }
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#call' do
|
21
|
-
it 'renders template within the layout' do
|
22
|
-
expect(controller.(options)).to eql(
|
23
|
-
'<!DOCTYPE html><html><head><title>Test</title></head><body><h1>User</h1><p>Jane</p></body></html>'
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'provides a meaningful error if the template name is missing' do
|
28
|
-
controller = Class.new(Dry::View::Controller) do
|
29
|
-
configure do |config|
|
30
|
-
config.paths = SPEC_ROOT.join('fixtures/templates')
|
31
|
-
end
|
32
|
-
end.new
|
33
|
-
|
34
|
-
expect { controller.(options) }.to raise_error Dry::View::Controller::UndefinedTemplateError
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/spec/unit/decorator_spec.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::View::Decorator do
|
2
|
-
subject(:decorator) { described_class.new }
|
3
|
-
|
4
|
-
describe '#call' do
|
5
|
-
let(:value) { double('value') }
|
6
|
-
let(:renderer) { double('renderer') }
|
7
|
-
let(:context) { double('context') }
|
8
|
-
let(:options) { {} }
|
9
|
-
|
10
|
-
describe 'returning a part value' do
|
11
|
-
subject(:part) { decorator.('user', value, renderer: renderer, context: context, **options) }
|
12
|
-
|
13
|
-
context 'no options provided' do
|
14
|
-
it 'returns a Part' do
|
15
|
-
expect(part).to be_a Dry::View::Part
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'wraps the value' do
|
19
|
-
expect(part._value).to eq value
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'part class provided via `:as` option' do
|
24
|
-
let(:options) { {as: Test::CustomPart} }
|
25
|
-
|
26
|
-
before do
|
27
|
-
module Test
|
28
|
-
CustomPart = Class.new(Dry::View::Part)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'returns an instance of the provided class' do
|
33
|
-
expect(part).to be_a Test::CustomPart
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'wraps the value' do
|
37
|
-
expect(part._value).to eq value
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'value is an array' do
|
42
|
-
let(:child_a) { double('child a') }
|
43
|
-
let(:child_b) { double('child a') }
|
44
|
-
let(:value) { [child_a, child_b] }
|
45
|
-
|
46
|
-
it 'returns a part wrapping the array' do
|
47
|
-
expect(part).to be_a Dry::View::Part
|
48
|
-
expect(part._value).to be_an Array
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'wraps the elements within the array' do
|
52
|
-
expect(part[0]).to be_a Dry::View::Part
|
53
|
-
expect(part[0]._value).to eq child_a
|
54
|
-
|
55
|
-
expect(part[1]).to be_a Dry::View::Part
|
56
|
-
expect(part[1]._value).to eq child_b
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/spec/unit/exposure_spec.rb
DELETED
@@ -1,227 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::View::Exposure do
|
2
|
-
subject(:exposure) { described_class.new(:hello, proc, object, **options) }
|
3
|
-
|
4
|
-
let(:proc) { -> input { "hi" } }
|
5
|
-
let(:object) { nil }
|
6
|
-
let(:options) { {} }
|
7
|
-
|
8
|
-
describe "initialization and attributes" do
|
9
|
-
describe "#name" do
|
10
|
-
it "accepts a name" do
|
11
|
-
expect(exposure.name).to eql :hello
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "#proc" do
|
16
|
-
it "accepts a proc" do
|
17
|
-
expect(exposure.proc).to eql proc
|
18
|
-
end
|
19
|
-
|
20
|
-
it "allows a nil proc" do
|
21
|
-
expect(described_class.new(:hello).proc).to be_nil
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "#object" do
|
26
|
-
let(:object) { Object.new }
|
27
|
-
|
28
|
-
it "accepts an object" do
|
29
|
-
expect(exposure.object).to eq object
|
30
|
-
end
|
31
|
-
|
32
|
-
it "allows a nil object" do
|
33
|
-
expect(described_class.new(:hello).object).to be_nil
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe "#private?" do
|
38
|
-
it "is false by default" do
|
39
|
-
expect(exposure).not_to be_private
|
40
|
-
end
|
41
|
-
|
42
|
-
it "can be set on initialization" do
|
43
|
-
expect(described_class.new(:hello, private: true)).to be_private
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe "#default_value" do
|
48
|
-
it "is nil by default" do
|
49
|
-
expect(exposure.default_value).to be_nil
|
50
|
-
end
|
51
|
-
|
52
|
-
it "can be set on initialization" do
|
53
|
-
exposuse = described_class.new(:hello, default: 'Hi !')
|
54
|
-
expect(exposuse.default_value).to eq('Hi !')
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "#bind" do
|
60
|
-
subject(:bound_exposure) { exposure.bind(bind_object) }
|
61
|
-
|
62
|
-
let(:bind_object) { Object.new }
|
63
|
-
|
64
|
-
it "returns a new object" do
|
65
|
-
expect(bound_exposure).not_to eql exposure
|
66
|
-
end
|
67
|
-
|
68
|
-
it "retains the bind object" do
|
69
|
-
expect(bound_exposure.object).to eq bind_object
|
70
|
-
end
|
71
|
-
|
72
|
-
context "proc is set" do
|
73
|
-
it "retains the existing proc" do
|
74
|
-
expect(bound_exposure.proc).to eql proc
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context "proc is nil" do
|
79
|
-
let(:proc) { nil }
|
80
|
-
|
81
|
-
context "matching instance method" do
|
82
|
-
let(:bind_object) do
|
83
|
-
Class.new do
|
84
|
-
def hello(input)
|
85
|
-
"hi there, #{input.fetch(:name)}"
|
86
|
-
end
|
87
|
-
end.new
|
88
|
-
end
|
89
|
-
|
90
|
-
it "sets the proc to the method on the object matching the exposure's name" do
|
91
|
-
expect(bound_exposure.proc).to eql bind_object.method(:hello)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
context "no matching instance method" do
|
96
|
-
let(:object) { Object.new }
|
97
|
-
|
98
|
-
it "leaves proc as nil" do
|
99
|
-
expect(bound_exposure.proc).to be_nil
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
describe "#dependency_names" do
|
106
|
-
context "proc provided" do
|
107
|
-
let(:proc) { -> input, foo, bar { "hi" } }
|
108
|
-
|
109
|
-
it "returns an array of exposure dependencies derived from the proc's argument names" do
|
110
|
-
expect(exposure.dependency_names).to eql [:input, :foo, :bar]
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
context "matching instance method" do
|
115
|
-
let(:proc) { nil }
|
116
|
-
|
117
|
-
let(:object) do
|
118
|
-
Class.new do
|
119
|
-
def hello(input, bar, baz)
|
120
|
-
"hi there, #{input.fetch(:name)}"
|
121
|
-
end
|
122
|
-
end.new
|
123
|
-
end
|
124
|
-
|
125
|
-
it "returns an array of exposure dependencies derived from the instance method's argument names" do
|
126
|
-
expect(exposure.dependency_names).to eql [:input, :bar, :baz]
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
context "proc is nil" do
|
131
|
-
let(:proc) { nil }
|
132
|
-
|
133
|
-
it "returns no dependencies" do
|
134
|
-
expect(exposure.dependency_names).to eql []
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
describe "#call" do
|
140
|
-
let(:input) { {name: "Jane"} }
|
141
|
-
|
142
|
-
context "proc expects input only" do
|
143
|
-
let(:proc) { -> name: { name } }
|
144
|
-
|
145
|
-
it "sends the input to the proc" do
|
146
|
-
expect(exposure.(input)).to eql "Jane"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
context "proc expects input and dependencies" do
|
151
|
-
let(:proc) { -> greeting, name: { "#{greeting}, #{name}" } }
|
152
|
-
let(:locals) { {greeting: "Hola"} }
|
153
|
-
|
154
|
-
it "sends the input and dependency values to the proc" do
|
155
|
-
expect(exposure.(input, locals)).to eq "Hola, Jane"
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
context "Default value" do
|
160
|
-
let(:options) { { default: "John" } }
|
161
|
-
|
162
|
-
context "use default value" do
|
163
|
-
let(:proc) { nil }
|
164
|
-
|
165
|
-
it "use the default value" do
|
166
|
-
expect(exposure.({})).to eq "John"
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
context "use input value instead of default" do
|
171
|
-
let(:proc) { nil }
|
172
|
-
|
173
|
-
it "use the default value" do
|
174
|
-
expect(exposure.({hello: "Jane"})).to eq "Jane"
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
context "use input value over default even when input is nil" do
|
179
|
-
let(:proc) { nil }
|
180
|
-
|
181
|
-
it "use the default value" do
|
182
|
-
expect(exposure.({hello: nil})).to eq nil
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
context "proc expects dependencies only" do
|
188
|
-
let(:proc) { -> greeting, farewell { "#{greeting}, #{farewell}" } }
|
189
|
-
let(:locals) { {greeting: "Hola", farewell: "Adios"} }
|
190
|
-
|
191
|
-
it "sends the dependency values to the proc" do
|
192
|
-
expect(exposure.(input, locals)).to eq "Hola, Adios"
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
context "proc accesses object instance" do
|
197
|
-
let(:proc) { -> name: { "My name is #{name} but call me #{title} #{name}" } }
|
198
|
-
|
199
|
-
let(:object) do
|
200
|
-
Class.new do
|
201
|
-
attr_reader :title
|
202
|
-
|
203
|
-
def initialize(title)
|
204
|
-
@title = title
|
205
|
-
end
|
206
|
-
end.new("Dr")
|
207
|
-
end
|
208
|
-
|
209
|
-
it "makes the instance available as self" do
|
210
|
-
expect(exposure.(input)).to eq "My name is Jane but call me Dr Jane"
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
context "no proc" do
|
215
|
-
let(:proc) { nil }
|
216
|
-
let(:input) { {hello: "hi there"} }
|
217
|
-
|
218
|
-
it "returns a matching key from the input" do
|
219
|
-
expect(exposure.(input)).to eq "hi there"
|
220
|
-
end
|
221
|
-
|
222
|
-
it "returns nil when no input key matches" do
|
223
|
-
expect(exposure.(nothing_matches_here: true)).to be_nil
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|