nanoc3 3.1.7 → 3.1.8

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 (91) hide show
  1. data/.gemtest +0 -0
  2. data/LICENSE +1 -1
  3. data/NEWS.md +9 -0
  4. data/doc/yardoc_templates/default/layout/html/footer.erb +10 -0
  5. data/lib/nanoc3/base/item.rb +1 -1
  6. data/lib/nanoc3/base/item_rep.rb +1 -0
  7. data/lib/nanoc3/base/layout.rb +1 -1
  8. data/lib/nanoc3/cli/base.rb +4 -2
  9. data/lib/nanoc3/cli/commands/view.rb +1 -0
  10. data/lib/nanoc3/data_sources/filesystem.rb +25 -6
  11. data/lib/nanoc3/data_sources/filesystem_unified.rb +5 -5
  12. data/lib/nanoc3/extra/validators/links.rb +1 -1
  13. data/lib/nanoc3/filters/rdiscount.rb +2 -1
  14. data/lib/nanoc3/filters/sass.rb +20 -8
  15. data/lib/nanoc3/filters/sass.rb.orig +75 -0
  16. data/lib/nanoc3.rb +1 -1
  17. data/nanoc3.gemspec +41 -0
  18. data/tasks/clean.rake +11 -0
  19. data/tasks/doc.rake +14 -0
  20. data/tasks/gem.rake +13 -0
  21. data/tasks/test.rake +38 -0
  22. data/test/base/core_ext/array_spec.rb +23 -0
  23. data/test/base/core_ext/hash_spec.rb +41 -0
  24. data/test/base/core_ext/string_spec.rb +27 -0
  25. data/test/base/test_code_snippet.rb +33 -0
  26. data/test/base/test_compiler.rb +410 -0
  27. data/test/base/test_compiler_dsl.rb +121 -0
  28. data/test/base/test_context.rb +33 -0
  29. data/test/base/test_data_source.rb +48 -0
  30. data/test/base/test_dependency_tracker.rb +510 -0
  31. data/test/base/test_directed_graph.rb +91 -0
  32. data/test/base/test_filter.rb +85 -0
  33. data/test/base/test_item.rb +141 -0
  34. data/test/base/test_item_rep.rb +953 -0
  35. data/test/base/test_layout.rb +44 -0
  36. data/test/base/test_notification_center.rb +36 -0
  37. data/test/base/test_plugin.rb +32 -0
  38. data/test/base/test_rule.rb +21 -0
  39. data/test/base/test_rule_context.rb +63 -0
  40. data/test/base/test_site.rb +366 -0
  41. data/test/cli/commands/test_compile.rb +12 -0
  42. data/test/cli/commands/test_create_item.rb +12 -0
  43. data/test/cli/commands/test_create_layout.rb +28 -0
  44. data/test/cli/commands/test_create_site.rb +24 -0
  45. data/test/cli/commands/test_help.rb +12 -0
  46. data/test/cli/commands/test_info.rb +12 -0
  47. data/test/cli/commands/test_update.rb +12 -0
  48. data/test/cli/test_logger.rb +12 -0
  49. data/test/data_sources/test_filesystem.rb +420 -0
  50. data/test/data_sources/test_filesystem_unified.rb +538 -0
  51. data/test/data_sources/test_filesystem_verbose.rb +359 -0
  52. data/test/extra/core_ext/test_enumerable.rb +32 -0
  53. data/test/extra/core_ext/test_time.rb +17 -0
  54. data/test/extra/deployers/test_rsync.rb +234 -0
  55. data/test/extra/test_auto_compiler.rb +482 -0
  56. data/test/extra/test_file_proxy.rb +21 -0
  57. data/test/extra/test_vcs.rb +24 -0
  58. data/test/extra/validators/test_links.rb +53 -0
  59. data/test/extra/validators/test_w3c.rb +49 -0
  60. data/test/filters/test_bluecloth.rb +20 -0
  61. data/test/filters/test_coderay.rb +46 -0
  62. data/test/filters/test_colorize_syntax.rb +56 -0
  63. data/test/filters/test_erb.rb +72 -0
  64. data/test/filters/test_erubis.rb +72 -0
  65. data/test/filters/test_haml.rb +98 -0
  66. data/test/filters/test_kramdown.rb +20 -0
  67. data/test/filters/test_less.rb +59 -0
  68. data/test/filters/test_markaby.rb +26 -0
  69. data/test/filters/test_maruku.rb +20 -0
  70. data/test/filters/test_rainpress.rb +31 -0
  71. data/test/filters/test_rdiscount.rb +33 -0
  72. data/test/filters/test_rdoc.rb +18 -0
  73. data/test/filters/test_redcloth.rb +20 -0
  74. data/test/filters/test_relativize_paths.rb +231 -0
  75. data/test/filters/test_rubypants.rb +20 -0
  76. data/test/filters/test_sass.rb +170 -0
  77. data/test/filters/test_sass.rb.orig +103 -0
  78. data/test/gem_loader.rb +11 -0
  79. data/test/helper.rb +99 -0
  80. data/test/helpers/test_blogging.rb +808 -0
  81. data/test/helpers/test_breadcrumbs.rb +83 -0
  82. data/test/helpers/test_capturing.rb +42 -0
  83. data/test/helpers/test_filtering.rb +108 -0
  84. data/test/helpers/test_html_escape.rb +18 -0
  85. data/test/helpers/test_link_to.rb +251 -0
  86. data/test/helpers/test_rendering.rb +109 -0
  87. data/test/helpers/test_tagging.rb +89 -0
  88. data/test/helpers/test_text.rb +26 -0
  89. data/test/helpers/test_xml_sitemap.rb +69 -0
  90. data/test/tasks/test_clean.rb +71 -0
  91. metadata +83 -8
