dry-view 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +15 -11
  3. data/CHANGELOG.md +23 -0
  4. data/Gemfile +6 -5
  5. data/README.md +8 -1
  6. data/benchmarks/templates/{button.erb → button.html.erb} +0 -0
  7. data/benchmarks/view.rb +3 -4
  8. data/bin/console +7 -0
  9. data/dry-view.gemspec +7 -6
  10. data/lib/dry/view/controller.rb +107 -0
  11. data/lib/dry/view/exposure.rb +61 -0
  12. data/lib/dry/view/exposures.rb +50 -0
  13. data/lib/dry/view/path.rb +40 -0
  14. data/lib/dry/view/renderer.rb +20 -28
  15. data/lib/dry/view/scope.rb +55 -0
  16. data/lib/dry/view/version.rb +1 -1
  17. data/lib/dry/view.rb +1 -1
  18. data/spec/fixtures/templates/empty.html.slim +1 -0
  19. data/spec/fixtures/templates/layouts/app.html.slim +1 -1
  20. data/spec/fixtures/templates/layouts/app.txt.erb +1 -1
  21. data/spec/fixtures/templates/parts_with_args/_box.html.slim +3 -0
  22. data/spec/fixtures/templates/parts_with_args.html.slim +3 -0
  23. data/spec/fixtures/templates/users/_tbody.html.slim +1 -1
  24. data/spec/fixtures/templates/users.html.slim +4 -4
  25. data/spec/fixtures/templates/users.txt.erb +0 -2
  26. data/spec/fixtures/templates/users_with_count.html.slim +5 -0
  27. data/spec/fixtures/templates_override/users.html.slim +5 -0
  28. data/spec/integration/exposures_spec.rb +178 -0
  29. data/spec/integration/view_spec.rb +83 -20
  30. data/spec/spec_helper.rb +13 -3
  31. data/spec/unit/controller_spec.rb +36 -0
  32. data/spec/unit/exposure_spec.rb +146 -0
  33. data/spec/unit/exposures_spec.rb +63 -0
  34. data/spec/unit/renderer_spec.rb +2 -1
  35. data/spec/unit/scope_spec.rb +98 -0
  36. metadata +36 -46
  37. data/lib/dry/view/layout.rb +0 -126
  38. data/lib/dry/view/null_part.rb +0 -30
  39. data/lib/dry/view/part.rb +0 -39
  40. data/lib/dry/view/value_part.rb +0 -50
  41. data/spec/unit/layout_spec.rb +0 -55
  42. data/spec/unit/null_part_spec.rb +0 -39
  43. data/spec/unit/value_part_spec.rb +0 -55
