nanoc-oo 0.0.1

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.
Files changed (54) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +31 -0
  6. data/Rakefile +1 -0
  7. data/bin/nanoc-oo +17 -0
  8. data/cucumber.yml +8 -0
  9. data/data/nanoc-oo/wrapper/Rules +115 -0
  10. data/data/nanoc-oo/wrapper/lib/classes/1_page.rb +198 -0
  11. data/data/nanoc-oo/wrapper/lib/fake_dir.rb +27 -0
  12. data/data/nanoc-oo/wrapper/lib/fake_item.rb +39 -0
  13. data/data/nanoc-oo/wrapper/lib/fake_items.rb +22 -0
  14. data/data/nanoc-oo/wrapper/lib/filter_for.rb +14 -0
  15. data/data/nanoc-oo/wrapper/lib/item_class.rb +22 -0
  16. data/features/_related_tests.feature +32 -0
  17. data/features/composite_file.example +82 -0
  18. data/features/move_children.example +43 -0
  19. data/features/paginate_article.example +86 -0
  20. data/features/step_definitions/complex_steps.rb +23 -0
  21. data/features/step_definitions/nanoc-oo_steps.rb +9 -0
  22. data/features/step_definitions/nanoc_steps.rb +22 -0
  23. data/features/step_definitions/steps.rb +1 -0
  24. data/features/support/env.rb +25 -0
  25. data/features/support/my_extension.rb +16 -0
  26. data/features/support/nice_steps.rb +14 -0
  27. data/lib/nanoc-oo/version.rb +3 -0
  28. data/lib/nanoc-oo.rb +25 -0
  29. data/nanoc-oo.gemspec +32 -0
  30. data/old-README.md +72 -0
  31. data/spec/add_item_spec.rb +97 -0
  32. data/spec/cli/all_spec.rb +57 -0
  33. data/spec/item_children_and_comiling_spec.rb +97 -0
  34. data/spec/items_configuration_spec.rb +239 -0
  35. data/spec/layouts_spec.rb +50 -0
  36. data/spec/rspec/compiler_spec.rb +8 -0
  37. data/spec/rspec/nanoc_spec.rb +13 -0
  38. data/spec/rspec/wrapper_spec.rb +15 -0
  39. data/spec/support/0_coverage.rb +18 -0
  40. data/spec/support/1_config.rb +27 -0
  41. data/spec/support/2_nanoc.rb +27 -0
  42. data/spec/support/3_wrapper.rb +17 -0
  43. data/spec/support/4_compiler.rb +16 -0
  44. data/spec/support/5_temp_files.rb +51 -0
  45. data/spec/support/6_temp_helpers.rb +98 -0
  46. data/spec/support/all.rb +22 -0
  47. data/spec/unit/fake_dir_spec.rb +45 -0
  48. data/spec/unit/fake_item_spec.rb +62 -0
  49. data/spec/unit/fake_items_spec.rb +38 -0
  50. data/spec/unit/filter_for_spec.rb +12 -0
  51. data/spec/unit/item_class_spec.rb +42 -0
  52. data/spec/unit/page_spec.rb +96 -0
  53. data/spec/unit/temp_files_spec.rb +107 -0
  54. metadata +278 -0
