client_pages 0.0.2.alpha → 0.0.3.beta

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.
@@ -0,0 +1,274 @@
1
+ require 'spec_helper'
2
+
3
+ module ClientPages
4
+ describe 'MarkdownContent' do
5
+ subject { ClientPages::MarkdownContent::Renderer }
6
+
7
+ describe 'invalid path' do
8
+ before { ClientPages.config { |c| c.content_path = 'not_there' } }
9
+ it { expect(subject.render_content(:bar)).to eql('No such file or directory - bar') }
10
+ end
11
+
12
+ describe 'valid path' do
13
+ before { ClientPages.config { |c| c.content_path = 'spec/fixtures/foo' } }
14
+ it { expect(subject.render_content(:bar)).to eql("<h1>foo</h1>\n\n<p>bar</p>") }
15
+ end
16
+
17
+ it 'blends' do
18
+ expect(
19
+ subject.render_content(:test_content) do |c|
20
+ c.modify :h1, with: { class: 'mycss_class', 'data-foo' => 'bar' }, if: ->(m) { m.includes?('Content') }
21
+ c.modify :a, with: { class: 'fancy', title: 'woah' }, if: { href: 'http://somewhere.com' }
22
+ c.wrap :h1, :div, with: { id: 'my-id', class: 'foo' }
23
+ c.replace :p, :span, with: { class: 'bar', 'data-p' => 'no-more' }
24
+ end
25
+ ).to eql(
26
+ "<div id=\"my-id\" class=\"foo\"><h1 class=\"mycss_class\" data-foo=\"bar\">Content from "\
27
+ "<a href=\"http://somewhere.com\" class=\"fancy\" title=\"woah\">somewhere</a></h1></div>\n\n"\
28
+ "<span class=\"bar\" data-p=\"no-more\">Lorem do <em>incididunt</em> ut labore</span>\n\n"\
29
+ "<span class=\"bar\" data-p=\"no-more\">Pariatur: "\
30
+ "<a href=\"/bar.com\" title=\"baz\">Foo</a> culpa</span>\n"
31
+ )
32
+ end
33
+
34
+ describe 'Renderer' do
35
+ let(:markdown) { fixture('test_content') }
36
+
37
+ before do
38
+ ClientPages.config do |c|
39
+ c.remote = true
40
+ c.caching = false
41
+ c.remote_content_path = 'http://somewhere.com'
42
+ end
43
+ stub_request(:get, 'http://somewhere.com/test_content.md')
44
+ .to_return(body: markdown, status: 200)
45
+ end
46
+
47
+ context 'without a block' do
48
+ let(:rendered_content) { subject.render_content(:test_content) }
49
+
50
+ it 'renders HTML content for given markdown file from somewhere' do
51
+ expect(rendered_content).to include('<h1>Content from <a href="http://somewhere.com">somewhere</a></h1>')
52
+ end
53
+
54
+ describe 'raw markdown' do
55
+ before do
56
+ ClientPages.config { |c| c.raw_markdown = true }
57
+ end
58
+
59
+ it 'renders HTML content for given markdown' do
60
+ expect(subject.render_content('# *raw* markdown')).to eql('<h1><em>raw</em> markdown</h1>')
61
+ end
62
+ end
63
+ end
64
+
65
+ context 'with a block' do
66
+ let(:link_list) { fixture('link_list') }
67
+ let(:text_list) { fixture('text_list') }
68
+ before do
69
+ stub_request(:get, 'http://somewhere.com/link_list.md').to_return(body: link_list, status: 200)
70
+ stub_request(:get, 'http://somewhere.com/text_list.md').to_return(body: text_list, status: 200)
71
+ end
72
+
73
+ it 'returns a content builder' do
74
+ expect(
75
+ subject.render_content(:test_content) { |c| c }
76
+ ).to be_kind_of(MarkdownContent::ContentBuilder)
77
+ end
78
+
79
+ it 'modifies tags and html attributes' do
80
+ expect(
81
+ subject.render_content(:test_content) do |c|
82
+ c.modify :h1, with: { class: 'mycss_class', 'data-foo' => 'bar' }
83
+ c.modify :a, with: { class: 'fancy', title: 'woah' }
84
+ end
85
+ ).to include(
86
+ '<h1 class="mycss_class" data-foo="bar">'\
87
+ 'Content from <a href="http://somewhere.com" class="fancy" title="woah">somewhere</a>'\
88
+ '</h1>'
89
+ )
90
+ end
91
+
92
+ it 'adds attributes conditionally' do
93
+ expect(
94
+ subject.render_content(:test_content) do |c|
95
+ c.modify :h1, with: { class: 'add_me cool' }, if: true
96
+ c.modify :a, with: { class: 'add_me_not' }, if: false
97
+ end
98
+ ).to include(
99
+ '<h1 class="add_me cool">Content from <a href="http://somewhere.com">somewhere</a></h1>'
100
+ )
101
+ end
102
+
103
+ it 'adds any attribute conditionally and selective' do
104
+ expect(
105
+ subject.render_content(:link_list) do |c|
106
+ c.modify :li, with: { class: 'yay' }, if: ->(m) { m.match_any?(:href, '/link1') }
107
+ c.modify :a, with: { class: 'active' }, if: { href: '/link2' }
108
+ c.modify :a, with: { class: 'important', 'data-foo' => 'bar' }, if: { title: 'i haz title' }
109
+ end
110
+ ).to include(
111
+ "<li class=\"yay\"><a href=\"/link1\">link1</a></li>\n"\
112
+ "<li><a href=\"/link2\" class=\"active\">link2</a></li>\n"\
113
+ "<li><a href=\"/link3\" title=\"i haz title\" class=\"important\" data-foo=\"bar\">link3</a></li>"
114
+ )
115
+ end
116
+
117
+ it 'wraps multiple tags with container' do
118
+ expect(
119
+ subject.render_content(:text_list) do |c|
120
+ c.wrap :ul, :div, with: { class: 'wrapper foo' }
121
+ c.wrap :em, :span, with: { class: 'special' }, if: ->(m) { m.includes?('Bar') }
122
+ end
123
+ ).to eql(
124
+ "<div class=\"wrapper foo\"><ul>\n"\
125
+ "<li>Foo <span class=\"special\"><em>Bar</em></span></li>\n"\
126
+ "<li>Baz</li>\n"\
127
+ "</ul></div>\n"
128
+ )
129
+ end
130
+
131
+ it 'wraps and modifies tags' do
132
+ expect(
133
+ subject.render_content(:text_list) do |c|
134
+ c.wrap :ul, :div, with: { class: 'container' }
135
+ c.modify :em, with: { style: 'color: #c0ffee' }
136
+ end
137
+ ).to eql(
138
+ "<div class=\"container\"><ul>\n"\
139
+ "<li>Foo <em style=\"color: #c0ffee\">Bar</em></li>\n"\
140
+ "<li>Baz</li>\n"\
141
+ "</ul></div>\n"
142
+ )
143
+ end
144
+
145
+ it 'replaces tags and adds class' do
146
+ expect(
147
+ subject.render_content(:test_content) do |c|
148
+ c.replace :p, :div, with: { class: 'byebye' }
149
+ c.replace :em, :span, with: { id: 'i-am', class: 'cool', 'data-u' => 'r-not' }
150
+ end
151
+ ).to eql(
152
+ "<h1>Content from <a href=\"http://somewhere.com\">somewhere</a></h1>\n\n"\
153
+ "<div class=\"byebye\">"\
154
+ "Lorem do <span id=\"i-am\" class=\"cool\" data-u=\"r-not\">incididunt</span> ut labore"\
155
+ "</div>\n\n"\
156
+ "<div class=\"byebye\">Pariatur: <a href=\"/bar.com\" title=\"baz\">Foo</a> culpa</div>\n"
157
+ )
158
+ end
159
+
160
+ it 'wraps and replaces conditionally' do
161
+ expect(
162
+ subject.render_content(:test_content) do |c|
163
+ c.wrap :a, :span, with: { class: 'btn' }, if: { href: 'http://somewhere.com' }
164
+ c.replace :p, :div, if: ->(m) { m.includes?('Lorem') }
165
+ c.replace :em, :span, with: { class: 'replaced' }, if: ->(m) { m.includes?('incididunt') }
166
+ end
167
+ ).to eql(
168
+ "<h1>Content from <span class=\"btn\"><a href=\"http://somewhere.com\">somewhere</a></span></h1>\n\n"\
169
+ "<div>Lorem do <span class=\"replaced\">incididunt</span> ut labore</div>\n\n"\
170
+ "<p>Pariatur: <a href=\"/bar.com\" title=\"baz\">Foo</a> culpa</p>\n"
171
+ )
172
+ end
173
+ end
174
+
175
+ describe 'with caching' do
176
+ before(:each) { ClientPages.cache.clear }
177
+ after { ClientPages.config { |c| c.caching = false } }
178
+
179
+ context 'enabled' do
180
+ before do
181
+ ClientPages.config do |c|
182
+ c.caching = true
183
+ c.remote = true
184
+ c.remote_content_path = 'http://c.ly'
185
+ end
186
+ end
187
+
188
+ it 'populates cache when empty' do
189
+ request = stub_request(:get, /\/caching.md/).to_return(body: '**cache me**')
190
+ expect { subject.render_content(:caching) }
191
+ .to change { ClientPages.cache }
192
+ .to eql('http://c.ly/caching.md' => '**cache me**')
193
+ expect(request).to have_been_made.times(1)
194
+ end
195
+
196
+ it 'makes request only once' do
197
+ request = stub_request(:get, /\/caching.md/).to_return(body: '**cache me**')
198
+ 5.times { subject.render_content(:caching) }
199
+ expect { subject.render_content(:caching) }.to_not change { ClientPages.cache }
200
+ expect(request).to have_been_made.times(1)
201
+ end
202
+ end
203
+
204
+ context 'disabled' do
205
+ before do
206
+ ClientPages.config do |c|
207
+ c.caching = false
208
+ c.remote = true
209
+ c.remote_content_path = 'http://c.ly'
210
+ end
211
+ end
212
+
213
+ it 'will not cache' do
214
+ stub_request(:get, /\/no_caching.md/).to_return(body: '_u_no_cache_me_')
215
+ subject.render_content(:no_caching)
216
+ expect(ClientPages.cache).to be_empty
217
+ end
218
+
219
+ it 'makes a request per render_content call' do
220
+ request = stub_request(:get, /\/no_caching.md/).to_return(body: '_u_no_cache_me_')
221
+ 5.times { subject.render_content(:no_caching) }
222
+ expect(request).to have_been_made.times(5)
223
+ end
224
+ end
225
+ end
226
+
227
+ describe 'default templates' do
228
+ before do
229
+ ClientPages.templates do |t|
230
+ t.set(:basic) do |c|
231
+ c.modify :h1, with: { class: 'headers' }
232
+ c.wrap :a, :span, with: { class: 'links' }, if: ->(m) { m.includes?('somewhere') }
233
+ c.replace :p, :div
234
+ end
235
+ end
236
+ end
237
+
238
+ it 'uses templates and accepts additional block' do
239
+ expect(
240
+ subject.render_content(:test_content, template: :basic) do |c|
241
+ c.modify :h1, with: { 'data-foo' => 'bar' }
242
+ end
243
+ ).to eql(
244
+ "<h1 class=\"headers\" data-foo=\"bar\">Content from <span class=\"links\">"\
245
+ "<a href=\"http://somewhere.com\">somewhere</a></span></h1>\n\n"\
246
+ "<div>Lorem do <em>incididunt</em> ut labore</div>\n\n<div>Pariatur: "\
247
+ "<a href=\"/bar.com\" title=\"baz\">Foo</a> culpa</div>\n"
248
+ )
249
+ end
250
+ end
251
+ end
252
+
253
+ describe 'configuration' do
254
+ subject { ClientPages }
255
+ before { subject.configuration = nil }
256
+
257
+ it 'is configurable with a block' do
258
+ expect {
259
+ subject.config do |c|
260
+ c.content_path = 'somewhere'
261
+ c.render_options = { foo: 'bar' }
262
+ c.markdown_extensions = { bam: true }
263
+ end
264
+ }.to change {
265
+ subject.config.to_hash
266
+ }.to eql(
267
+ content_path: 'somewhere',
268
+ render_options: { foo: 'bar' },
269
+ markdown_extensions: { bam: true }
270
+ )
271
+ end
272
+ end
273
+ end
274
+ end
data/spec/spec_helper.rb CHANGED
@@ -8,6 +8,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
8
  require 'client_pages'
