smartgen 0.1.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.
- 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
|