@@ -0,0 +1,239 @@
1
+ require 'support/all'
2
+ require_lib
3
+
4
+
5
+ shared_examples_for 'valid routing' do
6
+ it 'routes properly' do
7
+ compile!
8
+ File.should exist good
9
+ end
10
+ end
11
+
12
+ shared_examples_for 'produces html' do
13
+ it 'produces html file' do
14
+ compile!
15
+ output_file(name).should match compiled_html
16
+ end
17
+ end
18
+
19
+
20
+ describe '=>items configuration through classes' do
21
+
22
+ before do
23
+ TempFiles.create "#{ SITE }/lib/classes/#{ name }.rb" do
24
+ "
25
+ class TestingPage < Page
26
+ GOOD_ID = Regexp.new Regexp.escape '/#{ name }/'
27
+ #{ configuration }
28
+ end
29
+ "
30
+ end
31
+ end
32
+ let(:name){ 'teting-items-and-classes' }
33
+
34
+
35
+ describe '#route' do
36
+
37
+ context 'by default' do
38
+ let(:configuration){''}
39
+
40
+
41
+ context 'for .html files' do
42
+ before do
43
+ create_item("#{ name }.html"){ lorem }
44
+ end
45
+
46
+ let(:good){ "#{ SITE }/output/#{ name }/index.html" }
47
+
48
+ include_examples "valid routing"
49
+ end
50
+
51
+ context 'for .png files' do
52
+ before do
53
+ full_name = "#{ SITE }/content/#{ name }.png"
54
+ TempFiles.create full_name, &->{}
55
+ #save_png_image full_name
56
+ end
57
+
58
+ let(:good){ "#{ SITE }/output/#{ name }.png" }
59
+
60
+ include_examples "valid routing"
61
+ end
62
+
63
+ context 'for .css files' do
64
+ before do
65
+ full_name = "#{ SITE }/content/#{ name }.css"
66
+ TempFiles.create full_name do'
67
+ html {
68
+ color: lime;
69
+ outline: solid 10px orange;
70
+ }'
71
+ end
72
+ end
73
+
74
+ let(:good){ "#{ SITE }/output/#{ name }.css" }
75
+
76
+ include_examples "valid routing"
77
+ end
78
+ end
79
+
80
+ context 'configured through class' do
81
+ let :configuration do
82
+ "
83
+ def route
84
+ '/#{ route }/index.html'
85
+ end
86
+ "
87
+ end
88
+ let(:route){ 'test-route-changed' }
89
+
90
+ before do
91
+ create_item("#{ name }.html"){ lorem }
92
+ end
93
+
94
+ it 'routes properly' do
95
+ compile!
96
+
97
+ File.should_not exist "#{ SITE }/output/#{ name }/index.html"
98
+ File.should exist "#{ SITE }/output/#{ route }/index.html"
99
+ end
100
+ end
101
+ end
102
+
103
+ describe '#compile' do
104
+ describe 'filtering' do
105
+
106
+ let(:header){ 'Testing header!' }
107
+ let(:header_md){ "# #{ header }" }
108
+ let(:header_slim){ "h1 #{ header }" }
109
+ let(:compiled_html){ %r[<h1.*?>#{ header }</h1>] }
110
+
111
+ context 'by default' do
112
+ let(:configuration){''}
113
+
114
+ context 'should use last file extension to choose right filter' do
115
+ context 'for slim' do
116
+ before do
117
+ create_item "#{ name }.html.slim" do
118
+ header_slim
119
+ end
120
+ end
121
+
122
+ include_examples 'produces html'
123
+ end
124
+
125
+ context 'for markdown' do
126
+ before do
127
+ create_item "#{ name }.html.md" do
128
+ header_md
129
+ end
130
+ end
131
+
132
+ include_examples 'produces html'
133
+ end
134
+ end
135
+ end
136
+
137
+ context 'when configured' do
138
+ let :configuration do'
139
+ def apply_filter context
140
+ context.filter :kramdown
141
+ end'
142
+ end
143
+
144
+ before do
145
+ create_item "#{ name }.html" do
146
+ header_md
147
+ end
148
+ end
149
+
150
+ include_examples 'produces html'
151
+ end
152
+ end
153
+
154
+ context 'layout' do
155
+
156
+ before do
157
+ create_item("#{ name }.html"){ lorem }
158
+ end
159
+
160
+ context 'by default' do
161
+ let(:configuration){''}
162
+ it 'should use no layout' do
163
+ compile!
164
+ output_file(name).should_not match /doctype/i
165
+ output_file(name).should_not include '<head>'
166
+ end
167
+ end
168
+
169
+ context 'when configured' do
170
+ let :configuration do"
171
+ LAYOUT = 'default'"
172
+ end
173
+
174
+ it 'should be configurable' do
175
+ compile!
176
+ output_file(name).should match /doctype/i
177
+ output_file(name).should include '<head>'
178
+ end
179
+ end
180
+ end
181
+
182
+ context 'after compile' do
183
+
184
+ before do
185
+ create_item("#{ name }.html"){ link % absolute }
186
+ end
187
+
188
+ let(:path){ 'path.html' }
189
+ let(:relative){ "../#{path}" }
190
+ let(:absolute){ "/#{path}" }
191
+ let(:link){ "<a href='%s'>link!</a>" }
192
+
193
+ context 'by default' do
194
+ let(:configuration){''}
195
+ specify 'paths are relativised' do
196
+ compile!
197
+ output_file(name)[/href=['"](.+?)['"]/, 1].should == relative
198
+ end
199
+ end
200
+
201
+ context 'when configured' do
202
+ let :configuration do'
203
+ def after_compile *a
204
+ end'
205
+ end
206
+
207
+ it 'paths are not relativised' do
208
+ compile!
209
+ output_file(name).should include link % absolute
210
+ end
211
+ end
212
+ end
213
+ end
214
+
215
+ describe '#preprocess' do
216
+
217
+ before do
218
+ create_item("#{ name }.html"){ lorem }
219
+ end
220
+
221
+ context 'when defined' do
222
+ let :configuration do
223
+ "
224
+ def preprocess *a
225
+ item.identifier = item.identifier.chop + '#{ modified }' + '/'
226
+ end
227
+ "
228
+ end
229
+ let(:modified){ '-woohoo' }
230
+
231
+
232
+ it 'can change items identifier' do
233
+ compile!
234
+ File.should_not exist "#{ SITE }/output/#{ name }/index.html"
235
+ File.should exist "#{ SITE }/output/#{ name + modified }/index.html"
236
+ end
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,50 @@
1
+ require 'support/all'
2
+ require_lib
3
+
4
+
5
+ describe '=>layouts filter should be based on the file extension if not defined explicitly in Rules' do
6
+ let(:name){ 'testing-layout' }
7
+ prepare_new_item_and_layout!
8
+ let(:metadata){ { 'title' => "Title!" } }
9
+ let(:right_title){ "<title>#{metadata['title']}</title>" }
10
+
11
+ context 'layout.slim' do
12
+ let(:layout_ext){ '.slim' };let(:layout){ slim_layout }
13
+
14
+ it 'should be compiled preoperly' do
15
+ compile!
16
+ output_file(name).should include right_title
17
+ end
18
+ end
19
+
20
+ context 'layout.erb' do
21
+ let(:layout_ext){ '.erb' };let(:layout){ erb_layout }
22
+
23
+ it 'should be compiled preoperly' do
24
+ compile!
25
+ output_file(name).should include right_title
26
+ end
27
+ end
28
+
29
+ context 'layout.erb with slim content' do
30
+ let(:layout_ext){ '.erb' };let(:layout){ slim_layout }
31
+
32
+ it 'should not be compiled preoperly' do
33
+ compile!
34
+ output_file(name).should_not include
35
+ end
36
+
37
+ context 'defined as slim in Rules' do
38
+ before do
39
+ prepend_rules do
40
+ "layout /#{name}/, :slim"
41
+ end
42
+ end
43
+
44
+ it 'should be compiled preoperly' do
45
+ compile!
46
+ output_file(name).should include right_title
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,8 @@
1
+ require 'support/all'
2
+
3
+ describe 'compiler' do
4
+ it 'should compile without errors' do
5
+ Dir.should exist "#{SITE}/output"
6
+ File.should_not exist "#{SITE}/crash.log"
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ require 'support/all'
2
+
3
+ describe 'nanoc' do
4
+ it 'should create site' do
5
+ Dir.should exist SITE
6
+ end
7
+ it 'should delete index.html' do
8
+ File.should_not exist "#{SITE}/content/index.html"
9
+ end
10
+ it 'should delete stylesheet.css' do
11
+ File.should_not exist "#{SITE}/content/stylesheet.css"
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ require 'support/all'
2
+
3
+ describe 'wrapper' do
4
+ it 'should overwrite Rules file' do
5
+ File.read("#{SITE}/Rules").should == File.read("#{WRAP}/Rules")
6
+ end
7
+
8
+ it 'should add textual file extensions (.slim) to config.yaml' do
9
+ require 'yaml'
10
+ filters = YAML.load(File.read("#{SITE}/config.yaml"))['text_extensions']
11
+ filters.should be_a Array
12
+ filters.should include 'erb'
13
+ filters.should include 'slim'
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ if gem_available? 'simplecov'
2
+
3
+ require 'simplecov'
4
+ SimpleCov.start do
5
+ add_filter '/spec/'
6
+ end
7
+ end
8
+
9
+
10
+ BEGIN{
11
+ def gem_available?(name)
12
+ Gem::Specification.find_by_name(name)
13
+ rescue Gem::LoadError
14
+ false
15
+ rescue
16
+ Gem.available?(name)
17
+ end
18
+ }
@@ -0,0 +1,27 @@
1
+ require 'nanoc-oo'
2
+
3
+ SITE = 'tmp'
4
+ WRAP = NanocOO.wrapper
5
+
6
+ def require_here dir
7
+ Dir["#{dir}/*.rb"].each {|file| require File.expand_path file }
8
+ end
9
+
10
+ def require_lib
11
+ require_here "#{WRAP}/lib"
12
+ end
13
+
14
+ def require_classes
15
+ require_here "#{WRAP}/lib/classes"
16
+ end
17
+
18
+
19
+ RSpec.configure do |config|
20
+ config.filter_run :focus => true
21
+ config.run_all_when_everything_filtered = true
22
+ config.treat_symbols_as_metadata_keys_with_true_values = true
23
+ end
24
+
25
+ def f
26
+ :focus
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'fileutils'
2
+
3
+ def clean
4
+ rm_rf SITE
5
+ end
6
+
7
+ def rm_rf dir
8
+ FileUtils.rm_rf dir if Dir.exist? dir
9
+ end
10
+
11
+
12
+ def start
13
+ clean
14
+ `nanoc create-site #{SITE}`
15
+ File.delete "#{SITE}/content/index.html"
16
+ File.delete "#{SITE}/content/stylesheet.css"
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ config.before(:all) do
21
+ start
22
+ end
23
+
24
+ config.after(:all) do
25
+ clean
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ def wrap
2
+ require 'fileutils'
3
+ FileUtils.cp_r "#{WRAP}/.", SITE
4
+ end
5
+
6
+ def add_filters filters, config = "#{SITE}/config.yaml"
7
+ text = File.read(config)
8
+ text[/text_extensions: ?\[()/, 1] = filters.map{|x| " '#{x}'," }.join
9
+ File.write config, text
10
+ end
11
+
12
+ RSpec.configure do |config|
13
+ config.before(:all) do
14
+ wrap
15
+ add_filters ['slim']
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ def compile
2
+ Dir.chdir SITE do
3
+ rm_rf 'output'
4
+ `nanoc compile`
5
+ end
6
+ crash = File.exist? "#{SITE}/crash.log"
7
+ FileUtils.cp "#{SITE}/crash.log", 'crash.log' if crash
8
+ not crash
9
+ end
10
+
11
+ RSpec.configure do |config|
12
+ config.before(:all) do
13
+ File.delete 'crash.log' if File.exist? 'crash.log'
14
+ compile
15
+ end
16
+ end
@@ -0,0 +1,51 @@
1
+ RSpec.configure do |config|
2
+ config.after(:each) do
3
+ TempFiles.revert
4
+ TempFiles.purge
5
+ end
6
+ end
7
+
8
+ def prepare_directory_for file
9
+ require 'fileutils'
10
+ FileUtils.mkpath File.split(file)[0]
11
+ end
12
+
13
+ class TempFiles
14
+ @files = []
15
+ @prepends = []
16
+
17
+
18
+ class << self
19
+ def create file
20
+ @files << file
21
+ prepare_directory_for file
22
+ File.write(file, yield)
23
+ end
24
+
25
+ def purge
26
+ @files.each do |file|
27
+ File.delete file if File.exist? file
28
+ end
29
+ @files = []
30
+ end
31
+
32
+ def prepend file
33
+ fragment = yield
34
+ text = File.read(file)
35
+ File.write(file, "#{fragment}#{text}")
36
+ @prepends << [file, fragment]
37
+ end
38
+
39
+ def prepend_lines file
40
+ prepend(file){ yield.chomp + "\n" }
41
+ end
42
+
43
+ def revert
44
+ @prepends.each do |file, fragment|
45
+ text = File.read(file)
46
+ File.write file, text.sub(fragment, '')
47
+ end
48
+ @prepends = []
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,98 @@
1
+ def create_layout name, ext
2
+ TempFiles.create "#{SITE}/layouts/#{name}#{ext}" do
3
+ yield
4
+ end
5
+ end
6
+
7
+ def create_item name, ext=nil
8
+ full_name = ext==nil ? name : "#{name}#{ext}"
9
+ TempFiles.create "#{SITE}/content/#{full_name}" do
10
+ yield
11
+ end
12
+ end
13
+
14
+ def create_class
15
+ text = yield
16
+ name = text[/class(.+?)</, 1].strip.downcase
17
+ TempFiles.create "#{SITE}/lib/classes/#{name}.rb" do
18
+ text
19
+ end
20
+ end
21
+
22
+ def slim_layout
23
+ "doctype 5
24
+ html lang=@item[:lang]
25
+ head
26
+ title = @item[:title]
27
+ body == yield"
28
+ end
29
+
30
+ def erb_layout
31
+ "<!doctype html>
32
+ <html lang=en>
33
+ <head>
34
+ <title><%= @item[:title] %></title>
35
+ </head>
36
+ <body>
37
+ <%= yield %>
38
+ </body>
39
+ </html>"
40
+ end
41
+
42
+ def lorem meta={}
43
+ require 'yaml'
44
+ lo = YAML.dump meta
45
+ rem = '<h1>Content!</h1>'
46
+ "#{lo}---\n#{rem}"
47
+ end
48
+
49
+ def compile_item item, lay=nil
50
+ lay ||= item
51
+ "compile('/#{item}/'){ layout '#{lay}' }
52
+ route('/#{item}/'){'/#{item}/index.html'}"
53
+ end
54
+
55
+ def prepend_rules
56
+ TempFiles.prepend_lines "#{SITE}/Rules" do
57
+ yield
58
+ end
59
+ end
60
+
61
+ def output name
62
+ "#{SITE}/output/#{name}/index.html"
63
+ end
64
+
65
+ def output_file name
66
+ File.read output name
67
+ end
68
+
69
+ def compile!
70
+ compile.should == true
71
+ end
72
+
73
+ def not_compiling!
74
+ compile.should == false
75
+ end
76
+
77
+ def prepare_new_item_and_layout!
78
+ before :each do
79
+ create_layout(name, layout_ext){ layout }
80
+ create_item(name, item_ext){ item }
81
+ prepend_rules{ rule }
82
+ end
83
+
84
+ let(:item_ext){ '.html' };let(:item){ lorem metadata }
85
+ let(:rule){ compile_item name }
86
+ end
87
+
88
+ def stop!
89
+ require 'pry'
90
+ binding.pry
91
+ end
92
+
93
+ # def save_png_image file
94
+ # require 'chunky_png'
95
+ # png = ChunkyPNG::Image.new(16, 16, ChunkyPNG::Color::TRANSPARENT)
96
+ # png[1,1] = ChunkyPNG::Color.rgba(10, 20, 30, 128)
97
+ # png.save(file, :interlace => true)
98
+ # end
@@ -0,0 +1,22 @@
1
+ module This
2
+ extend self
3
+
4
+ def file
5
+ File.expand_path __FILE__
6
+ end
7
+
8
+ def dir
9
+ File.split(file)[0]
10
+ end
11
+ end
12
+
13
+ def ruby_files_at dir
14
+ Dir["#{dir}/*.rb"].to_a
15
+ end
16
+
17
+ def require_here
18
+ ruby_files_at(This.dir).each { |file| require_relative file }
19
+ end
20
+
21
+
22
+ require_here
@@ -0,0 +1,45 @@
1
+ require 'support/all'
2
+ require_lib
3
+
4
+ describe FakeDir do
5
+
6
+ describe '#file' do
7
+ let(:name){ 'some.dir' }
8
+
9
+ it 'is accessible' do
10
+ FakeDir.new(name).file.should == name
11
+ end
12
+ end
13
+
14
+ describe '(+self)' do
15
+ let(:item){ FakeDir.new('foo') }
16
+ let(:value){ 123 }
17
+
18
+ it 'should return self[:object]' do
19
+ item[:object] = value
20
+ (+item).should == value
21
+ end
22
+ end
23
+
24
+ describe '#identifier' do
25
+
26
+ variants = %w[
27
+
28
+ given_direcory_name: identifier:
29
+
30
+ content/canon/some.dir /canon/some.dir/
31
+ layouts/default_dir /default_dir/
32
+ content/index.dir.123 /index.dir.123/
33
+ content/index /index/
34
+ content/index.dir /index.dir/
35
+ content/index.dir/ /index.dir/
36
+
37
+ ].each_slice(2).drop(1)
38
+
39
+ variants.each do |name, identifier|
40
+ it "should be (#{identifier}) when directory name is (#{name})" do
41
+ FakeDir.new(name).identifier.should == identifier
42
+ end
43
+ end
44
+ end
45
+ end