nanoc 3.2.4 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. data/.gemtest +0 -0
  2. data/ChangeLog +3 -0
  3. data/Gemfile +32 -0
  4. data/LICENSE +19 -0
  5. data/NEWS.md +470 -0
  6. data/README.md +114 -0
  7. data/Rakefile +14 -0
  8. data/bin/nanoc +7 -27
  9. data/bin/nanoc3 +3 -0
  10. data/doc/yardoc_templates/default/layout/html/footer.erb +10 -0
  11. data/lib/nanoc.rb +41 -0
  12. data/lib/nanoc/base.rb +49 -0
  13. data/lib/nanoc/base/compilation/checksum_store.rb +57 -0
  14. data/lib/nanoc/base/compilation/compiled_content_cache.rb +62 -0
  15. data/lib/nanoc/base/compilation/compiler.rb +458 -0
  16. data/lib/nanoc/base/compilation/compiler_dsl.rb +214 -0
  17. data/lib/nanoc/base/compilation/dependency_tracker.rb +200 -0
  18. data/lib/nanoc/base/compilation/filter.rb +165 -0
  19. data/lib/nanoc/base/compilation/item_rep_proxy.rb +103 -0
  20. data/lib/nanoc/base/compilation/item_rep_recorder_proxy.rb +102 -0
  21. data/lib/nanoc/base/compilation/outdatedness_checker.rb +223 -0
  22. data/lib/nanoc/base/compilation/outdatedness_reasons.rb +46 -0
  23. data/lib/nanoc/base/compilation/rule.rb +73 -0
  24. data/lib/nanoc/base/compilation/rule_context.rb +84 -0
  25. data/lib/nanoc/base/compilation/rule_memory_calculator.rb +40 -0
  26. data/lib/nanoc/base/compilation/rule_memory_store.rb +53 -0
  27. data/lib/nanoc/base/compilation/rules_collection.rb +243 -0
  28. data/lib/nanoc/base/context.rb +47 -0
  29. data/lib/nanoc/base/core_ext.rb +6 -0
  30. data/lib/nanoc/base/core_ext/array.rb +62 -0
  31. data/lib/nanoc/base/core_ext/hash.rb +63 -0
  32. data/lib/nanoc/base/core_ext/pathname.rb +26 -0
  33. data/lib/nanoc/base/core_ext/string.rb +46 -0
  34. data/lib/nanoc/base/directed_graph.rb +275 -0
  35. data/lib/nanoc/base/errors.rb +211 -0
  36. data/lib/nanoc/base/memoization.rb +67 -0
  37. data/lib/nanoc/base/notification_center.rb +84 -0
  38. data/lib/nanoc/base/ordered_hash.rb +200 -0
  39. data/lib/nanoc/base/plugin_registry.rb +181 -0
  40. data/lib/nanoc/base/result_data/item_rep.rb +492 -0
  41. data/lib/nanoc/base/source_data/code_snippet.rb +58 -0
  42. data/lib/nanoc/base/source_data/configuration.rb +24 -0
  43. data/lib/nanoc/base/source_data/data_source.rb +234 -0
  44. data/lib/nanoc/base/source_data/item.rb +301 -0
  45. data/lib/nanoc/base/source_data/layout.rb +130 -0
  46. data/lib/nanoc/base/source_data/site.rb +361 -0
  47. data/lib/nanoc/base/store.rb +135 -0
  48. data/lib/nanoc/cli.rb +137 -0
  49. data/lib/nanoc/cli/command_runner.rb +104 -0
  50. data/lib/nanoc/cli/commands/autocompile.rb +58 -0
  51. data/lib/nanoc/cli/commands/compile.rb +297 -0
  52. data/lib/nanoc/cli/commands/create_item.rb +60 -0
  53. data/lib/nanoc/cli/commands/create_layout.rb +73 -0
  54. data/lib/nanoc/cli/commands/create_site.rb +411 -0
  55. data/lib/nanoc/cli/commands/debug.rb +117 -0
  56. data/lib/nanoc/cli/commands/deploy.rb +79 -0
  57. data/lib/nanoc/cli/commands/info.rb +98 -0
  58. data/lib/nanoc/cli/commands/nanoc.rb +38 -0
  59. data/lib/nanoc/cli/commands/prune.rb +50 -0
  60. data/lib/nanoc/cli/commands/update.rb +70 -0
  61. data/lib/nanoc/cli/commands/view.rb +82 -0
  62. data/lib/nanoc/cli/commands/watch.rb +124 -0
  63. data/lib/nanoc/cli/error_handler.rb +199 -0
  64. data/lib/nanoc/cli/logger.rb +92 -0
  65. data/lib/nanoc/data_sources.rb +29 -0
  66. data/lib/nanoc/data_sources/deprecated/delicious.rb +42 -0
  67. data/lib/nanoc/data_sources/deprecated/last_fm.rb +87 -0
  68. data/lib/nanoc/data_sources/deprecated/twitter.rb +38 -0
  69. data/lib/nanoc/data_sources/filesystem.rb +299 -0
  70. data/lib/nanoc/data_sources/filesystem_unified.rb +121 -0
  71. data/lib/nanoc/data_sources/filesystem_verbose.rb +91 -0
  72. data/lib/nanoc/extra.rb +24 -0
  73. data/lib/nanoc/extra/auto_compiler.rb +103 -0
  74. data/lib/nanoc/extra/chick.rb +125 -0
  75. data/lib/nanoc/extra/core_ext.rb +6 -0
  76. data/lib/nanoc/extra/core_ext/enumerable.rb +33 -0
  77. data/lib/nanoc/extra/core_ext/pathname.rb +30 -0
  78. data/lib/nanoc/extra/core_ext/time.rb +19 -0
  79. data/lib/nanoc/extra/deployer.rb +47 -0
  80. data/lib/nanoc/extra/deployers.rb +15 -0
  81. data/lib/nanoc/extra/deployers/fog.rb +98 -0
  82. data/lib/nanoc/extra/deployers/rsync.rb +70 -0
  83. data/lib/nanoc/extra/file_proxy.rb +40 -0
  84. data/lib/nanoc/extra/pruner.rb +86 -0
  85. data/lib/nanoc/extra/validators.rb +12 -0
  86. data/lib/nanoc/extra/validators/links.rb +268 -0
  87. data/lib/nanoc/extra/validators/w3c.rb +95 -0
  88. data/lib/nanoc/extra/vcs.rb +66 -0
  89. data/lib/nanoc/extra/vcses.rb +17 -0
  90. data/lib/nanoc/extra/vcses/bazaar.rb +25 -0
  91. data/lib/nanoc/extra/vcses/dummy.rb +24 -0
  92. data/lib/nanoc/extra/vcses/git.rb +25 -0
  93. data/lib/nanoc/extra/vcses/mercurial.rb +25 -0
  94. data/lib/nanoc/extra/vcses/subversion.rb +25 -0
  95. data/lib/nanoc/filters.rb +59 -0
  96. data/lib/nanoc/filters/asciidoc.rb +38 -0
  97. data/lib/nanoc/filters/bluecloth.rb +19 -0
  98. data/lib/nanoc/filters/coderay.rb +21 -0
  99. data/lib/nanoc/filters/coffeescript.rb +20 -0
  100. data/lib/nanoc/filters/colorize_syntax.rb +298 -0
  101. data/lib/nanoc/filters/erb.rb +38 -0
  102. data/lib/nanoc/filters/erubis.rb +34 -0
  103. data/lib/nanoc/filters/haml.rb +27 -0
  104. data/lib/nanoc/filters/kramdown.rb +20 -0
  105. data/lib/nanoc/filters/less.rb +53 -0
  106. data/lib/nanoc/filters/markaby.rb +20 -0
  107. data/lib/nanoc/filters/maruku.rb +20 -0
  108. data/lib/nanoc/filters/mustache.rb +24 -0
  109. data/lib/nanoc/filters/rainpress.rb +19 -0
  110. data/lib/nanoc/filters/rdiscount.rb +22 -0
  111. data/lib/nanoc/filters/rdoc.rb +33 -0
  112. data/lib/nanoc/filters/redcarpet.rb +62 -0
  113. data/lib/nanoc/filters/redcloth.rb +47 -0
  114. data/lib/nanoc/filters/relativize_paths.rb +94 -0
  115. data/lib/nanoc/filters/rubypants.rb +20 -0
  116. data/lib/nanoc/filters/sass.rb +74 -0
  117. data/lib/nanoc/filters/slim.rb +25 -0
  118. data/lib/nanoc/filters/typogruby.rb +23 -0
  119. data/lib/nanoc/filters/uglify_js.rb +42 -0
  120. data/lib/nanoc/filters/xsl.rb +46 -0
  121. data/lib/nanoc/filters/yui_compressor.rb +23 -0
  122. data/lib/nanoc/helpers.rb +16 -0
  123. data/lib/nanoc/helpers/blogging.rb +319 -0
  124. data/lib/nanoc/helpers/breadcrumbs.rb +40 -0
  125. data/lib/nanoc/helpers/capturing.rb +138 -0
  126. data/lib/nanoc/helpers/filtering.rb +50 -0
  127. data/lib/nanoc/helpers/html_escape.rb +55 -0
  128. data/lib/nanoc/helpers/link_to.rb +151 -0
  129. data/lib/nanoc/helpers/rendering.rb +140 -0
  130. data/lib/nanoc/helpers/tagging.rb +71 -0
  131. data/lib/nanoc/helpers/text.rb +44 -0
  132. data/lib/nanoc/helpers/xml_sitemap.rb +76 -0
  133. data/lib/nanoc/tasks.rb +10 -0
  134. data/lib/nanoc/tasks/clean.rake +16 -0
  135. data/lib/nanoc/tasks/clean.rb +29 -0
  136. data/lib/nanoc/tasks/deploy/rsync.rake +16 -0
  137. data/lib/nanoc/tasks/validate.rake +92 -0
  138. data/nanoc.gemspec +49 -0
  139. data/tasks/doc.rake +16 -0
  140. data/tasks/test.rake +46 -0
  141. data/test/base/core_ext/array_spec.rb +73 -0
  142. data/test/base/core_ext/hash_spec.rb +98 -0
  143. data/test/base/core_ext/pathname_spec.rb +27 -0
  144. data/test/base/core_ext/string_spec.rb +37 -0
  145. data/test/base/test_checksum_store.rb +35 -0
  146. data/test/base/test_code_snippet.rb +31 -0
  147. data/test/base/test_compiler.rb +403 -0
  148. data/test/base/test_compiler_dsl.rb +161 -0
  149. data/test/base/test_context.rb +31 -0
  150. data/test/base/test_data_source.rb +46 -0
  151. data/test/base/test_dependency_tracker.rb +262 -0
  152. data/test/base/test_directed_graph.rb +288 -0
  153. data/test/base/test_filter.rb +83 -0
  154. data/test/base/test_item.rb +179 -0
  155. data/test/base/test_item_rep.rb +579 -0
  156. data/test/base/test_layout.rb +59 -0
  157. data/test/base/test_memoization.rb +90 -0
  158. data/test/base/test_notification_center.rb +34 -0
  159. data/test/base/test_outdatedness_checker.rb +394 -0
  160. data/test/base/test_plugin.rb +30 -0
  161. data/test/base/test_rule.rb +19 -0
  162. data/test/base/test_rule_context.rb +65 -0
  163. data/test/base/test_site.rb +190 -0
  164. data/test/cli/commands/test_compile.rb +33 -0
  165. data/test/cli/commands/test_create_item.rb +14 -0
  166. data/test/cli/commands/test_create_layout.rb +28 -0
  167. data/test/cli/commands/test_create_site.rb +24 -0
  168. data/test/cli/commands/test_deploy.rb +74 -0
  169. data/test/cli/commands/test_help.rb +12 -0
  170. data/test/cli/commands/test_info.rb +11 -0
  171. data/test/cli/commands/test_prune.rb +98 -0
  172. data/test/cli/commands/test_update.rb +10 -0
  173. data/test/cli/test_cli.rb +102 -0
  174. data/test/cli/test_error_handler.rb +29 -0
  175. data/test/cli/test_logger.rb +10 -0
  176. data/test/data_sources/test_filesystem.rb +433 -0
  177. data/test/data_sources/test_filesystem_unified.rb +536 -0
  178. data/test/data_sources/test_filesystem_verbose.rb +357 -0
  179. data/test/extra/core_ext/test_enumerable.rb +30 -0
  180. data/test/extra/core_ext/test_pathname.rb +17 -0
  181. data/test/extra/core_ext/test_time.rb +15 -0
  182. data/test/extra/deployers/test_fog.rb +67 -0
  183. data/test/extra/deployers/test_rsync.rb +100 -0
  184. data/test/extra/test_auto_compiler.rb +417 -0
  185. data/test/extra/test_file_proxy.rb +19 -0
  186. data/test/extra/test_vcs.rb +22 -0
  187. data/test/extra/validators/test_links.rb +62 -0
  188. data/test/extra/validators/test_w3c.rb +47 -0
  189. data/test/filters/test_asciidoc.rb +22 -0
  190. data/test/filters/test_bluecloth.rb +18 -0
  191. data/test/filters/test_coderay.rb +44 -0
  192. data/test/filters/test_coffeescript.rb +18 -0
  193. data/test/filters/test_colorize_syntax.rb +379 -0
  194. data/test/filters/test_erb.rb +105 -0
  195. data/test/filters/test_erubis.rb +78 -0
  196. data/test/filters/test_haml.rb +96 -0
  197. data/test/filters/test_kramdown.rb +18 -0
  198. data/test/filters/test_less.rb +113 -0
  199. data/test/filters/test_markaby.rb +24 -0
  200. data/test/filters/test_maruku.rb +18 -0
  201. data/test/filters/test_mustache.rb +25 -0
  202. data/test/filters/test_rainpress.rb +29 -0
  203. data/test/filters/test_rdiscount.rb +31 -0
  204. data/test/filters/test_rdoc.rb +18 -0
  205. data/test/filters/test_redcarpet.rb +73 -0
  206. data/test/filters/test_redcloth.rb +33 -0
  207. data/test/filters/test_relativize_paths.rb +533 -0
  208. data/test/filters/test_rubypants.rb +18 -0
  209. data/test/filters/test_sass.rb +229 -0
  210. data/test/filters/test_slim.rb +35 -0
  211. data/test/filters/test_typogruby.rb +21 -0
  212. data/test/filters/test_uglify_js.rb +30 -0
  213. data/test/filters/test_xsl.rb +105 -0
  214. data/test/filters/test_yui_compressor.rb +44 -0
  215. data/test/gem_loader.rb +11 -0
  216. data/test/helper.rb +207 -0
  217. data/test/helpers/test_blogging.rb +754 -0
  218. data/test/helpers/test_breadcrumbs.rb +81 -0
  219. data/test/helpers/test_capturing.rb +41 -0
  220. data/test/helpers/test_filtering.rb +106 -0
  221. data/test/helpers/test_html_escape.rb +32 -0
  222. data/test/helpers/test_link_to.rb +249 -0
  223. data/test/helpers/test_rendering.rb +89 -0
  224. data/test/helpers/test_tagging.rb +87 -0
  225. data/test/helpers/test_text.rb +24 -0
  226. data/test/helpers/test_xml_sitemap.rb +103 -0
  227. data/test/tasks/test_clean.rb +67 -0
  228. metadata +327 -15
  229. data/bin/nanoc-select +0 -86
  230. data/lib/nanoc-select.rb +0 -11
