keynote 1.1.0 → 2.0.0
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 +5 -5
- data/CHANGELOG.md +73 -25
- data/{LICENSE → LICENSE.txt} +2 -6
- data/README.md +119 -47
- data/lib/generators/presenter_generator.rb +16 -24
- data/lib/keynote/cache.rb +1 -1
- data/lib/keynote/controller.rb +4 -5
- data/lib/keynote/core.rb +64 -0
- data/lib/keynote/helper.rb +4 -5
- data/lib/keynote/inline.rb +51 -109
- data/lib/keynote/presenter.rb +13 -19
- data/lib/keynote/railtie.rb +7 -24
- data/lib/keynote/rumble.rb +22 -13
- data/lib/keynote/testing/{minitest_rails.rb → minitest.rb} +1 -2
- data/lib/keynote/testing/rspec.rb +5 -5
- data/lib/keynote/testing/test_present_method.rb +2 -2
- data/lib/keynote/testing/test_unit.rb +1 -1
- data/lib/keynote/version.rb +2 -2
- data/lib/keynote.rb +7 -65
- metadata +68 -96
- data/.editorconfig +0 -14
- data/.gitignore +0 -18
- data/.travis.yml +0 -11
- data/.yardopts +0 -4
- data/Gemfile +0 -4
- data/Rakefile +0 -21
- data/keynote.gemspec +0 -37
- data/lib/generators/templates/keynote_mini_test_unit.rb +0 -11
- data/lib/keynote/testing/minitest_rails.rake +0 -7
- data/scenarios/rails31.docker-compose.yml +0 -15
- data/scenarios/rails31.dockerfile +0 -5
- data/scenarios/rails31.gemfile +0 -7
- data/scenarios/rails32.docker-compose.yml +0 -15
- data/scenarios/rails32.dockerfile +0 -5
- data/scenarios/rails32.gemfile +0 -6
- data/scenarios/rails40.docker-compose.yml +0 -15
- data/scenarios/rails40.dockerfile +0 -5
- data/scenarios/rails40.gemfile +0 -6
- data/scenarios/rails41.docker-compose.yml +0 -15
- data/scenarios/rails41.dockerfile +0 -5
- data/scenarios/rails41.gemfile +0 -6
- data/scenarios/rails42.docker-compose.yml +0 -15
- data/scenarios/rails42.dockerfile +0 -5
- data/scenarios/rails42.gemfile +0 -6
- data/scenarios/rails50.docker-compose.yml +0 -15
- data/scenarios/rails50.dockerfile +0 -5
- data/scenarios/rails50.gemfile +0 -6
- data/scenarios/rails51.docker-compose.yml +0 -15
- data/scenarios/rails51.dockerfile +0 -5
- data/scenarios/rails51.gemfile +0 -6
- data/scenarios.yml +0 -25
- data/spec/benchmarks.rb +0 -73
- data/spec/generator_spec.rb +0 -159
- data/spec/helper.rb +0 -90
- data/spec/inline_spec.rb +0 -157
- data/spec/keynote_spec.rb +0 -130
- data/spec/presenter_spec.rb +0 -179
- data/spec/railtie_spec.rb +0 -33
- data/spec/rumble_spec.rb +0 -271
- data/spec/test_case_spec.rb +0 -12
- /data/lib/generators/templates/{keynote_mini_test_spec.rb → keynote_mini_test_spec.rb.tt} +0 -0
- /data/lib/generators/templates/{keynote_test_unit.rb → keynote_mini_test_unit.rb.tt} +0 -0
- /data/lib/generators/templates/{keynote_presenter.rb → keynote_presenter.rb.tt} +0 -0
- /data/lib/generators/templates/{keynote_rspec.rb → keynote_rspec.rb.tt} +0 -0
data/spec/presenter_spec.rb
DELETED
@@ -1,179 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'helper'
|
4
|
-
|
5
|
-
TestPresenter = Keynote::Presenter
|
6
|
-
|
7
|
-
describe Keynote::Presenter do
|
8
|
-
describe "delegation" do
|
9
|
-
let(:klass) do
|
10
|
-
Class.new(TestPresenter) do
|
11
|
-
presents :grizzly, :bear
|
12
|
-
delegate :adams, :to => :grizzly
|
13
|
-
delegate :man, :to => :grizzly, :prefix => true
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should be able to use ActiveSupport Module#delegate method" do
|
18
|
-
mock = mock()
|
19
|
-
mock.expects(:adams)
|
20
|
-
mock.expects(:man)
|
21
|
-
|
22
|
-
klass.new(nil, mock, nil).tap do |p|
|
23
|
-
p.adams
|
24
|
-
p.grizzly_man
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe ".presents" do
|
30
|
-
it "should take just the view context by default" do
|
31
|
-
klass = Class.new(TestPresenter)
|
32
|
-
|
33
|
-
klass.new(1).instance_variable_get(:@view).must_equal 1
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "with two parameters" do
|
37
|
-
let(:klass) do
|
38
|
-
Class.new(TestPresenter) do
|
39
|
-
presents :grizzly, :bear
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should let you specify other objects to take" do
|
44
|
-
klass.new(1, 2, 3).instance_eval do
|
45
|
-
@view.must_equal 1
|
46
|
-
@grizzly.must_equal 2
|
47
|
-
@bear.must_equal 3
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should not be callable with the wrong arity" do
|
52
|
-
proc { klass.new(1, 2) }.must_raise ArgumentError
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should generate readers for the objects" do
|
56
|
-
klass.new(1, 2, 3).tap do |p|
|
57
|
-
p.view.must_equal 1
|
58
|
-
p.grizzly.must_equal 2
|
59
|
-
p.bear.must_equal 3
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe ".use_html5_tags" do
|
66
|
-
let(:klass) do
|
67
|
-
Class.new(TestPresenter) do
|
68
|
-
def generate_h3(content)
|
69
|
-
build_html { h3 content }
|
70
|
-
end
|
71
|
-
|
72
|
-
def generate_small(content)
|
73
|
-
build_html { small content }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
it "should add Rumble tags like `small` while preserving existing tags" do
|
79
|
-
presenter = klass.new(nil)
|
80
|
-
|
81
|
-
presenter.generate_h3("hi").must_equal "<h3>hi</h3>"
|
82
|
-
proc { presenter.generate_small("uh-oh") }.must_raise NoMethodError
|
83
|
-
|
84
|
-
klass.use_html_5_tags
|
85
|
-
|
86
|
-
presenter.generate_h3("hi").must_equal "<h3>hi</h3>"
|
87
|
-
presenter.generate_small("hi").must_equal "<small>hi</small>"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe ".object_names" do
|
92
|
-
it "doesn't leak between classes" do
|
93
|
-
c1 = Class.new(Keynote::Presenter)
|
94
|
-
c2 = Class.new(Keynote::Presenter)
|
95
|
-
|
96
|
-
c1.object_names << :foo
|
97
|
-
c1.object_names.must_equal [:foo]
|
98
|
-
c2.object_names.must_equal []
|
99
|
-
end
|
100
|
-
|
101
|
-
it "matches the list of presented objects" do
|
102
|
-
c = Class.new(Keynote::Presenter)
|
103
|
-
c.object_names.must_equal []
|
104
|
-
c.presents :biff, :bam, :pow
|
105
|
-
c.object_names.must_equal [:biff, :bam, :pow]
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
describe "#present" do
|
110
|
-
it "should pass its view context through to the new presenter" do
|
111
|
-
mock = mock()
|
112
|
-
mock.expects(:pizza)
|
113
|
-
|
114
|
-
p1 = TestPresenter.new(mock)
|
115
|
-
p2 = p1.present(:test)
|
116
|
-
|
117
|
-
p1.wont_equal p2
|
118
|
-
p2.pizza
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
describe "#inspect" do
|
123
|
-
it "includes the class name" do
|
124
|
-
CombinedPresenter.new(:view, :a, :b).inspect.
|
125
|
-
must_match(/^#<CombinedPresenter /)
|
126
|
-
end
|
127
|
-
|
128
|
-
it "shows .inspect output for each presented object" do
|
129
|
-
c1 = Class.new(Object) { def inspect; "c1"; end }
|
130
|
-
c2 = Class.new(Object) { def inspect; "c2"; end }
|
131
|
-
p = CombinedPresenter.new(:view, c1.new, c2.new)
|
132
|
-
|
133
|
-
p.inspect.must_equal "#<CombinedPresenter model_1: c1, model_2: c2>"
|
134
|
-
end
|
135
|
-
|
136
|
-
it "shouldn't leave extra padding for zero-arg presenters" do
|
137
|
-
EmptyPresenter.new(:view).inspect.must_equal "#<EmptyPresenter>"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
describe "#method_missing" do
|
142
|
-
it "should pass unknown method calls through to the view" do
|
143
|
-
mock = mock()
|
144
|
-
mock.expects(:talking).with(:heads)
|
145
|
-
|
146
|
-
object = Class.new do
|
147
|
-
define_method(:talking) do |arg|
|
148
|
-
mock.talking(arg)
|
149
|
-
end
|
150
|
-
private :talking
|
151
|
-
end.new
|
152
|
-
|
153
|
-
TestPresenter.new(object).talking(:heads)
|
154
|
-
end
|
155
|
-
|
156
|
-
it "should respond_to? methods of the view" do
|
157
|
-
object = Class.new do
|
158
|
-
define_method(:talking) do |arg|
|
159
|
-
end
|
160
|
-
private :talking
|
161
|
-
end.new
|
162
|
-
|
163
|
-
TestPresenter.new(object).respond_to?(:talking).must_equal true
|
164
|
-
end
|
165
|
-
|
166
|
-
it "should raise unknown methods at the presenter, not the view" do
|
167
|
-
err = nil
|
168
|
-
|
169
|
-
begin
|
170
|
-
Keynote::Presenter.new(Object.new).talking(:heads)
|
171
|
-
rescue NoMethodError => e
|
172
|
-
err = e
|
173
|
-
end
|
174
|
-
|
175
|
-
err.wont_be_nil
|
176
|
-
err.message.must_match(/Keynote::Presenter/)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
data/spec/railtie_spec.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'helper'
|
4
|
-
|
5
|
-
describe Keynote::Railtie do
|
6
|
-
let(:controller) { HelloController.new }
|
7
|
-
let(:context) { controller.view_context }
|
8
|
-
|
9
|
-
it "should make the present and k methods available to controllers" do
|
10
|
-
controller.must_respond_to :present
|
11
|
-
controller.must_respond_to :k
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should make the present and k methods available to views" do
|
15
|
-
context.must_respond_to :present
|
16
|
-
context.must_respond_to :k
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should pass present call from controller to Keynote.present" do
|
20
|
-
context = stub
|
21
|
-
controller.stubs(:view_context).returns(context)
|
22
|
-
|
23
|
-
Keynote.expects(:present).with(context, :dallas, :leeloo, :multipass)
|
24
|
-
|
25
|
-
controller.present(:dallas, :leeloo, :multipass)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should pass present call from view to Keynote.present" do
|
29
|
-
Keynote.expects(:present).with(context, :dallas, :leeloo, :multipass)
|
30
|
-
|
31
|
-
context.present(:dallas, :leeloo, :multipass)
|
32
|
-
end
|
33
|
-
end
|
data/spec/rumble_spec.rb
DELETED
@@ -1,271 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
# Original Rumble tests (c) 2011 Magnus Holm (https://github.com/judofyr).
|
4
|
-
|
5
|
-
require 'helper'
|
6
|
-
|
7
|
-
if defined?(Minitest::Test)
|
8
|
-
klass = Minitest::Test
|
9
|
-
else
|
10
|
-
klass = MiniTest::Unit::TestCase
|
11
|
-
end
|
12
|
-
|
13
|
-
class TestRumble < klass
|
14
|
-
include Keynote::Rumble
|
15
|
-
|
16
|
-
def assert_rumble(str, &blk)
|
17
|
-
exp = str.gsub(/(\s+(<)|>\s+)/) { $2 || '>' }
|
18
|
-
res = nil
|
19
|
-
build_html {
|
20
|
-
res = yield.to_s
|
21
|
-
}
|
22
|
-
assert_equal exp, res
|
23
|
-
assert_instance_of ActiveSupport::SafeBuffer, res
|
24
|
-
end
|
25
|
-
|
26
|
-
def setup
|
27
|
-
@rumble_context = nil
|
28
|
-
super
|
29
|
-
assert_nil @rumble_context
|
30
|
-
end
|
31
|
-
|
32
|
-
def teardown
|
33
|
-
super
|
34
|
-
assert_nil @rumble_context
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_simple
|
38
|
-
str = <<-HTML
|
39
|
-
<form>
|
40
|
-
<div id="wrapper">
|
41
|
-
<h1>My Site</h1>
|
42
|
-
</div>
|
43
|
-
<div class="input">
|
44
|
-
<input type="text" name="value">
|
45
|
-
</div>
|
46
|
-
</form>
|
47
|
-
HTML
|
48
|
-
|
49
|
-
assert_rumble str do
|
50
|
-
form do
|
51
|
-
div.wrapper! do
|
52
|
-
h1 "My Site"
|
53
|
-
end
|
54
|
-
|
55
|
-
div.input do
|
56
|
-
input type: 'text', name: 'value'
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_string_data
|
63
|
-
assert_rumble '<div data="whatever"></div>' do
|
64
|
-
div data: "whatever"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_hash_data
|
69
|
-
str = <<-HTML
|
70
|
-
<div data-modal="true" data-safe=""""" data-unsafe=""&quot;"">
|
71
|
-
</div>
|
72
|
-
HTML
|
73
|
-
|
74
|
-
assert_rumble str do
|
75
|
-
div data: {
|
76
|
-
modal: true,
|
77
|
-
safe: '"""'.html_safe,
|
78
|
-
absent: nil,
|
79
|
-
unsafe: '"""'
|
80
|
-
}
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_string_aria
|
85
|
-
assert_rumble '<div aria="whatever"></div>' do
|
86
|
-
div aria: "whatever"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def test_hash_aria
|
91
|
-
str = <<-HTML
|
92
|
-
<div aria-modal="true" aria-safe=""""" aria-unsafe=""&quot;"">
|
93
|
-
</div>
|
94
|
-
HTML
|
95
|
-
|
96
|
-
assert_rumble str do
|
97
|
-
div aria: {
|
98
|
-
modal: true,
|
99
|
-
safe: '"""'.html_safe,
|
100
|
-
absent: nil,
|
101
|
-
unsafe: '"""'
|
102
|
-
}
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_array_attrs
|
107
|
-
str = <<-HTML
|
108
|
-
<div class="hello "uns&amp;fe" "w&rld"">
|
109
|
-
</div>
|
110
|
-
HTML
|
111
|
-
|
112
|
-
assert_rumble str do
|
113
|
-
div class: ["hello", '"uns&fe"', '"w&rld"'.html_safe]
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_nil_attr
|
118
|
-
str = <<-HTML
|
119
|
-
<div id="id" class="class"></div>
|
120
|
-
HTML
|
121
|
-
|
122
|
-
assert_rumble str do
|
123
|
-
div id: "id", title: nil, class: "class"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_several
|
128
|
-
str = <<-HTML
|
129
|
-
<p>Hello</p>
|
130
|
-
<p>World</p>
|
131
|
-
HTML
|
132
|
-
|
133
|
-
assert_rumble str do
|
134
|
-
p "Hello"
|
135
|
-
p "World"
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def test_several_capture
|
140
|
-
str = <<-HTML
|
141
|
-
<div>
|
142
|
-
<p>Hello</p>
|
143
|
-
<p>Hello</p>
|
144
|
-
|
|
145
|
-
<p>World</p>
|
146
|
-
<p>World</p>
|
147
|
-
</div>
|
148
|
-
HTML
|
149
|
-
|
150
|
-
assert_rumble str do
|
151
|
-
div do
|
152
|
-
(%w[Hello World].map { |x| build_html { p x; p x } } * '|').html_safe
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def test_capture_raise
|
158
|
-
assert_raises RuntimeError do
|
159
|
-
build_html {
|
160
|
-
div do
|
161
|
-
build_html { raise }
|
162
|
-
end
|
163
|
-
}
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def test_escape
|
168
|
-
str = <<-HTML
|
169
|
-
<p class=""test"">Hello & World</p>
|
170
|
-
HTML
|
171
|
-
|
172
|
-
assert_rumble str do
|
173
|
-
p "Hello & World", :class => '"test"'
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
def test_multiple_css_classes
|
178
|
-
str = <<-HTML
|
179
|
-
<p class="one two three"></p>
|
180
|
-
HTML
|
181
|
-
|
182
|
-
assert_rumble str do
|
183
|
-
p.one.two.three
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def test_selfclosing
|
188
|
-
assert_rumble "<br>" do
|
189
|
-
br
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
def test_text
|
194
|
-
assert_rumble "hello" do
|
195
|
-
text "hello"
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def test_escaping_unsafe_input
|
200
|
-
str = "<br>"
|
201
|
-
|
202
|
-
assert_rumble "<div><br></div>" do
|
203
|
-
div { str }
|
204
|
-
end
|
205
|
-
|
206
|
-
assert_rumble "<div><br></div>" do
|
207
|
-
div str
|
208
|
-
end
|
209
|
-
|
210
|
-
assert_rumble "<div><br></div>" do
|
211
|
-
div { text { str } }
|
212
|
-
end
|
213
|
-
|
214
|
-
assert_rumble "<div><br></div>" do
|
215
|
-
div { text str }
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
def test_not_escaping_safe_input
|
220
|
-
str = "<br>".html_safe
|
221
|
-
|
222
|
-
assert_rumble "<div><br></div>" do
|
223
|
-
div { str }
|
224
|
-
end
|
225
|
-
|
226
|
-
assert_rumble "<div><br></div>" do
|
227
|
-
div str
|
228
|
-
end
|
229
|
-
|
230
|
-
assert_rumble "<div><br></div>" do
|
231
|
-
div { text { str } }
|
232
|
-
end
|
233
|
-
|
234
|
-
assert_rumble "<div><br></div>" do
|
235
|
-
div { text str }
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
def test_error_tags_outside_rumble_context
|
240
|
-
assert_raises Keynote::Rumble::Error do
|
241
|
-
div "content"
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
def test_error_selfclosing_content
|
246
|
-
assert_raises Keynote::Rumble::Error do
|
247
|
-
build_html {
|
248
|
-
br "content"
|
249
|
-
}
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
def test_error_css_proxy_continue
|
254
|
-
assert_raises Keynote::Rumble::Error do
|
255
|
-
build_html {
|
256
|
-
p.one("test").two
|
257
|
-
}
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
# The real test here is if @rumble_context is nil in the teardown.
|
262
|
-
def test_error_general
|
263
|
-
assert_raises RuntimeError do
|
264
|
-
build_html {
|
265
|
-
div do
|
266
|
-
raise
|
267
|
-
end
|
268
|
-
}
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
data/spec/test_case_spec.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
class Keynote::NestedPresenterTest < Keynote::TestCase
|
4
|
-
setup do
|
5
|
-
@presenter = Keynote::NestedPresenter.new(view, :model)
|
6
|
-
end
|
7
|
-
|
8
|
-
test "presenter has view context" do
|
9
|
-
assert_equal "<div id=\"hi\"><a href=\"Hello\">#</a></div>",
|
10
|
-
@presenter.generate_div
|
11
|
-
end
|
12
|
-
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|