9
9
 
10
10
  require 'webmock/rspec'
11
+ require 'open-uri'
11
12
 
12
13
  RSpec.configure do |config|
13
14
  config.treat_symbols_as_metadata_keys_with_true_values = true
@@ -22,9 +23,31 @@ RSpec.configure do |config|
22
23
  config.mock_with :rspec do |c|
23
24
  c.syntax = :expect
24
25
  end
26
+
27
+ config.before(:each) do
28
+ ClientPages.config do |c|
29
+ c.remote = false
30
+ c.caching = false
31
+ c.content_path = 'spec/fixtures/content'
32
+ c.remote_content_path = nil
33
+ c.raw_markdown = false
34
+ c.render_options = {
35
+ hard_wrap: true,
36
+ with_toc_data: false
37
+ }
38
+ c.markdown_extensions = {
39
+ tables: true,
40
+ autolink: true,
41
+ lax_spacing: true,
42
+ space_after_headers: true,
43
+ underline: false,
44
+ no_intra_emphasis: true
45
+ }
46
+ end
47
+ end
25
48
  end
26
49
 
27
50
  # helper for markdown fixture files
28
51
  def fixture(name)
29
- File.open(File.expand_path("spec/fixtures/#{name}.md"), 'r')
52
+ open("#{ClientPages.config.content_path}/#{name}.md").read
30
53
  end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ module ClientPages
