hologram 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -4
  3. data/Rakefile +5 -0
  4. data/hologram.gemspec +1 -1
  5. data/lib/hologram.rb +13 -445
  6. data/lib/hologram/display_message.rb +79 -0
  7. data/lib/hologram/doc_block_collection.rb +48 -0
  8. data/lib/hologram/doc_builder.rb +196 -0
  9. data/lib/hologram/doc_parser.rb +125 -0
  10. data/lib/hologram/document_block.rb +36 -0
  11. data/lib/hologram/template_variables.rb +21 -0
  12. data/lib/hologram/version.rb +1 -1
  13. data/lib/template/doc_assets/_header.html +7 -2
  14. data/lib/template/hologram_config.yml +3 -0
  15. data/spec/display_message_spec.rb +115 -0
  16. data/spec/doc_block_collection_spec.rb +80 -0
  17. data/spec/doc_builder_spec.rb +92 -0
  18. data/spec/doc_parser_spec.rb +89 -0
  19. data/spec/document_block_spec.rb +62 -0
  20. data/spec/fixtures/source/components/background/backgrounds.css +46 -0
  21. data/spec/fixtures/source/components/button/buttons.css +87 -0
  22. data/spec/fixtures/source/components/button/skin/buttonSkins.css +113 -0
  23. data/spec/fixtures/source/components/index.md +23 -0
  24. data/spec/fixtures/source/config.yml +17 -0
  25. data/spec/fixtures/source/extra/css/screen.css +1 -0
  26. data/spec/fixtures/source/templates/_footer.html +9 -0
  27. data/spec/fixtures/source/templates/_header.html +57 -0
  28. data/spec/fixtures/source/templates/static/css/doc.css +132 -0
  29. data/spec/fixtures/styleguide/base_css.html +170 -0
  30. data/spec/fixtures/styleguide/extra/css/screen.css +1 -0
  31. data/spec/fixtures/styleguide/index.html +84 -0
  32. data/spec/fixtures/styleguide/static/css/doc.css +132 -0
  33. data/spec/spec_helper.rb +7 -0
  34. metadata +66 -22
@@ -0,0 +1,36 @@
1
+ module Hologram
2
+ class DocumentBlock
3
+ attr_accessor :name, :parent, :children, :title, :category, :markdown, :config, :heading
4
+
5
+ def initialize(config = nil, markdown = nil)
6
+ @children = {}
7
+ set_members(config, markdown) if config and markdown
8
+ end
9
+
10
+ def set_members(config, markdown)
11
+ @name = config['name']
12
+ @category = config['category']
13
+ @title = config['title']
14
+ @parent = config['parent']
15
+ @markdown = markdown
16
+ end
17
+
18
+ def get_hash
19
+ {:name => @name,
20
+ :parent => @parent,
21
+ :category => @category,
22
+ :title => @title
23
+ }
24
+ end
25
+
26
+ def is_valid?
27
+ !!(@name && @markdown)
28
+ end
29
+
30
+ # sets the header tag based on how deep your nesting is
31
+ def markdown_with_heading(heading = 1)
32
+ @markdown = "\n\n<h#{heading.to_s} id=\"#{@name}\">#{@title}</h#{heading.to_s}>" + @markdown
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,21 @@
1
+ module Hologram
2
+
3
+ #Helper class for binding things for ERB
4
+ class TemplateVariables
5
+ attr_accessor :title, :file_name, :blocks, :categories
6
+
7
+ def initialize(args)
8
+ set_args(args)
9
+ end
10
+
11
+ def set_args(args)
12
+ args.each do |k,v|
13
+ instance_variable_set("@#{k}", v) unless v.nil?
14
+ end
15
+ end
16
+
17
+ def get_binding
18
+ binding()
19
+ end
20
+ end
21
+ end
@@ -25,5 +25,5 @@
25
25
  # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
26
 
27
27
  module Hologram
28
- VERSION = "0.6.0"
28
+ VERSION = "1.0.0"
29
29
  end
@@ -8,11 +8,16 @@
8
8
 
9
9
  <nav>