@@ -0,0 +1,178 @@
1
+ RSpec.describe 'exposures' do
2
+ let(:context) { Struct.new(:title, :assets).new('dry-view rocks!', -> input { "#{input}.jpg" }) }
3
+
4
+ it 'uses exposures to build view locals' do
5
+ vc = Class.new(Dry::View::Controller) do
6
+ configure do |config|
7
+ config.paths = SPEC_ROOT.join('fixtures/templates')
8
+ config.layout = 'app'
9
+ config.template = 'users'
10
+ config.default_format = :html
11
+ end
12
+
13
+ expose :users do |input|
14
+ input.fetch(:users).map { |user|
15
+ user.merge(name: user[:name].upcase)
16
+ }
17
+ end
18
+ end.new
19
+
20
+ users = [
21
+ { name: 'Jane', email: 'jane@doe.org' },
22
+ { name: 'Joe', email: 'joe@doe.org' }
23
+ ]
24
+
25
+ expect(vc.(users: users, context: context)).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 'supports both blocks and instance methods as exposures' do
31
+ vc = Class.new(Dry::View::Controller) do
32
+ configure do |config|
33
+ config.paths = SPEC_ROOT.join('fixtures/templates')
34
+ config.layout = 'app'
35
+ config.template = 'users'
36
+ config.default_format = :html
37
+ end
38
+
39
+ expose :users
40
+
41
+ private
42
+
43
+ def users(input)
44
+ input.fetch(:users).map { |user|
45
+ user.merge(name: user[:name].upcase)
46
+ }
47
+ end
48
+ end.new
49
+
50
+ users = [
51
+ { name: 'Jane', email: 'jane@doe.org' },
52
+ { name: 'Joe', email: 'joe@doe.org' }
53
+ ]
54
+
55
+ expect(vc.(users: users, context: context)).to eql(
56
+ '<!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>'
57
+ )
58
+ end
59
+
60
+ it 'passes matching input data if no proc or instance method is available' do
61
+ vc = Class.new(Dry::View::Controller) do
62
+ configure do |config|
63
+ config.paths = SPEC_ROOT.join('fixtures/templates')
64
+ config.layout = 'app'
65
+ config.template = 'users'
66
+ config.default_format = :html
67
+ end
68
+
69
+ expose :users
70
+ end.new
71
+
72
+ users = [
73
+ { name: 'Jane', email: 'jane@doe.org' },
74
+ { name: 'Joe', email: 'joe@doe.org' }
75
+ ]
76
+
77
+ expect(vc.(users: users, context: context)).to eql(
78
+ '<!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>'
79
+ )
80
+ end
81
+
82
+ it 'allows exposures to depend on each other' do
83
+ vc = Class.new(Dry::View::Controller) do
84
+ configure do |config|
85
+ config.paths = SPEC_ROOT.join('fixtures/templates')
86
+ config.layout = 'app'
87
+ config.template = 'users_with_count'
88
+ config.default_format = :html
89
+ end
90
+
91
+ expose :users do |input|
92
+ input.fetch(:users)
93
+ end
94
+
95
+ expose :users_count do |users|
96
+ "#{users.length} users"
97
+ end
98
+ end.new
99
+
100
+ users = [
101
+ {name: 'Jane', email: 'jane@doe.org'},
102
+ {name: 'Joe', email: 'joe@doe.org'}
103
+ ]
104
+
105
+ expect(vc.(users: users, context: context)).to eql(
106
+ '<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ul><li>Jane (jane@doe.org)</li><li>Joe (joe@doe.org)</li></ul><div class="count">2 users</div></body></html>'
107
+ )
108
+ end
109
+
110
+ it 'supports defining multiple exposures at once' do
111
+ vc = Class.new(Dry::View::Controller) do
112
+ configure do |config|
113
+ config.paths = SPEC_ROOT.join('fixtures/templates')
114
+ config.layout = 'app'
115
+ config.template = 'users_with_count'
116
+ config.default_format = :html
117
+ end
118
+
119
+ expose :users, :users_count
120
+
121
+ private
122
+
123
+ def users(input)
124
+ input.fetch(:users)
125
+ end
126
+
127
+ def users_count(users)
128
+ "#{users.length} users"
129
+ end
130
+ end.new
131
+
132
+ users = [
133
+ {name: 'Jane', email: 'jane@doe.org'},
134
+ {name: 'Joe', email: 'joe@doe.org'}
135
+ ]
136
+
137
+ expect(vc.(users: users, context: context)).to eql(
138
+ '<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ul><li>Jane (jane@doe.org)</li><li>Joe (joe@doe.org)</li></ul><div class="count">2 users</div></body></html>'
139
+ )
140
+ end
141
+
142
+ it 'allows exposures to be hidden from the view' do
143
+ vc = Class.new(Dry::View::Controller) do
144
+ configure do |config|
145
+ config.paths = SPEC_ROOT.join('fixtures/templates')
146
+ config.layout = 'app'
147
+ config.template = 'users_with_count'
148
+ config.default_format = :html
149
+ end
150
+
151
+ private_expose :prefix do
152
+ "COUNT: "
153
+ end
154
+
155
+ expose :users do |input|
156
+ input.fetch(:users)
157
+ end
158
+
159
+ expose :users_count do |prefix, users|
160
+ "#{prefix}#{users.length} users"
161
+ end
162
+ end.new
163
+
164
+ users = [
165
+ {name: 'Jane', email: 'jane@doe.org'},
166
+ {name: 'Joe', email: 'joe@doe.org'}
167
+ ]
168
+
169
+ input = {users: users, context: context}
170
+
171
+ expect(vc.(input)).to eql(
172
+ '<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ul><li>Jane (jane@doe.org)</li><li>Joe (joe@doe.org)</li></ul><div class="count">COUNT: 2 users</div></body></html>'
173
+ )
174
+
175
+ expect(vc.locals(input)).to include(:users, :users_count)
176
+ expect(vc.locals(input)).not_to include(:prefix)
177
+ end
178
+ end
@@ -1,51 +1,114 @@
1
1
  RSpec.describe 'dry-view' do