4
+ describe Configuration do
5
+
6
+ it 'has default config' do
7
+ config = {
8
+ content_path: 'content',
9
+ render_options: {},
10
+ markdown_extensions: {}
11
+ }
12
+ expect(subject.to_hash).to eql(config)
13
+ end
14
+
15
+ it 'is configurable' do
16
+ config = {
17
+ content_path: 'somewhere',
18
+ render_options: { foo: 'bar' },
19
+ markdown_extensions: { bam: true }
20
+ }
21
+ expect {
22
+ subject.content_path = 'somewhere'
23
+ subject.render_options = { foo: 'bar' }
24
+ subject.markdown_extensions = { bam: true }
25
+ }.to change {
26
+ subject.to_hash
27
+ }.to eql(config)
28
+ end
29
+
30
+ describe 'overwritable config' do
31
+ before do
32
+ subject.render_options = { opt1: true }
33
+ subject.markdown_extensions = { ext1: true }
34
+ end
35
+
36
+ it 'overwrites config and keeps untouched config settings' do
37
+ config = {
38
+ content_path: 'here',
39
+ render_options: { opt1: false, opt2: true },
40
+ markdown_extensions: { ext1: true, ext2: false }
41
+ }
42
+ expect {
43
+ subject.content_path = 'here'
44
+ subject.render_options = { opt1: false, opt2: true }
45
+ subject.markdown_extensions = { ext2: false }
46
+ }.to change {
47
+ subject.to_hash
48
+ }.to eql(config)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ module ClientPages
4
+ module MarkdownContent
5
+ describe ContentBuilder do
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ module ClientPages
4
+ describe Matcher do
5
+ subject { described_class.new(:span, '<span>foo</span>') }
6
+ it { expect(subject.tag).to eql(:span) }
7
+ it { expect(subject.line).to eql('<span>foo</span>') }
8
+ it { expect(subject.includes?('foo')).to be_true }
9
+ it { expect(subject.match?(nil, 'foo')).to be_false }
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ module ClientPages
4
+ module MarkdownContent
5
+ describe Renderer do
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ module ClientPages
4
+ describe 'Template' do
5
+ let(:templates) { {} }
6
+
7
+ before do
8
+ expect(ClientPages).to receive(:template) { templates }
9
+ Template.new.set(:foo) { |args| 'foobar' + args }
10
+ end
11
+
12
+ it 'saves a referenceable block with arguments' do
13
+ expect(templates[:foo].call('bam')).to eql('foobarbam')
14
+ end
15
+ end
16
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: client_pages
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2.alpha
4
+ version: 0.0.3.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Schaden
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-01 00:00:00.000000000 Z
11
+ date: 2014-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redcarpet
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ~>
109
109
  - !ruby/object:Gem::Version
