hologram 1.2.0 → 1.3.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 +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
|