2
- let(:view_class) do
3
- Class.new(Dry::View::Layout) do
2
+ let(:vc_class) do
3
+ Class.new(Dry::View::Controller) do
4
4
  configure do |config|
5
- config.root = SPEC_ROOT.join('fixtures/templates')
6
- config.name = 'app'
5
+ config.paths = SPEC_ROOT.join('fixtures/templates')
6
+ config.layout = 'app'
7
7
  config.template = 'users'
8
- config.formats = {html: :slim, txt: :erb}
8
+ config.default_format = :html
9
9
  end
10
10
  end
11
11
  end
12
12
 
13
- let(:scope) do
14
- Struct.new(:title).new('dry-view rocks!')
13
+ let(:context) do
14
+ Struct.new(:title, :assets).new('dry-view rocks!', -> input { "#{input}.jpg" })
15
15
  end
16
16
 
17
- it 'renders within a layout using provided scope' do
18
- view = view_class.new
17
+ it 'renders within a layout and makes the provided context available everywhere' do
18
+ vc = vc_class.new
19
19
 
20
20
  users = [
21
21
  { name: 'Jane', email: 'jane@doe.org' },
22
22
  { name: 'Joe', email: 'joe@doe.org' }
23
23
  ]
24
24
 
25
- expect(view.(scope: scope, locals: { subtitle: "Users List", users: users })).to eql(
26
- '<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><h2>Users List</h2><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>'
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>'
27
56
  )
28
57
  end
29
58
 
30
59
  it 'renders a view with an alternative format and engine' do
31
- view = view_class.new
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
32
95
 
33
96
  users = [
34
97
  { name: 'Jane', email: 'jane@doe.org' },
35
98
  { name: 'Joe', email: 'joe@doe.org' }
36
99
  ]
37
100
 
38
- expect(view.(scope: scope, locals: { subtitle: 'Users List', users: users }, format: 'txt').strip).to eql(
39
- "# dry-view rocks!\n\n## Users List\n\n* Jane (jane@doe.org)\n* Joe (joe@doe.org)"
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>'
40
103
  )
41
104
  end
42
105
 
43
106
  describe 'inheritance' do
44
107
  let(:parent_view) do
45
- klass = Class.new(Dry::View::Layout)
108
+ klass = Class.new(Dry::View::Controller)
46
109
 
47
- klass.setting :root, SPEC_ROOT.join('fixtures/templates')
48
- klass.setting :name, 'app'
110
+ klass.setting :paths, SPEC_ROOT.join('fixtures/templates')
111
+ klass.setting :layout, 'app'
49
112
  klass.setting :formats, {html: :slim}
50
113
 
51
114
  klass
@@ -59,10 +122,10 @@ RSpec.describe 'dry-view' do
59
122
  end
60
123
  end
61
124
 
62
- it 'renders within a parent class layout using provided scope' do
63
- view = child_view.new
125
+ it 'renders within a parent class layout using provided context' do
126
+ vc = child_view.new
64
127
 