10
10
  <ul>
11
- <% for b in blocks %>
12
- <li><a href="#<%= b[:name] %>"><%= b[:title] %></a></li>
11
+ <% @categories.each do |category, file_name| %>
12
+ <li><a href="<%= file_name %>"><%= category %></a></li>
13
13
  <% end %>
14
14
  </ul>
15
15
  </nav>
16
16
 
17
17
  <h1>a brand new style guide, it's super effective</h1>
18
18
  <section class="content">
19
+ <ul>
20
+ <% @blocks.each do |b| %>
21
+ <li><a href="#<%= b[:name] %>"><%= b[:title] %></a></li>
22
+ <% end %>
23
+ </ul>
@@ -1,3 +1,6 @@
1
+ # Hologram will run from same directory where this config file resides
2
+ # All paths should be relative to there
3
+
1
4
  # The directory containing the source files to parse recursively
2
5
  source: ./sass
3
6
 
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ describe Hologram::DisplayMessage do
5
+ subject(:display) { Hologram::DisplayMessage }
6
+
7
+ #Rails kernerl helper
8
+ def capture(stream)
9
+ stream = stream.to_s
10
+ captured_stream = Tempfile.new(stream)
11
+ stream_io = eval("$#{stream}")
12
+ origin_stream = stream_io.dup
13
+ stream_io.reopen(captured_stream)
14
+
15
+ yield
16
+
17
+ stream_io.rewind
18
+ return captured_stream.read
19
+ ensure
20
+ captured_stream.unlink
21
+ stream_io.reopen(origin_stream)
22
+ end
23
+
24
+ context '.quiet!' do
25
+ around do |example|
26
+ display.quiet!
27
+ example.run
28
+ display.show!
29
+ end
30
+
31
+ it 'sets quiet to true' do
32
+ display.quiet!
33
+ expect(display.quiet?).to be_true
34
+ end
35
+ end
36
+
37
+ context '.puts' do
38
+ let(:message) { capture(:stdout) { display.puts('foo') } }
39
+
40
+ it 'puts to console' do
41
+ expect(message).to eql "foo\n"
42
+ end
43
+
44
+ context 'when quiet' do
45
+ around do |example|
46
+ display.quiet!
47
+ example.run
48
+ display.show!
49
+ end
50
+
51
+ it 'does nothing' do
52
+ expect(message).to be_empty
53
+ end
54
+ end
55
+ end
56
+
57
+ context '.error' do
58
+ around do |example|
59
+ display.quiet!
60
+ example.run
61
+ display.show!
62
+ end
63
+
64
+ it 'displays an error in red' do
65
+ expect(display).to receive(:puts).with("\e[32m(╯°□°)╯\e[0m\e[31m︵ ┻━┻ \e[0m\e[31m Build not complete.\e[0m")
66
+ expect(display).to receive(:puts).with(" foo")
67
+
68
+ begin
69
+ display.error('foo')
70
+ rescue SystemExit
71
+ end
72
+ end
73
+
74
+ it 'exits' do
75
+ expect{ display.error('foo') }.to raise_error SystemExit
76
+ end
77
+ end
78
+
79
+ context '.warning' do
80
+ it 'displays a warning message in yellow' do
81
+ expect(display).to receive(:puts).with("\e[33mWarning: foo\e[0m")
82
+ display.warning('foo')
83
+ end
84
+ end
85
+
86
+ context '.colorize' do
87
+ it 'returns a colorized string' do
88
+ expect(display.colorize(31, 'foo')).to eql "\e[31mfoo\e[0m"
89
+ end
90
+ end
91
+
92
+ context '.red' do
93
+ it 'returns a red colorized string' do
94
+ expect(display.red('foo')).to eql display.colorize(31, 'foo')
95
+ end
96
+ end
97
+
98
+ context '.green' do
99
+ it 'returns a green colorized string' do
100
+ expect(display.green('foo')).to eql display.colorize(32, 'foo')
101
+ end
102
+ end
103
+
104
+ context '.yellow' do
105
+ it 'returns a yellow colorized string' do
106
+ expect(display.yellow('foo')).to eql display.colorize(33, 'foo')
107
+ end
108
+ end
109
+
110
+ context '.pink' do
111
+ it 'returns a pink colorized string' do
112
+ expect(display.pink('foo')).to eql display.colorize(35, 'foo')
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hologram::DocBlockCollection do
4
+ let(:comment) do
5
+ comment = <<comment
6
+ /*doc
7
+ ---
8
+ title: Buttons
9
+ name: button
10
+ category: Base CSS
11
+ ---
12
+
13
+ Button styles can be applied to any element. Typically you'll want
14
+ to use either a `<button>` or an `<a>` element:
15
+
16
+ ```html_example
17
+ <button class="btn btnDefault">Click</button>
18
+ <a class="btn btnDefault" href="trulia.com">Trulia!</a>
19
+ ```
20
+
21
+ If your button is actually a link to another page, please use the
22
+ `<a>` element, while if your button performs an action, such as
23
+ submitting a form or triggering some javascript event, then use a
24
+ `<button>` element.
25
+
26
+ */
27
+ comment
28
+ end
29
+
30
+ let(:collection){ Hologram::DocBlockCollection.new }
31
+
32
+ context '#add_doc_block' do
33
+ context 'when the comment is valid' do
34
+ before do
35
+ collection.add_doc_block(comment)
36
+ end
37
+
38
+ it 'adds a doc block to the collection' do
39
+ expect(collection.doc_blocks.size).to eql 1
40
+ end
41
+ end
42
+
43
+ context 'when no yaml is provided' do
44
+ before do
45
+ collection.add_doc_block('')
46
+ end
47
+
48
+ it 'does not add a new block' do
49
+ expect(collection.doc_blocks.size).to eql 0
50
+ end
51
+ end
52
+ end
53
+
54
+ context '#create_nested_structure' do
55
+ context 'when the collection has blocks with parents' do
56
+ before do
57
+ collection.add_doc_block(comment)
58
+ collection.add_doc_block(%q{
59
+ /*doc
60
+ ---
61
+ title: foo
62
+ name: bah
63
+ parent: button
64
+ ---
65
+ some other button style
66
+ */})
67
+
68
+ collection.create_nested_structure
69
+ end
70
+
71
+ it 'removes the child block from the collection level' do
72
+ expect(collection.doc_blocks.size).to eql 1
73
+ end
74
+
75
+ it 'nests the doc block as a child of the parent block' do
76
+ expect(collection.doc_blocks['button'].children.size).to eql 1
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hologram::DocBuilder do
4
+ subject(:builder) { Hologram::DocBuilder.new }
5
+
6
+ context '#init' do
7
+ around do |example|
8
+ Hologram::DisplayMessage.quiet!
9
+ example.run
10
+ Hologram::DisplayMessage.show!
11
+ end
12
+
13
+ context 'when passed an invalid config' do
14
+ before do
15
+ File.open('bad_config.yml', 'w'){ |io| io << '%' }
16
+ end
17
+
18
+ after do
19
+ FileUtils.rm('bad_config.yml')
20
+ end
21
+
22
+ it 'exits the process' do
23
+ expect { builder.init(['bad_config.yml']) }.to raise_error SystemExit
24
+ end
25
+ end
26
+
27
+ context 'when passed a config file' do
28
+ let(:style_files) { Dir[File.expand_path('../fixtures/styleguide/**/*.*', __FILE__)] }
29
+ let(:config_path) { File.join(Dir.pwd, 'spec/fixtures/source/config.yml') }
30
+ let(:config_copy_path) { File.join(Dir.pwd, 'spec/fixtures/source/config.yml.copy') }
31
+
32
+ around do |example|
33
+ Dir.mktmpdir do |tmpdir|
34
+ FileUtils.cp(config_path, config_copy_path)
35
+ File.open(config_copy_path, 'a'){ |io| io << "destination: #{tmpdir}" }
36
+ current_dir = Dir.pwd
37
+ Dir.chdir(tmpdir)
38
+
39
+ example.run
40
+
41
+ Dir.chdir(current_dir)
42
+ FileUtils.rm(config_copy_path)
43
+ end
44
+ end
45
+
46
+ before do
47
+ builder.init([config_copy_path])
48
+ end
49
+
50
+ it 'builds a styleguide' do
51
+ processed_files = Dir[File.join('.', '**/*.*')]
52
+ processed_files.each_with_index do |file, index|
53
+ expect(FileUtils.cmp(file, style_files[index])).to be_true
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'when passed "init" as arg' do
59
+ around do |example|
60
+ Dir.mktmpdir do |dir|
61
+ Dir.chdir(dir) do
62
+ example.run
63
+ end
64
+ end
65
+ end
66
+
67
+ before do
68
+ builder.init(['init'])
69
+ end
70
+
71
+ it 'creates a config file' do
72
+ expect(File.exists?('hologram_config.yml')).to be_true
73
+ end
74
+
75
+ it 'creates default assets' do
76
+ Dir.chdir('doc_assets') do
77
+ ['_header.html', '_footer.html'].each do |asset|
78
+ expect(File.exists?(asset)).to be_true
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'when a hologram_config.yml already exists' do
84
+ it 'does nothing' do
85
+ open('hologram_config.yml', 'w') {|io|io << 'foo'}
86
+ builder.init(['init'])
87
+ expect(IO.read('hologram_config.yml')).to eql('foo')
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hologram::DocParser do
4
+
5
+ let(:doc) do
6
+ <<-eos
7
+ /*doc
8
+ ---
9
+ title: Some other style
10
+ name: otherStyle
11
+ category: Foo
12
+ ---
13
+ Markdown stuff
14
+ */
15
+ eos
16
+ end
17
+
18
+ let(:child_doc) do
19
+ <<-eos
20
+ /*doc
21
+ ---
22
+ parent: button
23
+ name: otherStyle
24
+ title: Some other style
25
+ ---
26
+ Markdown stuff
27
+ */
28
+ eos
29
+ end
30
+
31
+ let(:source_path) { 'spec/fixtures/source' }
32
+ let(:temp_doc) { File.join(source_path, 'components', 'button', 'skin', 'testSkin.css') }
33
+
34
+ subject(:parser) { Hologram::DocParser.new('spec/fixtures/source') }
35
+
36
+ context '#parse' do
37
+ let(:result) { parser.parse }
38
+
39
+ it 'builds and returns a hash of pages' do
40
+ expect(result).to be_a Hash
41
+ end
42
+
43
+ context 'when an index page is specified' do
44
+ subject(:parser) { Hologram::DocParser.new('spec/fixtures/source', 'foo') }
45
+
46
+ around do |example|
47
+ File.open(temp_doc, 'a+'){ |io| io << doc }
48
+ example.run
49
+ FileUtils.rm(temp_doc)
50
+ end
51
+
52
+ it 'uses that page as the index' do
53
+ expect(result['index.html'][:md]).to include 'Markdown stuff'
54
+ end
55
+ end
56
+
57
+ context 'when the source is a parent doc' do
58
+ around do |example|
59
+ File.open(temp_doc, 'a+'){ |io| io << doc }
60
+ example.run
61
+ FileUtils.rm(temp_doc)
62
+ end
63
+
64
+ it 'takes the category in a collection and treats them as the page names' do
65
+ expect(result.keys).to include 'foo.html'
66
+ end
67
+ end
68
+
69
+ context 'when a source doc is a child' do
70
+ around do |example|
71
+ File.open(temp_doc, 'a+'){ |io| io << child_doc }
72
+ example.run
73
+ FileUtils.rm(temp_doc)
74
+ end
75
+
76
+ before do
77
+ parser.parse
78
+ end
79
+
80
+ it 'appends the child doc to the category page' do
81
+ expect(result['base_css.html'][:md]).to include 'Some other style'
82
+ end
83
+
84
+ it 'assigns the child doc a deeper header' do
85
+ expect(result['base_css.html'][:md]).to include '<h2 id="otherStyle">Some other style</h2>'
86
+ end
87
+ end
88
+ end
89
+ end