@@ -0,0 +1,100 @@
1
+ # encoding: utf-8
2
+
3
+ class Nanoc::Extra::Deployers::RsyncTest < MiniTest::Unit::TestCase
4
+
5
+ include Nanoc::TestHelpers
6
+
7
+ def test_run_without_dst
8
+ if_have 'systemu' do
9
+ # Create deployer
10
+ rsync = Nanoc::Extra::Deployers::Rsync.new(
11
+ 'output/',
12
+ {})
13
+
14
+ # Mock run_shell_cmd
15
+ def rsync.run_shell_cmd(args)
16
+ @shell_cms_args = args
17
+ end
18
+
19
+ # Try running
20
+ error = assert_raises(RuntimeError) do
21
+ rsync.run
22
+ end
23
+
24
+ # Check error message
25
+ assert_equal 'No dst found in deployment configuration', error.message
26
+ end
27
+ end
28
+
29
+ def test_run_with_erroneous_dst
30
+ if_have 'systemu' do
31
+ # Create deployer
32
+ rsync = Nanoc::Extra::Deployers::Rsync.new(
33
+ 'output/',
34
+ { :dst => 'asdf/' })
35
+
36
+ # Mock run_shell_cmd
37
+ def rsync.run_shell_cmd(args)
38
+ @shell_cms_args = args
39
+ end
40
+
41
+ # Try running
42
+ error = assert_raises(RuntimeError) do
43
+ rsync.run
44
+ end
45
+
46
+ # Check error message
47
+ assert_equal 'dst requires no trailing slash', error.message
48
+ end
49
+ end
50
+
51
+ def test_run_everything_okay
52
+ if_have 'systemu' do
53
+ # Create deployer
54
+ rsync = Nanoc::Extra::Deployers::Rsync.new(
55
+ 'output/',
56
+ { :dst => 'asdf' })
57
+
58
+ # Mock run_shell_cmd
59
+ def rsync.run_shell_cmd(args)
60
+ @shell_cms_args = args
61
+ end
62
+
63
+ # Run
64
+ rsync.run
65
+
66
+ # Check args
67
+ opts = Nanoc::Extra::Deployers::Rsync::DEFAULT_OPTIONS
68
+ assert_equal(
69
+ [ 'rsync', opts, File.expand_path('output') + '/', 'asdf' ].flatten,
70
+ rsync.instance_eval { @shell_cms_args }
71
+ )
72
+ end
73
+ end
74
+
75
+ def test_run_everything_okay_dry
76
+ if_have 'systemu' do
77
+ # Create deployer
78
+ rsync = Nanoc::Extra::Deployers::Rsync.new(
79
+ 'output/',
80
+ { :dst => 'asdf' },
81
+ :dry_run => true)
82
+
83
+ # Mock run_shell_cmd
84
+ def rsync.run_shell_cmd(args)
85
+ @shell_cms_args = args
86
+ end
87
+
88
+ # Run
89
+ rsync.run
90
+
91
+ # Check args
92
+ opts = Nanoc::Extra::Deployers::Rsync::DEFAULT_OPTIONS
93
+ assert_equal(
94
+ [ 'echo', 'rsync', opts, File.expand_path('output') + '/', 'asdf' ].flatten,
95
+ rsync.instance_eval { @shell_cms_args }
96
+ )
97
+ end
98
+ end
99
+
100
+ end
@@ -0,0 +1,417 @@
1
+ # encoding: utf-8
2
+
3
+ class Nanoc::Extra::AutoCompilerTest < MiniTest::Unit::TestCase
4
+
5
+ include Nanoc::TestHelpers
6
+
7
+ def test_handle_request_with_item_rep_with_index_filename
8
+ if_have 'mime/types', 'rack' do
9
+ # Create site
10
+ Nanoc::CLI.run %w( create_site bar)
11
+
12
+ FileUtils.cd('bar') do
13
+ # Create item
14
+ FileUtils.mkdir_p('content/foo')
15
+ File.open('content/foo/index.html', 'w') do |io|
16
+ io.write "Moo!"
17
+ end
18
+
19
+ # Create output file
20
+ FileUtils.mkdir_p('output/foo')
21
+ File.open('output/foo/index.html', 'w') do |io|
22
+ io.write "Compiled moo!"
23
+ end
24
+
25
+ # Create site
26
+ site = Nanoc::Site.new('.')
27
+ site.expects(:compile)
28
+
29
+ # Create autocompiler
30
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
31
+ autocompiler.stubs(:build_site)
32
+ autocompiler.stubs(:site).returns(site)
33
+
34
+ # Serve
35
+ status, headers, body = autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/foo/index.html') }
36
+
37
+ # Check response
38
+ assert_equal(200, status)
39
+ assert_equal('text/html', headers['Content-Type'])
40
+ body.each do |b|
41
+ assert_equal "Compiled moo!", b
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def test_handle_request_with_broken_url
48
+ if_have 'mime/types', 'rack' do
49
+ # Create site
50
+ Nanoc::CLI.run %w( create_site bar)
51
+
52
+ FileUtils.cd('bar') do
53
+ # Create site
54
+ site = Nanoc::Site.new('.')
55
+
56
+ # Create autocompiler
57
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
58
+ autocompiler.stubs(:build_site)
59
+ autocompiler.stubs(:site).returns(site)
60
+
61
+ # Serve
62
+ status, headers, body = autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/afjwiagoawf.html') }
63
+
64
+ # Check response
65
+ assert_equal(404, status)
66
+ end
67
+ end
68
+ end
69
+
70
+ def test_handle_request_with_file
71
+ if_have 'mime/types', 'rack' do
72
+ # Create file
73
+ FileUtils.mkdir_p('out')
74
+ File.open('out/somefile.txt', 'w') { |io| io.write('hello') }
75
+
76
+ # Create file server
77
+ file_server = mock
78
+ def file_server.call(env)
79
+ @expected_path_info = 'somefile.txt'
80
+ @actual_path_info = env['PATH_INFO']
81
+ end
82
+ def file_server.expected_path_info ; @expected_path_info ; end
83
+ def file_server.actual_path_info ; @actual_path_info ; end
84
+
85
+ # Create site
86
+ site = mock
87
+ site.expects(:items).returns([])
88
+ site.expects(:config).returns({ :output_dir => 'out', :index_filenames => [ 'index.html' ] })
89
+
90
+ # Create autocompiler
91
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
92
+ autocompiler.stubs(:build_site)
93
+ autocompiler.stubs(:site).returns(site)
94
+ autocompiler.expects(:file_server).returns(file_server)
95
+
96
+ # Run
97
+ autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => 'somefile.txt') }
98
+
99
+ # Check
100
+ assert_equal(file_server.expected_path_info, file_server.actual_path_info)
101
+ end
102
+ end
103
+
104
+ def test_handle_request_with_dir_with_slash_with_index_file
105
+ if_have 'mime/types', 'rack' do
106
+ # Create file
107
+ FileUtils.mkdir_p('out/foo/bar')
108
+ File.open('out/foo/bar/index.html', 'w') { |io| io.write('hello') }
109
+
110
+ # Create file server
111
+ file_server = mock
112
+ def file_server.call(env)
113
+ @expected_path_info = '/foo/bar/index.html'
114
+ @actual_path_info = env['PATH_INFO']
115
+ end
116
+ def file_server.expected_path_info ; @expected_path_info ; end
117
+ def file_server.actual_path_info ; @actual_path_info ; end
118
+
119
+ # Create site
120
+ site = mock
121
+ site.expects(:items).returns([])
122
+ site.expects(:config).at_least_once.returns({ :output_dir => 'out', :index_filenames => [ 'index.html' ] })
123
+
124
+ # Create autocompiler
125
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
126
+ autocompiler.stubs(:build_site)
127
+ autocompiler.stubs(:site).returns(site)
128
+ autocompiler.expects(:file_server).returns(file_server)
129
+
130
+ # Run
131
+ autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/foo/bar/') }
132
+
133
+ # Check
134
+ assert_equal(file_server.expected_path_info, file_server.actual_path_info)
135
+ end
136
+ end
137
+
138
+ def test_handle_request_with_dir_with_slash_without_index_file
139
+ if_have 'mime/types', 'rack' do
140
+ # Create file
141
+ FileUtils.mkdir_p('out/foo/bar')
142
+ File.open('out/foo/bar/someotherfile.txt', 'w') { |io| io.write('hello') }
143
+
144
+ # Create file server
145
+ file_server = mock
146
+ def file_server.call(env)
147
+ @expected_path_info = 'foo/bar/'
148
+ @actual_path_info = env['PATH_INFO']
149
+ end
150
+ def file_server.expected_path_info ; @expected_path_info ; end
151
+ def file_server.actual_path_info ; @actual_path_info ; end
152
+
153
+ # Create site
154
+ site = mock
155
+ site.expects(:items).returns([])
156
+ site.expects(:config).at_least_once.returns({ :output_dir => 'out', :index_filenames => [ 'index.html' ] })
157
+
158
+ # Create autocompiler
159
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
160
+ autocompiler.stubs(:build_site)
161
+ autocompiler.stubs(:site).returns(site)
162
+ autocompiler.expects(:file_server).returns(file_server)
163
+
164
+ # Run
165
+ autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => 'foo/bar/') }
166
+
167
+ # Check
168
+ assert_equal(file_server.expected_path_info, file_server.actual_path_info)
169
+ end
170
+ end
171
+
172
+ def test_handle_request_with_dir_without_slash_with_index_file
173
+ if_have 'mime/types', 'rack' do
174
+ # Create file
175
+ FileUtils.mkdir_p('out/foo/bar')
176
+ File.open('out/foo/bar/index.html', 'w') { |io| io.write('hello') }
177
+
178
+ # Create file server
179
+ file_server = mock
180
+ def file_server.call(env)
181
+ @expected_path_info = 'foo/bar'
182
+ @actual_path_info = env['PATH_INFO']
183
+ end
184
+ def file_server.expected_path_info ; @expected_path_info ; end
185
+ def file_server.actual_path_info ; @actual_path_info ; end
186
+
187
+ # Create site
188
+ site = mock
189
+ site.expects(:items).returns([])
190
+ site.expects(:config).at_least_once.returns({ :output_dir => 'out', :index_filenames => [ 'index.html' ] })
191
+
192
+ # Create autocompiler
193
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
194
+ autocompiler.stubs(:build_site)
195
+ autocompiler.stubs(:site).returns(site)
196
+ autocompiler.expects(:file_server).returns(file_server)
197
+
198
+ # Run
199
+ autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => 'foo/bar') }
200
+
201
+ # Check
202
+ assert_equal(file_server.expected_path_info, file_server.actual_path_info)
203
+ end
204
+ end
205
+
206
+ def test_handle_request_with_dir_without_slash_without_index_file
207
+ if_have 'mime/types', 'rack' do
208
+ # Create file
209
+ FileUtils.mkdir_p('out/foo/bar')
210
+ File.open('out/foo/bar/someotherfile.txt', 'w') { |io| io.write('hello') }
211
+
212
+ # Create file server
213
+ file_server = mock
214
+ def file_server.call(env)
215
+ @expected_path_info = 'foo/bar'
216
+ @actual_path_info = env['PATH_INFO']
217
+ end
218
+ def file_server.expected_path_info ; @expected_path_info ; end
219
+ def file_server.actual_path_info ; @actual_path_info ; end
220
+
221
+ # Create site
222
+ site = mock
223
+ site.expects(:items).returns([])
224
+ site.expects(:config).at_least_once.returns({ :output_dir => 'out', :index_filenames => [ 'index.html' ] })
225
+
226
+ # Create autocompiler
227
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
228
+ autocompiler.stubs(:build_site)
229
+ autocompiler.stubs(:site).returns(site)
230
+ autocompiler.expects(:file_server).returns(file_server)
231
+
232
+ # Run
233
+ autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => 'foo/bar') }
234
+
235
+ # Check
236
+ assert_equal(file_server.expected_path_info, file_server.actual_path_info)
237
+ end
238
+ end
239
+
240
+ def test_handle_request_with_404
241
+ if_have 'mime/types', 'rack' do
242
+ # Create file server
243
+ file_server = mock
244
+ def file_server.call(env)
245
+ @expected_path_info = 'four-oh-four.txt'
246
+ @actual_path_info = env['PATH_INFO']
247
+ end
248
+ def file_server.expected_path_info ; @expected_path_info ; end
249
+ def file_server.actual_path_info ; @actual_path_info ; end
250
+
251
+ # Create site
252
+ site = mock
253
+ site.expects(:items).returns([])
254
+ site.expects(:config).at_least_once.returns({ :output_dir => 'out', :index_filenames => [ 'index.html' ] })
255
+
256
+ # Create autocompiler
257
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
258
+ autocompiler.stubs(:build_site)
259
+ autocompiler.stubs(:site).returns(site)
260
+ autocompiler.expects(:file_server).returns(file_server)
261
+
262
+ # Run
263
+ autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => 'four-oh-four.txt') }
264
+
265
+ # Check
266
+ assert_equal(file_server.expected_path_info, file_server.actual_path_info)
267
+ end
268
+ end
269
+
270
+ def test_mime_type_of
271
+ if_have 'mime/types', 'rack' do
272
+ # Create autocompiler
273
+ autocompiler = Nanoc::Extra::AutoCompiler.new(nil)
274
+
275
+ # Create known test file
276
+ File.open('foo.html', 'w') { |io| io.write('hello') }
277
+ assert_equal(
278
+ 'text/html',
279
+ autocompiler.instance_eval { mime_type_of('foo.html', 'huh') }
280
+ )
281
+
282
+ # Create unknown test file
283
+ File.open('foo', 'w') { |io| io.write('hello') }
284
+ assert_equal(
285
+ 'huh',
286
+ autocompiler.instance_eval { mime_type_of('foo', 'huh') }
287
+ )
288
+ end
289
+ end
290
+
291
+ def test_serve_with_working_item
292
+ if_have 'mime/types', 'rack' do
293
+ # Create site
294
+ Nanoc::CLI.run %w( create_site bar)
295
+
296
+ FileUtils.cd('bar') do
297
+ # Create item
298
+ File.open('content/index.html', 'w') do |io|
299
+ io.write "Moo!"
300
+ end
301
+
302
+ # Create output file
303
+ File.open('output/index.html', 'w') do |io|
304
+ io.write "Compiled moo!"
305
+ end
306
+
307
+ # Create site
308
+ site = Nanoc::Site.new('.')
309
+ site.expects(:compile)
310
+
311
+ # Create autocompiler
312
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
313
+ autocompiler.stubs(:build_site)
314
+ autocompiler.stubs(:site).returns(site)
315
+
316
+ # Serve
317
+ status, headers, body = autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/') }
318
+
319
+ # Check response
320
+ assert_equal(200, status)
321
+ assert_equal('text/html', headers['Content-Type'])
322
+ body.each do |b|
323
+ assert_equal "Compiled moo!", b
324
+ end
325
+ end
326
+ end
327
+ end
328
+
329
+ def test_serve_with_broken_item
330
+ if_have 'mime/types', 'rack' do
331
+ # Create site
332
+ Nanoc::CLI.run %w( create_site bar)
333
+
334
+ FileUtils.cd('bar') do
335
+ # Create item
336
+ File.open('content/whatever.html', 'w') do |io|
337
+ io.write "Whatever!"
338
+ end
339
+
340
+ # Create site
341
+ site = Nanoc::Site.new('.')
342
+ site.expects(:compile).raises(RuntimeError, 'aah! fail!')
343
+
344
+ # Create autocompiler
345
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
346
+ autocompiler.stubs(:build_site)
347
+ autocompiler.stubs(:site).returns(site)
348
+
349
+ # Serve
350
+ assert_raises(RuntimeError) do
351
+ autocompiler.instance_eval { call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/whatever/') }
352
+ end
353
+ end
354
+ end
355
+ end
356
+
357
+ def test_reload_config_file_before_each_request
358
+ if_have 'mime/types', 'rack' do
359
+ # Create site
360
+ Nanoc::CLI.run %w( create_site foo )
361
+
362
+ FileUtils.cd('foo') do
363
+ # Create item that outputs config elements
364
+ File.open('content/index.html', 'w') do |io|
365
+ io.write "The Grand Value of Configuration is <%= @config[:value] %>!"
366
+ end
367
+
368
+ # Create autocompiler
369
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
370
+
371
+ # Set config to 1st value
372
+ File.open('config.yaml', 'w') do |io|
373
+ io.write "value: Foo"
374
+ end
375
+ File.utime(Time.now+5, Time.now+5, 'config.yaml')
376
+
377
+ # Check
378
+ status, headers, body = autocompiler.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/')
379
+ body.each do |b|
380
+ assert_match /The Grand Value of Configuration is Foo!/, b
381
+ end
382
+
383
+ # Set config to 2nd value
384
+ File.open('config.yaml', 'w') do |io|
385
+ io.write "value: Bar"
386
+ end
387
+ File.utime(Time.now+5, Time.now+5, 'config.yaml')
388
+
389
+ # Check
390
+ status, headers, body = autocompiler.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/')
391
+ body.each do |b|
392
+ assert_match /The Grand Value of Configuration is Bar!/, b
393
+ end
394
+ end
395
+ end
396
+ end
397
+
398
+ def test_call_with_uri_encoded_path
399
+ if_have 'rack' do
400
+ # Create autocompiler
401
+ autocompiler = Nanoc::Extra::AutoCompiler.new('.')
402
+
403
+ # Mock dependencies
404
+ site = mock
405
+ site.stubs(:config).returns({ :output_dir => 'output/' })
406
+ site.stubs(:items).returns([])
407
+ autocompiler.stubs(:build_site)
408
+ autocompiler.stubs(:site).returns(site)
409
+
410
+ # Test
411
+ result = autocompiler.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/%73oftware')
412
+ assert_equal 404, result[0]
413
+ assert_match "File not found: /software\n", result[2][0]
414
+ end
415
+ end
416
+
417
+ end