110
110
  version: 0.18.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: flog
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 4.2.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 4.2.0
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: simplecov
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -133,18 +147,30 @@ extensions: []
133
147
  extra_rdoc_files: []
134
148
  files:
135
149
  - .gitignore
150
+ - .rubocop.yml
136
151
  - Gemfile
137
152
  - LICENSE.txt
138
153
  - README.md
139
154
  - Rakefile
140
155
  - client_pages.gemspec
141
156
  - lib/client_pages.rb
157
+ - lib/client_pages/configuration.rb
158
+ - lib/client_pages/markdown_content/content_builder.rb
159
+ - lib/client_pages/markdown_content/renderer.rb
160
+ - lib/client_pages/matcher.rb
161
+ - lib/client_pages/template.rb
142
162
  - lib/client_pages/version.rb
143
- - spec/fixtures/link_list.md
144
- - spec/fixtures/test_content.md
145
- - spec/fixtures/text_list.md
163
+ - spec/fixtures/content/link_list.md
164
+ - spec/fixtures/content/test_content.md
165
+ - spec/fixtures/content/text_list.md
166
+ - spec/fixtures/foo/bar.md
167
+ - spec/integration/client_pages_spec.rb
146
168
  - spec/spec_helper.rb
147
- - spec/unit/client_pages_spec.rb
169
+ - spec/unit/configuration_spec.rb
170
+ - spec/unit/content_builder_spec.rb
171
+ - spec/unit/matcher_spec.rb
172
+ - spec/unit/renderer_spec.rb
173
+ - spec/unit/template_spec.rb
148
174
  homepage: ''
149
175
  licenses:
150
176
  - MIT
@@ -171,9 +197,15 @@ specification_version: 4
171
197
  summary: With client_pages you can separate your content from html markup and css
172
198
  styles
173
199
  test_files:
174
- - spec/fixtures/link_list.md
175
- - spec/fixtures/test_content.md
176
- - spec/fixtures/text_list.md
200
+ - spec/fixtures/content/link_list.md
201
+ - spec/fixtures/content/test_content.md
202
+ - spec/fixtures/content/text_list.md
203
+ - spec/fixtures/foo/bar.md
204
+ - spec/integration/client_pages_spec.rb
177
205
  - spec/spec_helper.rb
178
- - spec/unit/client_pages_spec.rb
206
+ - spec/unit/configuration_spec.rb
207
+ - spec/unit/content_builder_spec.rb
208
+ - spec/unit/matcher_spec.rb
209
+ - spec/unit/renderer_spec.rb
210
+ - spec/unit/template_spec.rb
179
211
  has_rdoc: