client_pages 0.0.2.alpha → 0.0.3.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.rubocop.yml +74 -0
- data/README.md +19 -46
- data/Rakefile +8 -1
- data/client_pages.gemspec +1 -0
- data/lib/client_pages/configuration.rb +29 -0
- data/lib/client_pages/markdown_content/content_builder.rb +64 -0
- data/lib/client_pages/markdown_content/renderer.rb +84 -0
- data/lib/client_pages/matcher.rb +39 -0
- data/lib/client_pages/template.rb +7 -0
- data/lib/client_pages/version.rb +1 -1
- data/lib/client_pages.rb +14 -196
- data/spec/fixtures/{link_list.md → content/link_list.md} +0 -0
- data/spec/fixtures/{test_content.md → content/test_content.md} +0 -0
- data/spec/fixtures/{text_list.md → content/text_list.md} +0 -0
- data/spec/fixtures/foo/bar.md +3 -0
- data/spec/integration/client_pages_spec.rb +274 -0
- data/spec/spec_helper.rb +24 -1
- data/spec/unit/configuration_spec.rb +52 -0
- data/spec/unit/content_builder_spec.rb +8 -0
- data/spec/unit/matcher_spec.rb +11 -0
- data/spec/unit/renderer_spec.rb +8 -0
- data/spec/unit/template_spec.rb +16 -0
- metadata +42 -10
- data/spec/unit/client_pages_spec.rb +0 -205
@@ -1,205 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module ClientPages
|
4
|
-
describe MarkdownContent do
|
5
|
-
context 'blank slate' do
|
6
|
-
before { ClientPages.config { |c| c.remote = false; c.content_path = 'foo' } }
|
7
|
-
it { expect(ClientPages::MarkdownContent.render_content('bar')).to eql("No such file or directory - foo/bar.md") }
|
8
|
-
it 'has more specs for non remote!'
|
9
|
-
end
|
10
|
-
|
11
|
-
describe 'Renderer' do
|
12
|
-
subject { Class.send(:include, ClientPages::MarkdownContent).new }
|
13
|
-
let(:markdown) { fixture('test_content') }
|
14
|
-
let(:content) { subject.render_content(:test_content) }
|
15
|
-
|
16
|
-
before do
|
17
|
-
ClientPages.config do |c|
|
18
|
-
c.remote = true
|
19
|
-
c.caching = false
|
20
|
-
c.remote_content_path = 'http://somewhere.com'
|
21
|
-
end
|
22
|
-
stub_request(:get, 'http://somewhere.com/test_content.md').
|
23
|
-
to_return(body: markdown, status: 200)
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'renders HTML content for given markdown file from somewhere' do
|
27
|
-
expect(content).to include('<h1>Content from <a href="http://somewhere.com">somewhere</a></h1>')
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'with a block' do
|
31
|
-
let(:link_list) { fixture('link_list') }
|
32
|
-
let(:text_list) { fixture('text_list') }
|
33
|
-
before do
|
34
|
-
stub_request(:get, 'http://somewhere.com/link_list.md').to_return(body: link_list, status: 200)
|
35
|
-
stub_request(:get, 'http://somewhere.com/text_list.md').to_return(body: text_list, status: 200)
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'returns a content builder' do
|
39
|
-
expect(
|
40
|
-
subject.render_content(:test_content) { |c| c }
|
41
|
-
).to be_kind_of(MarkdownContent::ContentBuilder)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'modifies tags and html attributes' do
|
45
|
-
expect(
|
46
|
-
subject.render_content(:test_content) do |c|
|
47
|
-
c.modify :h1, class: 'mycss_class', 'data-foo' => 'bar'
|
48
|
-
c.modify :a, class: 'fancy', title: 'woah'
|
49
|
-
end
|
50
|
-
).to include('<h1 data-foo="bar" class="mycss_class">Content from <a title="woah" class="fancy" href="http://somewhere.com">somewhere</a></h1>')
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'adds css classes conditionally' do
|
54
|
-
expect(
|
55
|
-
subject.render_content(:test_content) do |c|
|
56
|
-
c.modify :h1, { class: 'add_me cool' }, true
|
57
|
-
c.modify :a, { class: 'add_me_not' }, false
|
58
|
-
end
|
59
|
-
).to include('<h1 class="add_me cool">Content from <a href="http://somewhere.com">somewhere</a></h1>')
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'adds any attribute conditionally and selective' do
|
63
|
-
expect(
|
64
|
-
subject.render_content(:link_list) do |c|
|
65
|
-
c.modify :li, { class: 'yay' }, ->(m) { m.attr?(:href, '/link1') }
|
66
|
-
c.modify :a, { class: 'active' }, href: '/link2'
|
67
|
-
c.modify :a, { class: 'important' }, title: 'i haz title'
|
68
|
-
end
|
69
|
-
).to include("<li class=\"yay\"><a href=\"/link1\">link1</a></li>\n<li><a class=\"active\" href=\"/link2\">link2</a></li>\n<li><a class=\"important\" href=\"/link3\" title=\"i haz title\">link3</a></li>")
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'wraps multiple tags with container' do
|
73
|
-
expect(
|
74
|
-
subject.render_content(:text_list) do |c|
|
75
|
-
c.wrap :li, wrapper: :span, class: 'wrapper'
|
76
|
-
c.wrap :em, wrapper: :span, class: 'special'
|
77
|
-
end
|
78
|
-
).to eql("<ul>\n<span class=\"wrapper\"><li>Foo <span class=\"special\"><em>Bar</em></span></li></span>\n<span class=\"wrapper\"><li>Baz</li></span>\n</ul>\n")
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'wraps and modifies tags' do
|
82
|
-
expect(
|
83
|
-
subject.render_content(:text_list) do |c|
|
84
|
-
c.wrap :ul, wrapper: :div, class: 'container'
|
85
|
-
c.modify :em, style: 'color: #c0ffee'
|
86
|
-
end
|
87
|
-
).to eql("<div class=\"container\"><ul>\n<li>Foo <em style=\"color: #c0ffee\">Bar</em></li>\n<li>Baz</li>\n</ul></div>\n")
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'replaces tags and adds class' do
|
91
|
-
expect(
|
92
|
-
subject.render_content(:test_content) do |c|
|
93
|
-
c.replace :p, :div, class: 'byebye'
|
94
|
-
c.replace :em, :span, class: 'cooler'
|
95
|
-
end
|
96
|
-
).to eql("<h1>Content from <a href=\"http://somewhere.com\">somewhere</a></h1>\n\n<div class=\"byebye\">Lorem do <span class=\"cooler\">incididunt</span> ut labore</div>\n\n<div class=\"byebye\">Pariatur: <a href=\"/bar.com\" title=\"baz\">Foo</a> culpa</div>\n")
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
describe "caching" do
|
101
|
-
before do
|
102
|
-
ClientPages.config do |c|
|
103
|
-
c.caching = true
|
104
|
-
c.remote = true
|
105
|
-
c.remote_content_path = "http://c.ly"
|
106
|
-
end
|
107
|
-
end
|
108
|
-
after { ClientPages.config { |c| c.caching = false } }
|
109
|
-
before(:each) { ClientPages.clear_cache }
|
110
|
-
|
111
|
-
it 'populates cache when empty' do
|
112
|
-
request = stub_request(:get, %r[/caching.md]).to_return(body: '**cache me**')
|
113
|
-
expect { subject.render_content(:caching) }.to change { ClientPages.cache }.to eql({"http://c.ly/caching.md"=>"**cache me**"})
|
114
|
-
expect(request).to have_been_made.times(1)
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'makes request only once' do
|
118
|
-
request = stub_request(:get, %r[/caching.md]).to_return(body: '**cache me**')
|
119
|
-
5.times { subject.render_content(:caching) }
|
120
|
-
expect { subject.render_content(:caching) }.to_not change { ClientPages.cache }
|
121
|
-
expect(request).to have_been_made.times(1)
|
122
|
-
end
|
123
|
-
|
124
|
-
context 'disabled' do
|
125
|
-
before do
|
126
|
-
ClientPages.config do |c|
|
127
|
-
c.caching = false
|
128
|
-
c.remote = true
|
129
|
-
c.remote_content_path = "http://c.ly"
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'will not cache' do
|
134
|
-
stub_request(:get, %r[/no_caching.md]).to_return(body: '_u_no_cache_me_')
|
135
|
-
subject.render_content(:no_caching)
|
136
|
-
expect(ClientPages.cache).to be_empty
|
137
|
-
end
|
138
|
-
|
139
|
-
it 'makes a request per render_content call' do
|
140
|
-
request = stub_request(:get, %r[/no_caching.md]).to_return(body: '_u_no_cache_me_')
|
141
|
-
5.times { subject.render_content(:no_caching) }
|
142
|
-
expect(request).to have_been_made.times(5)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
describe 'configuration' do
|
149
|
-
subject { ClientPages }
|
150
|
-
before { subject.configuration = nil }
|
151
|
-
|
152
|
-
it 'has default config' do
|
153
|
-
config = {
|
154
|
-
content_path: 'content',
|
155
|
-
render_options: {},
|
156
|
-
markdown_extensions: {}
|
157
|
-
}
|
158
|
-
expect(subject.config.to_hash).to eql(config)
|
159
|
-
end
|
160
|
-
|
161
|
-
it 'is configurable' do
|
162
|
-
config = {
|
163
|
-
content_path: 'somewhere',
|
164
|
-
render_options: { foo: "bar" },
|
165
|
-
markdown_extensions: { bam: true }
|
166
|
-
}
|
167
|
-
expect {
|
168
|
-
subject.config do |c|
|
169
|
-
c.content_path = 'somewhere'
|
170
|
-
c.render_options = { foo: 'bar' }
|
171
|
-
c.markdown_extensions = { bam: true }
|
172
|
-
end
|
173
|
-
}.to change {
|
174
|
-
subject.config.to_hash
|
175
|
-
}.to eql(config)
|
176
|
-
end
|
177
|
-
|
178
|
-
describe 'overwritable config' do
|
179
|
-
before do
|
180
|
-
subject.config do |c|
|
181
|
-
c.render_options = { opt1: true }
|
182
|
-
c.markdown_extensions = { ext1: true }
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
it 'overwrites config and keeps untouched config settings' do
|
187
|
-
config = {
|
188
|
-
content_path: 'here',
|
189
|
-
render_options: { opt1: false, opt2: true },
|
190
|
-
markdown_extensions: { ext1: true, ext2: false }
|
191
|
-
}
|
192
|
-
expect {
|
193
|
-
subject.config do |c|
|
194
|
-
c.content_path = 'here'
|
195
|
-
c.render_options = { opt1: false, opt2: true }
|
196
|
-
c.markdown_extensions = { ext2: false }
|
197
|
-
end
|
198
|
-
}.to change {
|
199
|
-
subject.config.to_hash
|
200
|
-
}.to eql(config)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|