smartgen 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.md +4 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +61 -0
- data/README.md +119 -0
- data/Rakefile +8 -0
- data/bin/smartgen +25 -0
- data/lib/smartgen.rb +21 -0
- data/lib/smartgen/configuration.rb +17 -0
- data/lib/smartgen/engines.rb +3 -0
- data/lib/smartgen/engines/base.rb +45 -0
- data/lib/smartgen/engines/markdown.rb +16 -0
- data/lib/smartgen/engines/textile.rb +16 -0
- data/lib/smartgen/generator.rb +104 -0
- data/lib/smartgen/markup_file.rb +47 -0
- data/lib/smartgen/object_hash.rb +41 -0
- data/lib/smartgen/renderers.rb +1 -0
- data/lib/smartgen/renderers/erb.rb +12 -0
- data/lib/smartgen/resource.rb +32 -0
- data/lib/smartgen/version.rb +4 -0
- data/spec/fixtures/expectations/common/another_index.html +13 -0
- data/spec/fixtures/expectations/common/index.html +8 -0
- data/spec/fixtures/expectations/common/other_index.html +13 -0
- data/spec/fixtures/expectations/with_layout/index.html +12 -0
- data/spec/fixtures/expectations/with_layout/index_with_metadata.html +43 -0
- data/spec/fixtures/expectations/with_layout/index_with_specific_metadata.html +44 -0
- data/spec/fixtures/src/assets/images/image.gif +0 -0
- data/spec/fixtures/src/assets/javascripts/somelib.js +2 -0
- data/spec/fixtures/src/assets/stylesheets/style.css +2 -0
- data/spec/fixtures/src/common/another_index.md +12 -0
- data/spec/fixtures/src/common/index.textile +10 -0
- data/spec/fixtures/src/common/other_index.markdown +12 -0
- data/spec/fixtures/src/layout.html.erb +5 -0
- data/spec/fixtures/src/layout_with_metadata.html.erb +22 -0
- data/spec/fixtures/src/layout_with_specific_metadata.html.erb +23 -0
- data/spec/fixtures/src/metadata.yml +43 -0
- data/spec/fixtures/src/with_layout/index.textile +10 -0
- data/spec/fixtures/src/with_layout/index_with_specific_metadata.textile +10 -0
- data/spec/lib/smartgen/configuration_spec.rb +30 -0
- data/spec/lib/smartgen/engines/base_spec.rb +71 -0
- data/spec/lib/smartgen/engines/markdown_spec.rb +23 -0
- data/spec/lib/smartgen/engines/textile_spec.rb +19 -0
- data/spec/lib/smartgen/generator_spec.rb +166 -0
- data/spec/lib/smartgen/markup_file_spec.rb +128 -0
- data/spec/lib/smartgen/object_hash_spec.rb +54 -0
- data/spec/lib/smartgen/renderers/erb_spec.rb +32 -0
- data/spec/lib/smartgen/resource_spec.rb +60 -0
- data/spec/lib/smartgen_spec.rb +18 -0
- data/spec/sandbox/.gitkeep +0 -0
- data/spec/spec_helper.rb +37 -0
- metadata +240 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Smartgen::Configuration do
|
4
|
+
matcher :be_an_empty_array do
|
5
|
+
match { |actual| actual.instance_of?(Array) && actual.empty? }
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "defaults" do
|
9
|
+
it "should initialize src_files to an empty array" do
|
10
|
+
subject.src_files.should be_an_empty_array
|
11
|
+
subject.src_files.should be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should initialize output folder to 'tmp'" do
|
15
|
+
subject.output_folder.should == 'tmp'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should initialize layout to nil" do
|
19
|
+
subject.layout.should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should initialize assets to an empty array" do
|
23
|
+
subject.assets.should be_an_empty_array
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should initialize metadata_file to 'metadata.yml'" do
|
27
|
+
subject.metadata_file.should == 'metadata.yml'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Smartgen::Engine::Base do
|
4
|
+
describe "processing" do
|
5
|
+
it "should just return body" do
|
6
|
+
body = 'body'
|
7
|
+
subject.process(body).should == body
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "pre processing" do
|
11
|
+
before do
|
12
|
+
Smartgen::Engine::Base.pre_processors = []
|
13
|
+
end
|
14
|
+
|
15
|
+
context "without pre processors" do
|
16
|
+
it "should just return body" do
|
17
|
+
body = 'body'
|
18
|
+
subject.process(body).should == body
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with pre processors" do
|
23
|
+
class PreProcessor
|
24
|
+
def process(body) # just needs to respond_to?(:process)
|
25
|
+
"<pre_processed>#{body}</pre_processed>"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should pre process body" do
|
30
|
+
Smartgen::Engine::Base.register(PreProcessor.new)
|
31
|
+
|
32
|
+
body = 'body'
|
33
|
+
subject.process(body).should == "<pre_processed>#{body}</pre_processed>"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should do run pre processors in the order they were registered" do
|
37
|
+
class AnotherPreProcessor
|
38
|
+
def process(body)
|
39
|
+
body.gsub(/pre_processed/, 'another')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Smartgen::Engine::Base.register(PreProcessor.new)
|
44
|
+
Smartgen::Engine::Base.register(AnotherPreProcessor.new)
|
45
|
+
|
46
|
+
body = 'body'
|
47
|
+
subject.process(body).should == "<another>#{body}</another>"
|
48
|
+
end
|
49
|
+
|
50
|
+
context "of a subclass" do
|
51
|
+
class OtherPreProcessor
|
52
|
+
def process(body)
|
53
|
+
"<another>#{body}</another>"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class MyCustomEngine < Smartgen::Engine::Base
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should pre process body with different processor of ancestor" do
|
61
|
+
Smartgen::Engine::Base.register(PreProcessor.new)
|
62
|
+
MyCustomEngine.register(OtherPreProcessor.new)
|
63
|
+
|
64
|
+
body = 'body'
|
65
|
+
MyCustomEngine.new.process(body).should == "<another>#{body}</another>"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Smartgen::Engine::Markdown do
|
4
|
+
def body
|
5
|
+
"# Some Header\n\nSome paragraph"
|
6
|
+
end
|
7
|
+
|
8
|
+
def contents
|
9
|
+
"<h1>Some Header</h1>\n\n<p>Some paragraph</p>"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should process body using BlueCloth" do
|
13
|
+
subject.process(body).should == contents
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should support .md extension" do
|
17
|
+
should be_supported('.md')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should support .markdown extension" do
|
21
|
+
should be_supported('.markdown')
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Smartgen::Engine::Textile do
|
4
|
+
def body
|
5
|
+
"h1. Some Header\n\nSome paragraph"
|
6
|
+
end
|
7
|
+
|
8
|
+
def contents
|
9
|
+
"<h1>Some Header</h1>\n<p>Some paragraph</p>"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should process body using RedCloth" do
|
13
|
+
subject.process(body).should == contents
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should support .textile extension" do
|
17
|
+
should be_supported('.textile')
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
describe Smartgen::Generator do
|
5
|
+
def src_files
|
6
|
+
[fixture('src/common/**/*')]
|
7
|
+
end
|
8
|
+
|
9
|
+
def output_folder
|
10
|
+
sandbox('doc')
|
11
|
+
end
|
12
|
+
|
13
|
+
def output_folder_file(path)
|
14
|
+
File.join(output_folder, path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def actual_src_files
|
18
|
+
Dir[*src_files].select { |f| ['.textile', '.markdown', '.md'].include?(File.extname(f)) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def actual_src_filenames
|
22
|
+
actual_src_files.map { |f| [File.basename(f, File.extname(f)), File.extname(f)] }
|
23
|
+
end
|
24
|
+
|
25
|
+
def read_output(filename)
|
26
|
+
File.read(output_folder_file(filename))
|
27
|
+
end
|
28
|
+
|
29
|
+
def read_fixture(filename)
|
30
|
+
File.read(fixture(filename))
|
31
|
+
end
|
32
|
+
|
33
|
+
def arguments
|
34
|
+
[src_files, output_folder]
|
35
|
+
end
|
36
|
+
|
37
|
+
def options
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
|
41
|
+
subject { Smartgen::Generator.new arguments, options, { :verbose => false } }
|
42
|
+
|
43
|
+
before do
|
44
|
+
FileUtils.rm_rf output_folder
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "generation" do
|
48
|
+
it "should create the output folder" do
|
49
|
+
capture(:stdout) { subject.invoke_all }
|
50
|
+
File.should be_directory(output_folder)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should create HTML files for each markup template in src_files" do
|
54
|
+
capture(:stdout) { subject.invoke_all }
|
55
|
+
|
56
|
+
actual_src_filenames.each do |src_filename, src_ext|
|
57
|
+
File.should be_file(output_folder_file("#{src_filename}.html"))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should convert markup files into HTML files when generating" do
|
62
|
+
capture(:stdout) { subject.invoke_all }
|
63
|
+
actual_src_filenames.each do |src_filename, src_ext|
|
64
|
+
read_output("#{src_filename}.html").should == read_fixture("expectations/common/#{src_filename}.html")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should always force generation of each file, even if it exists" do
|
69
|
+
FileUtils.mkdir_p(output_folder)
|
70
|
+
File.open(output_folder_file("index.html"), 'w') { |f| f.write('old contents') }
|
71
|
+
capture(:stdout) { subject.invoke_all }
|
72
|
+
read_output("index.html").should == read_fixture("expectations/common/index.html")
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "with layout" do
|
76
|
+
def src_files
|
77
|
+
[fixture('src/with_layout/index.textile')]
|
78
|
+
end
|
79
|
+
|
80
|
+
def options
|
81
|
+
{ :layout => fixture('src/layout.html.erb') }
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should use the layout when generating" do
|
85
|
+
capture(:stdout) { subject.invoke_all }
|
86
|
+
read_output("index.html").should == read_fixture("expectations/with_layout/index.html")
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "and metadata" do
|
90
|
+
def options
|
91
|
+
{ :layout => fixture('src/layout_with_metadata.html.erb'), :metadata_file => fixture('src/metadata.yml') }
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should load metadata from file and expose it when rendering files" do
|
95
|
+
capture(:stdout) { subject.invoke_all }
|
96
|
+
read_output("index.html").should == read_fixture("expectations/with_layout/index_with_metadata.html")
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "using conventions" do
|
100
|
+
def src_files
|
101
|
+
[fixture('src/with_layout/index_with_specific_metadata.textile')]
|
102
|
+
end
|
103
|
+
|
104
|
+
def options
|
105
|
+
{ :layout => fixture('src/layout_with_specific_metadata.html.erb'), :metadata_file => fixture('src/metadata.yml') }
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should expose metadata for current page data for each file in metadata.current_page" do
|
109
|
+
capture(:stdout) { subject.invoke_all }
|
110
|
+
read_output("index_with_specific_metadata.html").should == read_fixture("expectations/with_layout/index_with_specific_metadata.html")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "assets" do
|
117
|
+
def assets
|
118
|
+
[fixture("src/assets/images"), fixture("src/assets/javascripts"), fixture("src/assets/stylesheets")]
|
119
|
+
end
|
120
|
+
|
121
|
+
def options
|
122
|
+
{ :assets => assets }
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should copy directories to output folder" do
|
126
|
+
capture(:stdout) { subject.invoke_all }
|
127
|
+
|
128
|
+
File.should be_directory(output_folder_file('images'))
|
129
|
+
File.should be_directory(output_folder_file('javascripts'))
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should copy the contents of the given directories to output folder" do
|
133
|
+
capture(:stdout) { subject.invoke_all }
|
134
|
+
|
135
|
+
File.should be_file(output_folder_file('images/image.gif'))
|
136
|
+
File.should be_file(output_folder_file('javascripts/somelib.js'))
|
137
|
+
File.should be_file(output_folder_file('stylesheets/style.css'))
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should force copy of the contents of the given directories to output folder" do
|
141
|
+
FileUtils.mkdir_p(output_folder_file('javascripts'))
|
142
|
+
File.open(output_folder_file('javascripts/somelib.js'), 'w') { |f| f.write('//some code') }
|
143
|
+
|
144
|
+
capture(:stdout) { subject.invoke_all }
|
145
|
+
read_output('javascripts/somelib.js').should == read_fixture('src/assets/javascripts/somelib.js')
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "renderer registration" do
|
151
|
+
it "should register ERB renderer by default" do
|
152
|
+
Smartgen::Generator.renderer.should be_an_instance_of(Smartgen::Renderer::ERB)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should allow the registration of a custom renderer" do
|
156
|
+
class MyRenderer
|
157
|
+
def render(layout, markup_file)
|
158
|
+
"do some rendering stuff"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
Smartgen::Generator.renderer = MyRenderer.new
|
163
|
+
Smartgen::Generator.renderer.render('some_layout', mock(Smartgen::MarkupFile)).should == "do some rendering stuff"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Smartgen::MarkupFile do
|
4
|
+
def path
|
5
|
+
fixture('src/common/index.textile')
|
6
|
+
end
|
7
|
+
|
8
|
+
subject { Smartgen::MarkupFile.new path }
|
9
|
+
|
10
|
+
describe "engine registration" do
|
11
|
+
before do
|
12
|
+
Smartgen::MarkupFile.engines.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
after do
|
16
|
+
Smartgen::MarkupFile.engines.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should register textile engine by default" do
|
20
|
+
Smartgen::MarkupFile.engines.one? { |engine| engine.instance_of?(Smartgen::Engine::Textile) }.should be_true, "Textile was not registered as engine"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should register markdown engine by default" do
|
24
|
+
Smartgen::MarkupFile.engines.one? { |engine| engine.instance_of?(Smartgen::Engine::Markdown) }.should be_true, "Markdown was not registered as engine"
|
25
|
+
end
|
26
|
+
|
27
|
+
class MyEngine < Smartgen::Engine::Base
|
28
|
+
protected
|
29
|
+
def parse(body)
|
30
|
+
"some processing"
|
31
|
+
end
|
32
|
+
|
33
|
+
def extensions
|
34
|
+
['.something', '.otherext']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should register an engine" do
|
39
|
+
Smartgen::MarkupFile.register(MyEngine)
|
40
|
+
Smartgen::MarkupFile.engines.one? { |engine| engine.instance_of?(MyEngine) }.should be_true, "MyEngine was not registered as engine"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should register the engine with high priority" do
|
44
|
+
Smartgen::MarkupFile.register(MyEngine)
|
45
|
+
Smartgen::MarkupFile.engines.first.should be_an_instance_of(MyEngine)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "attributes" do
|
50
|
+
it "should have a file path" do
|
51
|
+
subject.path.should == path
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should have a filename" do
|
55
|
+
subject.filename.should == File.basename(path, File.extname(path))
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have an extension" do
|
59
|
+
subject.extension.should == File.extname(path)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "contents" do
|
64
|
+
it "should returns its raw contents" do
|
65
|
+
subject.raw_contents.should == File.read(path)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return its contents" do
|
69
|
+
subject.contents.should == File.read(fixture('expectations/common/index.html'))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "engines usage" do
|
74
|
+
context "using default engine" do
|
75
|
+
it "should use textile as markup engine when using defaults for files without extension" do
|
76
|
+
def path
|
77
|
+
fixture('src/common/somefile')
|
78
|
+
end
|
79
|
+
|
80
|
+
subject.engine.should be_an_instance_of(Smartgen::Engine::Textile)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should use the engine with the highest priority for files without extension" do
|
84
|
+
class MyEngine
|
85
|
+
def process(body)
|
86
|
+
"some processing"
|
87
|
+
end
|
88
|
+
|
89
|
+
def supported?(extension)
|
90
|
+
['.something'].include?(extension)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def path
|
95
|
+
fixture('src/common/somefile')
|
96
|
+
end
|
97
|
+
|
98
|
+
Smartgen::MarkupFile.register(MyEngine)
|
99
|
+
subject.engine.should be_an_instance_of(MyEngine)
|
100
|
+
Smartgen::MarkupFile.engines.clear
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "using textile engine" do
|
105
|
+
it "should use textile as markup engine" do
|
106
|
+
subject.engine.should be_an_instance_of(Smartgen::Engine::Textile)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "using markdown template" do
|
111
|
+
it "should use textile as markup engine for files with .markdown" do
|
112
|
+
def path
|
113
|
+
fixture('src/common/other_index.markdown')
|
114
|
+
end
|
115
|
+
|
116
|
+
subject.engine.should be_an_instance_of(Smartgen::Engine::Markdown)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should use textile as markup engine for files with .md" do
|
120
|
+
def path
|
121
|
+
fixture('src/common/other_index.md')
|
122
|
+
end
|
123
|
+
|
124
|
+
subject.engine.should be_an_instance_of(Smartgen::Engine::Markdown)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|