hologram 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +37 -0
- data/README.md +243 -5
- data/hologram.gemspec +2 -0
- data/lib/hologram.rb +2 -0
- data/lib/hologram/block_code_renderer.rb +45 -0
- data/lib/hologram/code_example_renderer.rb +73 -0
- data/lib/hologram/code_example_renderer/example.rb +27 -0
- data/lib/hologram/code_example_renderer/factory.rb +60 -0
- data/lib/hologram/code_example_renderer/renderers/haml_renderer.rb +17 -0
- data/lib/hologram/code_example_renderer/renderers/html_renderer.rb +6 -0
- data/lib/hologram/code_example_renderer/renderers/js_renderer.rb +5 -0
- data/lib/hologram/code_example_renderer/renderers/jsx_renderer.rb +4 -0
- data/lib/hologram/code_example_renderer/renderers/react_renderer.rb +21 -0
- data/lib/hologram/code_example_renderer/renderers/slim_renderer.rb +16 -0
- data/lib/hologram/code_example_renderer/template.rb +33 -0
- data/lib/hologram/display_message.rb +13 -0
- data/lib/hologram/doc_block_collection.rb +5 -1
- data/lib/hologram/doc_builder.rb +58 -7
- data/lib/hologram/doc_parser.rb +20 -4
- data/lib/hologram/document_block.rb +22 -4
- data/lib/hologram/link_helper.rb +18 -0
- data/lib/hologram/markdown_renderer.rb +56 -35
- data/lib/hologram/version.rb +1 -1
- data/lib/template/code_example_templates/js_example_template.html.erb +7 -0
- data/lib/template/code_example_templates/jsx_example_template.html.erb +7 -0
- data/lib/template/code_example_templates/markup_example_template.html.erb +10 -0
- data/lib/template/code_example_templates/markup_table_template.html.erb +23 -0
- data/lib/template/hologram_config.yml +23 -0
- data/spec/block_code_renderer_spec.rb +279 -0
- data/spec/code_example_renderer/example_spec.rb +26 -0
- data/spec/code_example_renderer/factory_spec.rb +102 -0
- data/spec/code_example_renderer/template_spec.rb +50 -0
- data/spec/display_message_spec.rb +18 -0
- data/spec/doc_block_collection_spec.rb +26 -1
- data/spec/doc_builder_spec.rb +28 -5
- data/spec/doc_parser_spec.rb +67 -7
- data/spec/document_block_spec.rb +33 -2
- data/spec/fixtures/source/components/button/buttons.css +8 -6
- data/spec/fixtures/source/components/button/skin/buttonSkins.css +17 -0
- data/spec/fixtures/styleguide/base_css.html +176 -52
- data/spec/fixtures/styleguide/index.html +6 -14
- data/spec/link_helper_spec.rb +57 -0
- data/spec/markdown_renderer_spec.rb +82 -0
- metadata +75 -19
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hologram::CodeExampleRenderer::Example do
|
4
|
+
let(:code) { 'goto 12' }
|
5
|
+
let(:example) { described_class.new(code) }
|
6
|
+
|
7
|
+
describe '#rendered_example' do
|
8
|
+
subject { example.rendered_example }
|
9
|
+
it { is_expected.to eq 'goto 12' }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#code_example' do
|
13
|
+
let(:formatter) { double(:formatter) }
|
14
|
+
let(:lexer) { double(:lexer, lex: 'lexed_code') }
|
15
|
+
|
16
|
+
before do
|
17
|
+
allow(Rouge::Lexer).to receive(:find_fancy).with('guess', code) { lexer }
|
18
|
+
allow(Rouge::Formatters::HTML).to receive(:new) { formatter }
|
19
|
+
allow(formatter).to receive(:format).with('lexed_code') { 'formatted_lexed_code' }
|
20
|
+
end
|
21
|
+
|
22
|
+
subject { example.code_example }
|
23
|
+
|
24
|
+
it { is_expected.to eq 'formatted_lexed_code' }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
Hologram::CodeExampleRenderer.load_renderers_and_templates
|
4
|
+
|
5
|
+
describe Hologram::CodeExampleRenderer::Factory do
|
6
|
+
describe '.define' do
|
7
|
+
let(:example_type) { 'foobar' }
|
8
|
+
|
9
|
+
before do
|
10
|
+
allow(Hologram::CodeExampleRenderer::Template).to receive(:new).with('custom_example_template') { double(template: 'the full custom example template') }
|
11
|
+
allow(Hologram::CodeExampleRenderer::Template).to receive(:new).with('custom_table_template') { double(template: 'the full custom table template') }
|
12
|
+
allow(Hologram::CodeExampleRenderer::Template).to receive(:new).with(nil).and_call_original
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when a renderer is registered with all of the options" do
|
16
|
+
before do
|
17
|
+
custom_lexer = double(:lexer, lex: 'lexed code from supplied lexer')
|
18
|
+
|
19
|
+
Hologram::CodeExampleRenderer::Factory.define(example_type) do
|
20
|
+
example_template 'custom_example_template'
|
21
|
+
table_template 'custom_table_template'
|
22
|
+
lexer { custom_lexer }
|
23
|
+
rendered_example { |code| "special rendering for #{code}" }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
after { Hologram::CodeExampleRenderer.unregister(example_type) }
|
28
|
+
|
29
|
+
describe "the registered example class" do
|
30
|
+
let(:example_class) { Hologram::CodeExampleRenderer.example_class_for(example_type) }
|
31
|
+
let(:example) { example_class.new('some code') }
|
32
|
+
|
33
|
+
it "renders the example using the block supplied to the factory" do
|
34
|
+
expect(example.rendered_example).to eq "special rendering for some code"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "formats the code uses the supplied lexer" do
|
38
|
+
formatter = double(:formatter)
|
39
|
+
allow(Rouge::Formatters::HTML).to receive(:new) { formatter }
|
40
|
+
|
41
|
+
expect(formatter).to receive(:format).with('lexed code from supplied lexer') { 'formatted code' }
|
42
|
+
example.code_example
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "the registered templates" do
|
47
|
+
let(:example_template) { Hologram::CodeExampleRenderer.example_template_for(example_type) }
|
48
|
+
let(:table_template) { Hologram::CodeExampleRenderer.table_template_for(example_type) }
|
49
|
+
|
50
|
+
it "uses the supplied example template" do
|
51
|
+
expect(example_template).to eq 'the full custom example template'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "uses the supplied table template" do
|
55
|
+
expect(table_template).to eq 'the full custom table template'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when a renderer is registered with only some of the options" do
|
61
|
+
before do
|
62
|
+
|
63
|
+
Hologram::CodeExampleRenderer::Factory.define(example_type) do
|
64
|
+
example_template 'custom_example_template'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
after { Hologram::CodeExampleRenderer.unregister(example_type) }
|
69
|
+
|
70
|
+
describe "the registered example class" do
|
71
|
+
let(:example_class) { Hologram::CodeExampleRenderer.example_class_for(example_type) }
|
72
|
+
let(:example) { example_class.new('some code') }
|
73
|
+
|
74
|
+
it "renders the example as is" do
|
75
|
+
expect(example.rendered_example).to eq "some code"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "formats the code uses the default lexer" do
|
79
|
+
formatter = double(:formatter)
|
80
|
+
allow(Rouge::Lexer).to receive(:find_fancy).with('guess', 'some code') { double(lex: 'default lexed code') }
|
81
|
+
allow(Rouge::Formatters::HTML).to receive(:new) { formatter }
|
82
|
+
|
83
|
+
expect(formatter).to receive(:format).with('default lexed code') { 'formatted code' }
|
84
|
+
example.code_example
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "the registered templates" do
|
89
|
+
let(:example_template) { Hologram::CodeExampleRenderer.example_template_for(example_type) }
|
90
|
+
let(:table_template) { Hologram::CodeExampleRenderer.table_template_for(example_type) }
|
91
|
+
|
92
|
+
it "uses the supplied example template" do
|
93
|
+
expect(example_template).to eq 'the full custom example template'
|
94
|
+
end
|
95
|
+
|
96
|
+
it "does not have a table template" do
|
97
|
+
expect(table_template).to be_nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hologram::CodeExampleRenderer::Template do
|
4
|
+
describe '#template' do
|
5
|
+
subject { described_class.new(template_name).template }
|
6
|
+
|
7
|
+
context 'when template_name is nil' do
|
8
|
+
let(:template_name) { nil }
|
9
|
+
it { is_expected.to be_nil }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when template_name is not nil' do
|
13
|
+
let(:template_name) { 'bar' }
|
14
|
+
|
15
|
+
let(:custom_template_filename) { 'custom/bar.html.erb' }
|
16
|
+
let(:default_template_filename) { 'cwd/../../template/code_example_templates/bar.html.erb' }
|
17
|
+
|
18
|
+
before do
|
19
|
+
allow(File).to receive(:dirname) { 'cwd/' }
|
20
|
+
allow(File).to receive(:read).with(custom_template_filename) { 'custom template' }
|
21
|
+
allow(File).to receive(:read).with(default_template_filename) { 'default template' }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when path_to_custom_example_templates is defined' do
|
25
|
+
before do
|
26
|
+
described_class.path_to_custom_example_templates = 'custom/'
|
27
|
+
allow(File).to receive(:file?).with(custom_template_filename) { has_custom_template? }
|
28
|
+
end
|
29
|
+
|
30
|
+
after do
|
31
|
+
described_class.path_to_custom_example_templates = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when a custom template exists' do
|
35
|
+
let(:has_custom_template?) { true }
|
36
|
+
it { is_expected.to eq 'custom template' }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when a custom template does not exist' do
|
40
|
+
let(:has_custom_template?) { false }
|
41
|
+
it { is_expected.to eq 'default template' }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when a path_to_custom_example_templates is not defined' do
|
46
|
+
it { is_expected.to eq 'default template' }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -60,10 +60,28 @@ describe Hologram::DisplayMessage do
|
|
60
60
|
end
|
61
61
|
|
62
62
|
context '.warning' do
|
63
|
+
around do |example|
|
64
|
+
display.quiet!
|
65
|
+
example.run
|
66
|
+
display.show!
|
67
|
+
end
|
68
|
+
|
63
69
|
it 'displays a warning message in yellow' do
|
64
70
|
expect(display).to receive(:puts).with("\e[33mWarning: foo\e[0m")
|
65
71
|
display.warning('foo')
|
66
72
|
end
|
73
|
+
|
74
|
+
context 'when .exit_on_warnings! has been called' do
|
75
|
+
around do |example|
|
76
|
+
display.exit_on_warnings!
|
77
|
+
example.run
|
78
|
+
display.continue_on_warnings!
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'exits' do
|
82
|
+
expect{ display.warning('foo') }.to raise_error SystemExit
|
83
|
+
end
|
84
|
+
end
|
67
85
|
end
|
68
86
|
|
69
87
|
context '.colorize' do
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Hologram::DocBlockCollection do
|
4
4
|
let(:comment) do
|
5
|
-
|
5
|
+
<<-comment
|
6
6
|
/*doc
|
7
7
|
---
|
8
8
|
title: Buttons
|
@@ -49,6 +49,31 @@ comment
|
|
49
49
|
expect(collection.doc_blocks.size).to eql 0
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
context 'when the block has the same name as another block in the collection' do
|
54
|
+
let(:duplicate_comment) do
|
55
|
+
<<-comment
|
56
|
+
/*doc
|
57
|
+
---
|
58
|
+
title: Imposter Buttons
|
59
|
+
name: button
|
60
|
+
category: Base CSS
|
61
|
+
---
|
62
|
+
|
63
|
+
Same old stuff
|
64
|
+
*/
|
65
|
+
comment
|
66
|
+
end
|
67
|
+
|
68
|
+
before do
|
69
|
+
collection.add_doc_block(comment, 'fake_file.sass')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'displays a warning' do
|
73
|
+
expect(Hologram::DisplayMessage).to receive(:warning)
|
74
|
+
collection.add_doc_block(duplicate_comment, 'fake_file.sass')
|
75
|
+
end
|
76
|
+
end
|
52
77
|
end
|
53
78
|
|
54
79
|
context '#create_nested_structure' do
|
data/spec/doc_builder_spec.rb
CHANGED
@@ -131,6 +131,32 @@ describe Hologram::DocBuilder do
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
+
context '#initialize' do
|
135
|
+
subject { Hologram::DocBuilder.new(config) }
|
136
|
+
|
137
|
+
context 'when the "exit_on_warnings" option is passed in as true' do
|
138
|
+
let(:config) do
|
139
|
+
{ 'exit_on_warnings' => true }
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'calls DisplayMessage.exit_on_warnings!' do
|
143
|
+
expect(Hologram::DisplayMessage).to receive(:exit_on_warnings!)
|
144
|
+
subject
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'when the "exit_on_warnings" option is not passed in' do
|
149
|
+
let(:config) do
|
150
|
+
{ }
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'does not call DisplayMessage.exit_on_warnings!' do
|
154
|
+
expect(Hologram::DisplayMessage).not_to receive(:exit_on_warnings!)
|
155
|
+
subject
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
134
160
|
context '#is_valid?' do
|
135
161
|
|
136
162
|
let(:config) do
|
@@ -204,8 +230,6 @@ describe Hologram::DocBuilder do
|
|
204
230
|
end
|
205
231
|
|
206
232
|
context '#build' do
|
207
|
-
let(:style_files) { Dir[File.expand_path('../fixtures/styleguide/**/*.*', __FILE__)] }
|
208
|
-
let(:processed_files) { Dir[File.join(builder.destination, '.', '**/*.*')] }
|
209
233
|
let(:config_path) { File.join(Dir.pwd, 'spec/fixtures/source/config.yml') }
|
210
234
|
let(:config_copy_path) { File.join(Dir.pwd, 'spec/fixtures/source/config.yml.copy') }
|
211
235
|
let(:builder) { Hologram::DocBuilder.from_yaml(config_copy_path) }
|
@@ -226,9 +250,8 @@ describe Hologram::DocBuilder do
|
|
226
250
|
|
227
251
|
it 'builds a styleguide' do
|
228
252
|
builder.build
|
229
|
-
|
230
|
-
|
231
|
-
end
|
253
|
+
expect(File.read(File.expand_path('../fixtures/styleguide/base_css.html', __FILE__))).to eq File.read(File.join(builder.destination, '.', 'base_css.html'))
|
254
|
+
expect(File.read(File.expand_path('../fixtures/styleguide/index.html', __FILE__))).to eq File.read(File.join(builder.destination, '.', 'index.html'))
|
232
255
|
end
|
233
256
|
end
|
234
257
|
end
|
data/spec/doc_parser_spec.rb
CHANGED
@@ -15,6 +15,19 @@ Markdown stuff
|
|
15
15
|
eos
|
16
16
|
end
|
17
17
|
|
18
|
+
let(:docs_child) do
|
19
|
+
<<-eos
|
20
|
+
/*doc
|
21
|
+
---
|
22
|
+
parent: otherStyle
|
23
|
+
title: Other Style Child
|
24
|
+
name: otherStyleChild
|
25
|
+
---
|
26
|
+
Markdown stuff
|
27
|
+
*/
|
28
|
+
eos
|
29
|
+
end
|
30
|
+
|
18
31
|
let(:child_doc) do
|
19
32
|
<<-eos
|
20
33
|
/*doc
|
@@ -28,6 +41,19 @@ Markdown stuff
|
|
28
41
|
eos
|
29
42
|
end
|
30
43
|
|
44
|
+
let(:grandchild_doc) do
|
45
|
+
<<-eos
|
46
|
+
/*doc
|
47
|
+
---
|
48
|
+
parent: otherStyle
|
49
|
+
name: grandbaby
|
50
|
+
title: Grandbaby
|
51
|
+
---
|
52
|
+
Markdown stuff
|
53
|
+
*/
|
54
|
+
eos
|
55
|
+
end
|
56
|
+
|
31
57
|
let(:multi_category_child_doc) do
|
32
58
|
<<-eos
|
33
59
|
/*doc
|
@@ -77,10 +103,10 @@ multi-parent
|
|
77
103
|
expect(output_files_by_category).to be_a Hash
|
78
104
|
end
|
79
105
|
|
80
|
-
context
|
106
|
+
context 'when the source has multiple paths' do
|
81
107
|
subject(:parser) { Hologram::DocParser.new(['spec/fixtures/source/colors', 'spec/fixtures/source/components'], nil, plugins) }
|
82
108
|
|
83
|
-
it
|
109
|
+
it 'parses all sources' do
|
84
110
|
expect(pages['base_css.html'][:md]).to include 'Base colors'
|
85
111
|
expect(pages['base_css.html'][:md]).to include 'Background Colors'
|
86
112
|
end
|
@@ -123,6 +149,30 @@ multi-parent
|
|
123
149
|
it 'takes the category in a collection and treats them as the page names' do
|
124
150
|
expect(pages.keys).to include 'foo.html'
|
125
151
|
end
|
152
|
+
|
153
|
+
context 'when nav_level is set to section' do
|
154
|
+
before do
|
155
|
+
File.open(temp_doc, 'a+'){ |io| io << docs_child }
|
156
|
+
parser.nav_level = 'section'
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'generates navigation to children from their parent' do
|
160
|
+
parser.parse
|
161
|
+
expect(pages['foo.html'][:md]).to include '<li><a href="#otherStyleChild">Other Style Child</a></li>'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'when nav_level is not set' do
|
166
|
+
before do
|
167
|
+
File.open(temp_doc, 'a+'){ |io| io << docs_child }
|
168
|
+
parser.nav_level = nil
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should not generate sub navigation' do
|
172
|
+
parser.parse
|
173
|
+
expect(pages['foo.html'][:md]).not_to include '<li><a href="#otherStyleChild">Other Style Child</a></li>'
|
174
|
+
end
|
175
|
+
end
|
126
176
|
end
|
127
177
|
|
128
178
|
context 'when a source doc is a child' do
|
@@ -132,16 +182,26 @@ multi-parent
|
|
132
182
|
FileUtils.rm(temp_doc)
|
133
183
|
end
|
134
184
|
|
135
|
-
before do
|
136
|
-
parser.parse
|
137
|
-
end
|
138
|
-
|
139
185
|
it 'appends the child doc to the category page' do
|
186
|
+
parser.parse
|
140
187
|
expect(pages['base_css.html'][:md]).to include 'Some other style'
|
141
188
|
end
|
142
189
|
|
143
190
|
it 'assigns the child doc a deeper header' do
|
144
|
-
|
191
|
+
parser.parse
|
192
|
+
expect(pages['base_css.html'][:md]).to include '<h2 id="otherStyle" class="styleguide">Some other style</h2>'
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'when nav_level is set to all' do
|
196
|
+
before do
|
197
|
+
File.open(temp_doc, 'a+'){ |io| io << grandchild_doc }
|
198
|
+
parser.nav_level = 'all'
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'generates navigation to grandchildren from their parent' do
|
202
|
+
parser.parse
|
203
|
+
expect(pages['base_css.html'][:md]).to include '<li><a href="#grandbaby">Grandbaby</a></li>'
|
204
|
+
end
|
145
205
|
end
|
146
206
|
end
|
147
207
|
|
data/spec/document_block_spec.rb
CHANGED
@@ -116,8 +116,39 @@ eos
|
|
116
116
|
end
|
117
117
|
|
118
118
|
context '#markdown_with_heading' do
|
119
|
-
|
120
|
-
|
119
|
+
context 'when include_sub_nav is false' do
|
120
|
+
it 'returns markdown with a specified header' do
|
121
|
+
expect(doc_block.markdown_with_heading(2)).to eql "\n\n<h2 id=\"foo\" class=\"styleguide\">baz</h2>blah"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when include_sub_nav is true' do
|
126
|
+
context 'when the component has no children' do
|
127
|
+
it 'returns markdown with no nav' do
|
128
|
+
expect(doc_block.markdown_with_heading(2, include_sub_nav: true)).to eql "\n\n<h2 id=\"foo\" class=\"styleguide\">baz</h2>blah"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'when the component has children' do
|
133
|
+
before do
|
134
|
+
doc_block.children['child-one'] = double( name: 'child-one', title: 'Child 1' )
|
135
|
+
doc_block.children['child-two'] = double( name: 'child-two', title: 'Child 2' )
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'returns markdown with no nav' do
|
139
|
+
expected_output = <<-eos
|
140
|
+
|
141
|
+
|
142
|
+
<h2 id="foo" class="styleguide">baz</h2>
|
143
|
+
<ul class="section-nav">
|
144
|
+
<li><a href="#child-one">Child 1</a></li>
|
145
|
+
<li><a href="#child-two">Child 2</a></li>
|
146
|
+
</ul>
|
147
|
+
blah
|
148
|
+
eos
|
149
|
+
expect(doc_block.markdown_with_heading(2, include_sub_nav: true)).to eql expected_output.rstrip
|
150
|
+
end
|
151
|
+
end
|
121
152
|
end
|
122
153
|
end
|
123
154
|
end
|