65
- expect(view.(scope: scope, locals: { tasks: [{ title: 'one' }, { title: 'two' }] })).to eql(
128
+ expect(vc.(context: context, locals: { tasks: [{ title: 'one' }, { title: 'two' }] })).to eql(
66
129
  '<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ol><li>one</li><li>two</li></ol></body></html>'
67
130
  )
68
131
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
- if RUBY_ENGINE == "rbx"
2
- require "codeclimate-test-reporter"
3
- CodeClimate::TestReporter.start
1
+ if RUBY_ENGINE == 'ruby'
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "/spec/"
5
+ end
4
6
  end
5
7
 
6
8
  begin
@@ -24,3 +26,11 @@ RSpec.configure do |config|
24
26
  config.order = :random
25
27
  Kernel.srand config.seed
26
28
  end
29
+
30
+ RSpec::Matchers.define :part_including do |data|
31
+ match { |actual|
32
+ data.all? { |(key, val)|
33
+ actual._data[key] == val
34
+ }
35
+ }
36
+ end
@@ -0,0 +1,36 @@
1
+ RSpec.describe Dry::View::Controller do
2
+ subject(:layout) { layout_class.new }
3
+
4
+ let(:layout_class) do
5
+ klass = Class.new(Dry::View::Controller)
6
+
7
+ klass.configure do |config|
8
+ config.paths = SPEC_ROOT.join('fixtures/templates')
9
+ config.layout = 'app'
10
+ config.template = 'user'
11
+ config.default_format = :html
12
+ end
13
+
14
+ klass
15
+ end
16
+
17
+ let(:page) do
18
+ double(:page, title: 'Test')
19
+ end
20
+
21
+ let(:options) do
22
+ { context: page, locals: { user: { name: 'Jane' }, header: { title: 'User' } } }
23
+ end
24
+
25
+ let(:renderer) do
26
+ layout.class.renderers[:html]
27
+ end
28
+
29
+ describe '#call' do
30
+ it 'renders template within the layout' do
31
+ expect(layout.(options)).to eql(
32
+ '<!DOCTYPE html><html><head><title>Test</title></head><body><h1>User</h1><p>Jane</p></body></html>'
33
+ )
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,146 @@
1
+ RSpec.describe Dry::View::Exposure do
2
+ subject(:exposure) { described_class.new(:hello, proc) }
3
+
4
+ let(:proc) { -> input { "hi" } }
5
+
6
+ describe "initialization and attributes" do
7
+ describe "#name" do
8
+ it "accepts a name" do
9
+ expect(exposure.name).to eql :hello
10
+ end
11
+ end
12
+
13
+ describe "#proc" do
14
+ it "accepts a proc" do
15
+ expect(exposure.proc).to eql proc
16
+ end
17
+
18
+ it "allows a nil proc" do
19
+ expect(described_class.new(:hello).proc).to be_nil
20
+ end
21
+
22
+ it "allows proc to take no arguments" do
23
+ proc = -> { "hi" }
24
+ expect { described_class.new(:hello, proc) }.not_to raise_error
25
+ end
26
+
27
+ it "requires proc to take positional arguments only" do
28
+ proc = -> a: "a" { "hi" }
29
+ expect { described_class.new(:hello, proc) }.to raise_error ArgumentError
30
+
31
+ proc = -> input, a: "a" { "hi" }
32
+ expect { described_class.new(:hello, proc) }.to raise_error ArgumentError
33
+ end
34
+ end
35
+
36
+ describe "#to_view" do
37
+ it "is true by default" do
38
+ expect(exposure.to_view).to be true
39
+ end
40
+
41
+ it "can be set to false on initialization" do
42
+ expect(described_class.new(:hello, to_view: false).to_view).to be false
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "#bind" do
48
+ context "proc provided" do
49
+ subject(:bound_exposure) { exposure.bind(Object.new) }
50
+
51
+ it "returns itself" do
52
+ expect(bound_exposure).to eql exposure
53
+ end
54
+
55
+ it "retains the same proc" do
56
+ expect(bound_exposure.proc).to eql proc
57
+ end
58
+ end
59
+
60
+ context "no proc provided" do
61
+ subject(:bound_exposure) { exposure.bind(object) }
62
+
63
+ let(:exposure) { described_class.new(:hello) }
64
+
65
+ context "matching instance method" do
66
+ let(:object) do
67
+ Class.new do
68
+ def hello(input)
69
+ "hi there, #{input.fetch(:name)}"
70
+ end
71
+ end.new
72
+ end
73
+
74
+ it "returns a new object" do
75
+ expect(bound_exposure).not_to eql exposure
76
+ end
77
+
78
+ it "sets the proc to the method on the object matching the exposure's name" do
79
+ expect(bound_exposure.proc).to eql object.method(:hello)
80
+ end
81
+ end
82
+
83
+ context "no matching instance method" do
84
+ let(:object) { Object.new }
85
+
86
+ it "returns a new object" do
87
+ expect(bound_exposure).not_to eql exposure
88
+ end
89
+
90
+ it "builds a proc that passes through data from a matching key in the input" do
91
+ expect(bound_exposure.proc.(hello: "hello in input")).to eq "hello in input"
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "#dependencies" do
98
+ let(:proc) { -> input, foo, bar { "hi" } }
99
+
100
+ it "returns an array of exposure dependencies derived from the proc's argument names" do
101
+ expect(exposure.dependencies).to eql [:input, :foo, :bar]
102
+ end
103
+ end
104
+
105
+ describe "#call" do
106
+ let(:input) { double("input") }
107
+
108
+ before do
109
+ allow(proc).to receive(:call)
110
+ end
111
+
112
+ context "proc expects input only" do
113
+ it "sends the input to the proc" do
114
+ exposure.(input)
115
+
116
+ expect(proc).to have_received(:call).with(input)
117
+ end
118
+ end
119
+
120
+ context "proc expects input and dependencies" do
121
+ let(:proc) { -> input, greeting { "#{greeting}, #{input.fetch(:name)}" } }
122
+ let(:locals) { {greeting: "Hola"} }
123
+
124
+ before do
125
+ exposure.(input, locals)
126
+ end
127
+
128
+ it "sends the input and dependency values to the proc" do
129
+ expect(proc).to have_received(:call).with(input, "Hola")
130
+ end
131
+ end
132
+
133
+ context "proc expects dependencies only" do
134
+ let(:proc) { -> greeting, farewell { "#{greeting}, #{input.fetch(:name)}" } }
135
+ let(:locals) { {greeting: "Hola", farewell: "Adios"} }
136
+
137
+ before do
138
+ exposure.(input, locals)
139
+ end
140
+
141
+ it "sends the dependency values to the proc" do
142
+ expect(proc).to have_received(:call).with "Hola", "Adios"
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,63 @@
1
+ RSpec.describe Dry::View::Exposures do
2
+ subject(:exposures) { described_class.new }
3
+
4
+ describe "#exposures" do
5
+ it "is empty by defalut" do
6
+ expect(exposures.exposures).to be_empty
7
+ end
8
+ end
9
+
10
+ describe "#add" do
11
+ it "creates and adds an exposure" do
12
+ proc = -> input { "hi" }
13
+ exposures.add :hello, proc
14
+
15
+ expect(exposures[:hello].name).to eq :hello
16
+ expect(exposures[:hello].proc).to eq proc
17
+ end
18
+ end
19
+
20
+ describe "#bind" do
21
+ subject(:bound_exposures) { exposures.bind(object) }
22
+
23
+ let(:object) do
24
+ Class.new do
25
+ def hello(input)
26
+ "hi"
27
+ end
28
+ end.new
29
+ end
30
+
31
+ before do
32
+ exposures.add(:hello)
33
+ end
34
+
35
+ it "binds each of the exposures" do
36
+ expect(bound_exposures[:hello].proc).to eq object.method(:hello)
37
+ end
38
+
39
+ it "returns a new copy of the exposures" do
40
+ expect(exposures.exposures).not_to eql(bound_exposures.exposures)
41
+ end
42
+ end
43
+
44
+ describe "#locals" do
45
+ before do
46
+ exposures.add(:greeting, -> input { input.fetch(:greeting).upcase })
47
+ exposures.add(:farewell, -> greeting { "#{greeting} and goodbye" })
48
+ end
49
+
50
+ subject(:locals) { exposures.locals(greeting: "hello") }
51
+
52
+ it "returns the values from the exposures' procs" do
53
+ expect(locals).to eq(greeting: "HELLO", farewell: "HELLO and goodbye")
54
+ end
55
+
56
+ it "does not return any values from private exposures" do
57
+ exposures.add(:hidden, -> input { "shh" }, to_view: false)
58
+
59
+ expect(locals).to include(:greeting, :farewell)
60
+ expect(locals).not_to include(:hidden)
61
+ end
62
+ end
63
+ end
@@ -1,8 +1,9 @@
1
+ require 'dry/view/path'
1
2
  require 'dry/view/renderer'
2
3
 
3
4
  RSpec.describe Dry::View::Renderer do
4
5
  subject(:renderer) do
5
- Dry::View::Renderer.new(SPEC_ROOT.join('fixtures/templates'), format: 'html', engine: :slim)
6
+ Dry::View::Renderer.new([Dry::View::Path.new(SPEC_ROOT.join('fixtures/templates'))], format: 'html')
6
7
  end
7
8
 
8
9
  let(:scope) { double(:scope) }