@@ -0,0 +1,538 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/helper'
4
+
5
+ class Nanoc3::DataSources::FilesystemUnifiedTest < MiniTest::Unit::TestCase
6
+
7
+ include Nanoc3::TestHelpers
8
+
9
+ def new_data_source(params=nil)
10
+ # Mock site
11
+ site = Nanoc3::Site.new({})
12
+
13
+ # Create data source
14
+ data_source = Nanoc3::DataSources::FilesystemUnified.new(site, nil, nil, params)
15
+
16
+ # Done
17
+ data_source
18
+ end
19
+
20
+ def test_create_object_not_at_root
21
+ # Create item
22
+ data_source = new_data_source
23
+ data_source.send(:create_object, 'foobar', 'content here', { :foo => 'bar' }, '/asdf/')
24
+
25
+ # Check file existance
26
+ assert File.directory?('foobar')
27
+ assert !File.directory?('foobar/content')
28
+ assert !File.directory?('foobar/asdf')
29
+ assert File.file?('foobar/asdf.html')
30
+
31
+ # Check file content
32
+ expected = "--- \nfoo: bar\n---\n\ncontent here"
33
+ assert_equal expected, File.read('foobar/asdf.html')
34
+ end
35
+
36
+ def test_create_object_at_root
37
+ # Create item
38
+ data_source = new_data_source
39
+ data_source.send(:create_object, 'foobar', 'content here', { :foo => 'bar' }, '/')
40
+
41
+ # Check file existance
42
+ assert File.directory?('foobar')
43
+ assert !File.directory?('foobar/index')
44
+ assert !File.directory?('foobar/foobar')
45
+ assert File.file?('foobar/index.html')
46
+
47
+ # Check file content
48
+ expected = "--- \nfoo: bar\n---\n\ncontent here"
49
+ assert_equal expected, File.read('foobar/index.html')
50
+ end
51
+
52
+ def test_load_objects
53
+ # Create data source
54
+ data_source = new_data_source
55
+
56
+ # Create a fake class
57
+ klass = Class.new do
58
+ attr_reader :stuff
59
+ def initialize(*stuff)
60
+ @stuff = stuff
61
+ end
62
+ def ==(other)
63
+ @stuff == other.stuff
64
+ end
65
+ end
66
+
67
+ # Create sample files
68
+ FileUtils.mkdir_p('foo')
69
+ FileUtils.mkdir_p('foo/a/b')
70
+ File.open('foo/bar.html', 'w') { |io| io.write("---\nnum: 1\n---\ntest 1") }
71
+ File.open('foo/b.c.html', 'w') { |io| io.write("---\nnum: 2\n---\ntest 2") }
72
+ File.open('foo/a/b/c.html', 'w') { |io| io.write("---\nnum: 3\n---\ntest 3") }
73
+ File.open('foo/ugly.html~', 'w') { |io| io.write("---\nnum: 4\n---\ntest 4") }
74
+ File.open('foo/ugly.html.orig', 'w') { |io| io.write("---\nnum: 5\n---\ntest 5") }
75
+ File.open('foo/ugly.html.rej', 'w') { |io| io.write("---\nnum: 6\n---\ntest 6") }
76
+ File.open('foo/ugly.html.bak', 'w') { |io| io.write("---\nnum: 7\n---\ntest 7") }
77
+
78
+ # Get expected and actual output
79
+ expected_out = [
80
+ klass.new(
81
+ 'test 1',
82
+ { 'num' => 1, :filename => 'foo/bar.html', :extension => 'html', :file => File.open('foo/bar.html') },
83
+ '/bar/',
84
+ :binary => false, :mtime => File.mtime('foo/bar.html')
85
+ ),
86
+ klass.new(
87
+ 'test 2',
88
+ { 'num' => 2, :filename => 'foo/b.c.html', :extension => 'c.html', :file => File.open('foo/b.c.html') },
89
+ '/b/',
90
+ :binary => false, :mtime => File.mtime('foo/b.c.html')
91
+ ),
92
+ klass.new(
93
+ 'test 3',
94
+ { 'num' => 3, :filename => 'foo/a/b/c.html', :extension => 'html', :file => File.open('foo/a/b/c.html') },
95
+ '/a/b/c/',
96
+ :binary => false, :mtime => File.mtime('foo/a/b/c.html')
97
+ )
98
+ ]
99
+ actual_out = data_source.send(:load_objects, 'foo', 'The Foo', klass).sort_by { |i| i.stuff[0] }
100
+
101
+ # Check
102
+ (0..expected_out.size-1).each do |i|
103
+ assert_equal expected_out[i].stuff[0], actual_out[i].stuff[0], 'content must match'
104
+ assert_equal expected_out[i].stuff[2], actual_out[i].stuff[2], 'identifier must match'
105
+ assert_equal expected_out[i].stuff[3], actual_out[i].stuff[3], 'mtime must match'
106
+ assert_equal expected_out[i].stuff[1][:file].path, actual_out[i].stuff[1][:file].path, 'file paths must match'
107
+ expected_out[i].stuff[1][:file].close;
108
+ actual_out[i].stuff[1][:file].close
109
+ [ 'num', :filename, :extension ].each do |key|
110
+ assert_equal expected_out[i].stuff[1][key], actual_out[i].stuff[1][key], "attribute key #{key} must match"
111
+ end
112
+ end
113
+ end
114
+
115
+ def test_load_binary_objects
116
+ # Create data source
117
+ data_source = new_data_source
118
+
119
+ # Create sample files
120
+ FileUtils.mkdir_p('foo')
121
+ File.open('foo/stuff.dat', 'w') { |io| io.write("random binary data") }
122
+
123
+ # Load
124
+ items = data_source.send(:load_objects, 'foo', 'item', Nanoc3::Item)
125
+
126
+ # Check
127
+ assert_equal 1, items.size
128
+ assert items[0].binary?
129
+ assert_equal 'foo/stuff.dat', items[0].raw_filename
130
+ assert_nil items[0].raw_content
131
+ end
132
+
133
+ def test_load_binary_layouts
134
+ # Create data source
135
+ data_source = new_data_source
136
+
137
+ # Create sample files
138
+ FileUtils.mkdir_p('foo')
139
+ File.open('foo/stuff.dat', 'w') { |io| io.write("random binary data") }
140
+
141
+ # Load
142
+ items = data_source.send(:load_objects, 'foo', 'item', Nanoc3::Layout)
143
+
144
+ # Check
145
+ assert_equal 1, items.size
146
+ assert_equal 'random binary data', items[0].raw_content
147
+ end
148
+
149
+ def test_identifier_for_filename_allowing_periods_in_identifiers
150
+ # Create data source
151
+ data_source = new_data_source(:allow_periods_in_identifiers => true)
152
+
153
+ # Get input and expected output
154
+ expected = {
155
+ '/foo' => '/foo/',
156
+ '/foo.html' => '/foo/',
157
+ '/foo/index.html' => '/foo/',
158
+ '/foo.entry.html' => '/foo.entry/'
159
+ }
160
+
161
+ # Check
162
+ expected.each_pair do |input, expected_output|
163
+ actual_output = data_source.send(:identifier_for_filename, input)
164
+ assert_equal(
165
+ expected_output, actual_output,
166
+ "identifier_for_filename(#{input.inspect}) should equal #{expected_output.inspect}, not #{actual_output.inspect}"
167
+ )
168
+ end
169
+ end
170
+
171
+ def test_identifier_for_filename_disallowing_periods_in_identifiers
172
+ # Create data source
173
+ data_source = new_data_source
174
+
175
+ # Get input and expected output
176
+ expected = {
177
+ '/foo' => '/foo/',
178
+ '/foo.html' => '/foo/',
179
+ '/foo/index.html' => '/foo/',
180
+ '/foo.html.erb' => '/foo/'
181
+ }
182
+
183
+ # Check
184
+ expected.each_pair do |input, expected_output|
185
+ actual_output = data_source.send(:identifier_for_filename, input)
186
+ assert_equal(
187
+ expected_output, actual_output,
188
+ "identifier_for_filename(#{input.inspect}) should equal #{expected_output.inspect}, not #{actual_output.inspect}"
189
+ )
190
+ end
191
+ end
192
+
193
+ def test_identifier_for_filename_with_subfilename_allowing_periods_in_identifiers
194
+ expectations = {
195
+ 'foo/bar.yaml' => '/foo/bar/',
196
+ 'foo/quxbar.yaml' => '/foo/quxbar/',
197
+ 'foo/barqux.yaml' => '/foo/barqux/',
198
+ 'foo/quxbarqux.yaml' => '/foo/quxbarqux/',
199
+ 'foo/qux.bar.yaml' => '/foo/qux.bar/',
200
+ 'foo/bar.qux.yaml' => '/foo/bar.qux/',
201
+ 'foo/qux.bar.qux.yaml' => '/foo/qux.bar.qux/',
202
+ 'foo/index.yaml' => '/foo/',
203
+ 'index.yaml' => '/',
204
+ 'foo/blah_index.yaml' => '/foo/blah_index/'
205
+ }
206
+
207
+ data_source = new_data_source(:allow_periods_in_identifiers => true)
208
+ expectations.each_pair do |meta_filename, expected_identifier|
209
+ content_filename = meta_filename.sub(/yaml$/, 'html')
210
+ [ meta_filename, content_filename ].each do |filename|
211
+ assert_equal(
212
+ expected_identifier,
213
+ data_source.instance_eval { identifier_for_filename(filename) }
214
+ )
215
+ end
216
+ end
217
+ end
218
+
219
+ def test_identifier_for_filename_with_subfilename_disallowing_periods_in_identifiers
220
+ expectations = {
221
+ 'foo/bar.yaml' => '/foo/bar/',
222
+ 'foo/quxbar.yaml' => '/foo/quxbar/',
223
+ 'foo/barqux.yaml' => '/foo/barqux/',
224
+ 'foo/quxbarqux.yaml' => '/foo/quxbarqux/',
225
+ 'foo/qux.bar.yaml' => '/foo/qux/',
226
+ 'foo/bar.qux.yaml' => '/foo/bar/',
227
+ 'foo/qux.bar.qux.yaml' => '/foo/qux/',
228
+ 'foo/index.yaml' => '/foo/',
229
+ 'index.yaml' => '/',
230
+ 'foo/blah_index.yaml' => '/foo/blah_index/'
231
+ }
232
+
233
+ data_source = new_data_source
234
+ expectations.each_pair do |meta_filename, expected_identifier|
235
+ content_filename = meta_filename.sub(/yaml$/, 'html')
236
+ [ meta_filename, content_filename ].each do |filename|
237
+ assert_equal(
238
+ expected_identifier,
239
+ data_source.instance_eval { identifier_for_filename(filename) }
240
+ )
241
+ end
242
+ end
243
+ end
244
+
245
+ def test_load_objects_allowing_periods_in_identifiers
246
+ # Create data source
247
+ data_source = new_data_source(:allow_periods_in_identifiers => true)
248
+
249
+ # Create a fake class
250
+ klass = Class.new do
251
+ attr_reader :stuff
252
+ def initialize(*stuff)
253
+ @stuff = stuff
254
+ end
255
+ def ==(other)
256
+ @stuff == other.stuff
257
+ end
258
+ end
259
+
260
+ # Create sample files
261
+ FileUtils.mkdir_p('foo')
262
+ FileUtils.mkdir_p('foo/a/b')
263
+ File.open('foo/a/b/c.yaml', 'w') { |io| io.write("---\nnum: 1\n") }
264
+ File.open('foo/b.c.yaml', 'w') { |io| io.write("---\nnum: 2\n") }
265
+ File.open('foo/b.c.html', 'w') { |io| io.write("test 2") }
266
+ File.open('foo/car.html', 'w') { |io| io.write("test 3") }
267
+ File.open('foo/ugly.yaml~', 'w') { |io| io.write("blah") }
268
+ File.open('foo/ugly.html~', 'w') { |io| io.write("blah") }
269
+ File.open('foo/ugly.html.orig', 'w') { |io| io.write("blah") }
270
+ File.open('foo/ugly.html.rej', 'w') { |io| io.write("blah") }
271
+ File.open('foo/ugly.html.bak', 'w') { |io| io.write("blah") }
272
+
273
+ # Get expected output
274
+ expected_out = [
275
+ klass.new(
276
+ '',
277
+ {
278
+ 'num' => 1,
279
+ :content_filename => nil,
280
+ :meta_filename => 'foo/a/b/c.yaml',
281
+ :extension => nil,
282
+ :file => nil
283
+ },
284
+ '/a/b/c/',
285
+ :binary => false, :mtime => File.mtime('foo/a/b/c.yaml')
286
+ ),
287
+ klass.new(
288
+ 'test 2',
289
+ {
290
+ 'num' => 2,
291
+ :content_filename => 'foo/b.c.html',
292
+ :meta_filename => 'foo/b.c.yaml',
293
+ :extension => 'html',
294
+ :file => File.open('foo/b.c.html')
295
+ },
296
+ '/b.c/',
297
+ :binary => false, :mtime => File.mtime('foo/b.c.html') > File.mtime('foo/b.c.yaml') ? File.mtime('foo/b.c.html') : File.mtime('foo/b.c.yaml')
298
+ ),
299
+ klass.new(
300
+ 'test 3',
301
+ {
302
+ :content_filename => 'foo/car.html',
303
+ :meta_filename => nil,
304
+ :extension => 'html',
305
+ :file => File.open('foo/car.html')
306
+ },
307
+ '/car/',
308
+ :binary => false, :mtime => File.mtime('foo/car.html')
309
+ )
310
+ ]
311
+
312
+ # Get actual output ordered by identifier
313
+ actual_out = data_source.send(:load_objects, 'foo', 'The Foo', klass).sort_by { |i| i.stuff[2] }
314
+
315
+ # Check
316
+ (0..expected_out.size-1).each do |i|
317
+ assert_equal expected_out[i].stuff[0], actual_out[i].stuff[0], 'content must match'
318
+ assert_equal expected_out[i].stuff[2], actual_out[i].stuff[2], 'identifier must match'
319
+ assert_equal expected_out[i].stuff[3], actual_out[i].stuff[3], 'mtime must match'
320
+
321
+ actual_file = actual_out[i].stuff[1][:file]
322
+ expected_file = expected_out[i].stuff[1][:file]
323
+ assert(actual_file == expected_file || actual_file.path == expected_file.path, 'file paths must match')
324
+ actual_file.close unless actual_file.nil?
325
+ expected_file.close unless expected_file.nil?
326
+
327
+ [ 'num', :content_filename, :meta_filename, :extension ].each do |key|
328
+ assert_equal expected_out[i].stuff[1][key], actual_out[i].stuff[1][key], "attribute key #{key} must match"
329
+ end
330
+ end
331
+ end
332
+
333
+ def test_load_objects_disallowing_periods_in_identifiers
334
+ # Create data source
335
+ data_source = new_data_source
336
+
337
+ # Create a fake class
338
+ klass = Class.new do
339
+ attr_reader :stuff
340
+ def initialize(*stuff)
341
+ @stuff = stuff
342
+ end
343
+ def ==(other)
344
+ @stuff == other.stuff
345
+ end
346
+ end
347
+
348
+ # Create sample files
349
+ FileUtils.mkdir_p('foo')
350
+ FileUtils.mkdir_p('foo/a/b')
351
+ File.open('foo/a/b/c.yaml', 'w') { |io| io.write("---\nnum: 1\n") }
352
+ File.open('foo/b.yaml', 'w') { |io| io.write("---\nnum: 2\n") }
353
+ File.open('foo/b.html.erb', 'w') { |io| io.write("test 2") }
354
+ File.open('foo/car.html', 'w') { |io| io.write("test 3") }
355
+ File.open('foo/ugly.yaml~', 'w') { |io| io.write("blah") }
356
+ File.open('foo/ugly.html~', 'w') { |io| io.write("blah") }
357
+ File.open('foo/ugly.html.orig', 'w') { |io| io.write("blah") }
358
+ File.open('foo/ugly.html.rej', 'w') { |io| io.write("blah") }
359
+ File.open('foo/ugly.html.bak', 'w') { |io| io.write("blah") }
360
+
361
+ # Get expected output
362
+ expected_out = [
363
+ klass.new(
364
+ '',
365
+ {
366
+ 'num' => 1,
367
+ :content_filename => nil,
368
+ :meta_filename => 'foo/a/b/c.yaml',
369
+ :extension => nil,
370
+ :file => nil
371
+ },
372
+ '/a/b/c/',
373
+ :binary => false, :mtime => File.mtime('foo/a/b/c.yaml')
374
+ ),
375
+ klass.new(
376
+ 'test 2',
377
+ {
378
+ 'num' => 2,
379
+ :content_filename => 'foo/b.html.erb',
380
+ :meta_filename => 'foo/b.yaml',
381
+ :extension => 'html.erb',
382
+ :file => File.open('foo/b.html.erb')
383
+ },
384
+ '/b/',
385
+ :binary => false, :mtime => File.mtime('foo/b.html.erb') > File.mtime('foo/b.yaml') ? File.mtime('foo/b.html.erb') : File.mtime('foo/b.yaml')
386
+ ),
387
+ klass.new(
388
+ 'test 3',
389
+ {
390
+ :content_filename => 'foo/car.html',
391
+ :meta_filename => nil,
392
+ :extension => 'html',
393
+ :file => File.open('foo/car.html')
394
+ },
395
+ '/car/',
396
+ :binary => false, :mtime => File.mtime('foo/car.html')
397
+ )
398
+ ]
399
+
400
+ # Get actual output ordered by identifier
401
+ actual_out = data_source.send(:load_objects, 'foo', 'The Foo', klass).sort_by { |i| i.stuff[2] }
402
+
403
+ # Check
404
+ (0..expected_out.size-1).each do |i|
405
+ assert_equal expected_out[i].stuff[0], actual_out[i].stuff[0], 'content must match'
406
+ assert_equal expected_out[i].stuff[2], actual_out[i].stuff[2], 'identifier must match'
407
+ assert_equal expected_out[i].stuff[3], actual_out[i].stuff[3], 'mtime must match'
408
+
409
+ actual_file = actual_out[i].stuff[1][:file]
410
+ expected_file = expected_out[i].stuff[1][:file]
411
+ assert(actual_file == expected_file || actual_file.path == expected_file.path, 'file paths must match')
412
+ actual_file.close unless actual_file.nil?
413
+ expected_file.close unless expected_file.nil?
414
+
415
+ [ 'num', :content_filename, :meta_filename, :extension ].each do |key|
416
+ assert_equal expected_out[i].stuff[1][key], actual_out[i].stuff[1][key], "attribute key #{key} must match"
417
+ end
418
+ end
419
+ end
420
+
421
+ def test_create_object_allowing_periods_in_identifiers
422
+ # Create data source
423
+ data_source = new_data_source(:allow_periods_in_identifiers => true)
424
+
425
+ # Create object without period
426
+ data_source.send(:create_object, 'foo', 'some content', { :some => 'attributes' }, '/asdf/')
427
+ assert File.file?('foo/asdf.html')
428
+ data = data_source.send(:parse, 'foo/asdf.html', nil, 'moo')
429
+ assert_equal({ 'some' => 'attributes' }, data[0])
430
+ assert_equal('some content', data[1])
431
+
432
+ # Create object with period
433
+ data_source.send(:create_object, 'foo', 'some content', { :some => 'attributes' }, '/as.df/')
434
+ assert File.file?('foo/as.df.html')
435
+ data = data_source.send(:parse, 'foo/as.df.html', nil, 'moo')
436
+ assert_equal({ 'some' => 'attributes' }, data[0])
437
+ assert_equal('some content', data[1])
438
+ end
439
+
440
+ def test_create_object_disallowing_periods_in_identifiers
441
+ # Create data source
442
+ data_source = new_data_source
443
+
444
+ # Create object without period
445
+ data_source.send(:create_object, 'foo', 'some content', { :some => 'attributes' }, '/asdf/')
446
+ assert File.file?('foo/asdf.html')
447
+ data = data_source.send(:parse, 'foo/asdf.html', nil, 'moo')
448
+ assert_equal({ 'some' => 'attributes' }, data[0])
449
+ assert_equal('some content', data[1])
450
+
451
+ # Create object with period
452
+ assert_raises(RuntimeError) do
453
+ data_source.send(:create_object, 'foo', 'some content', { :some => 'attributes' }, '/as.df/')
454
+ end
455
+ end
456
+
457
+ def test_filename_for
458
+ data_source = new_data_source
459
+
460
+ assert_equal '/foo.bar', data_source.send(:filename_for, '/foo', 'bar')
461
+ assert_equal '/foo.bar.baz', data_source.send(:filename_for, '/foo', 'bar.baz')
462
+ assert_equal '/foo', data_source.send(:filename_for, '/foo', '')
463
+ assert_equal nil, data_source.send(:filename_for, '/foo', nil)
464
+ end
465
+
466
+ def test_compile_huge_site
467
+ if_implemented do
468
+ # Create data source
469
+ data_source = new_data_source
470
+
471
+ # Create a lot of items
472
+ count = Process.getrlimit(Process::RLIMIT_NOFILE)[0] + 5
473
+ count.times do |i|
474
+ FileUtils.mkdir_p("content/#{i}")
475
+ File.open("content/#{i}/#{i}.html", 'w') { |io| io << "This is item #{i}." }
476
+ File.open("content/#{i}/#{i}.yaml", 'w') { |io| io << "title: Item #{i}" }
477
+ end
478
+
479
+ # Read all items
480
+ data_source.items
481
+ end
482
+ end
483
+
484
+ def test_compile_iso_8859_1_site
485
+ # Check encoding
486
+ if !''.respond_to?(:encode)
487
+ skip "Test only works on 1.9.x"
488
+ return
489
+ end
490
+
491
+ # Create data source
492
+ data_source = new_data_source
493
+
494
+ # Create item
495
+ data_source.create_item("Hëllö", {}, '/foo/')
496
+
497
+ # Parse
498
+ begin
499
+ original_default_external_encoding = Encoding.default_external
500
+ Encoding.default_external = 'ISO-8859-1'
501
+
502
+ items = data_source.items
503
+
504
+ assert_equal 1, items.size
505
+ assert_equal Encoding.find("UTF-8"), items[0].raw_content.encoding
506
+ ensure
507
+ Encoding.default_external = original_default_external_encoding
508
+ end
509
+ end
510
+
511
+ def test_compile_iso_8859_1_site_with_explicit_encoding
512
+ # Check encoding
513
+ if !''.respond_to?(:encode)
514
+ skip "Test only works on 1.9.x"
515
+ return
516
+ end
517
+
518
+ # Create data source
519
+ data_source = new_data_source({})
520
+ data_source.config[:encoding] = 'ISO-8859-1'
521
+
522
+ # Create item
523
+ begin
524
+ original_default_external_encoding = Encoding.default_external
525
+ Encoding.default_external = 'ISO-8859-1'
526
+
527
+ data_source.create_item("Hëllö", {}, '/foo/')
528
+ ensure
529
+ Encoding.default_external = original_default_external_encoding
530
+ end
531
+
532
+ # Parse
533
+ items = data_source.items
534
+ assert_equal 1, items.size
535
+ assert_equal Encoding.find("UTF-8"), items[0].raw_content.encoding
536
+ end
537
+
538
+ end