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,231 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/helper'
4
+
5
+ class Nanoc3::Filters::RelativizePathsTest < MiniTest::Unit::TestCase
6
+
7
+ include Nanoc3::TestHelpers
8
+
9
+ def test_filter_html_with_double_quotes
10
+ # Create filter with mock item
11
+ filter = Nanoc3::Filters::RelativizePaths.new
12
+
13
+ # Mock item
14
+ filter.instance_eval do
15
+ @item_rep = MiniTest::Mock.new
16
+ @item_rep.expect(:path, '/foo/bar/baz/')
17
+ end
18
+
19
+ # Set content
20
+ raw_content = %[<a href="/foo">foo</a>]
21
+ expected_content = %[<a href="../..">foo</a>]
22
+
23
+ # Test
24
+ actual_content = filter.run(raw_content, :type => :html)
25
+ assert_equal(expected_content, actual_content)
26
+ end
27
+
28
+ def test_filter_html_with_single_quotes
29
+ # Create filter with mock item
30
+ filter = Nanoc3::Filters::RelativizePaths.new
31
+
32
+ # Mock item
33
+ filter.instance_eval do
34
+ @item_rep = MiniTest::Mock.new
35
+ @item_rep.expect(:path, '/foo/bar/baz/')
36
+ end
37
+
38
+ # Set content
39
+ raw_content = %[<a href='/foo'>foo</a>]
40
+ expected_content = %[<a href='../..'>foo</a>]
41
+
42
+ # Test
43
+ actual_content = filter.run(raw_content, :type => :html)
44
+ assert_equal(expected_content, actual_content)
45
+ end
46
+
47
+ def test_filter_html_without_quotes
48
+ # Create filter with mock item
49
+ filter = Nanoc3::Filters::RelativizePaths.new
50
+
51
+ # Mock item
52
+ filter.instance_eval do
53
+ @item_rep = MiniTest::Mock.new
54
+ @item_rep.expect(:path, '/foo/bar/baz/')
55
+ end
56
+
57
+ # Set content
58
+ raw_content = %[<a href=/foo>foo</a>]
59
+ expected_content = %[<a href=../..>foo</a>]
60
+
61
+ # Test
62
+ actual_content = filter.run(raw_content, :type => :html)
63
+ assert_equal(expected_content, actual_content)
64
+ end
65
+
66
+ def test_filter_html_multiple
67
+ # Create filter with mock item
68
+ filter = Nanoc3::Filters::RelativizePaths.new
69
+
70
+ # Mock item
71
+ filter.instance_eval do
72
+ @item_rep = MiniTest::Mock.new
73
+ @item_rep.expect(:path, '/foo/bar/baz/')
74
+ end
75
+
76
+ # Set content
77
+ raw_content = %[<a href="/foo">foo</a> <a href="/bar">bar</a>]
78
+ expected_content = %[<a href="../..">foo</a> <a href="../../../bar">bar</a>]
79
+
80
+ # Test
81
+ actual_content = filter.run(raw_content, :type => :html)
82
+ assert_equal(expected_content, actual_content)
83
+ end
84
+
85
+ def test_filter_html_outside_tag
86
+ # Create filter with mock item
87
+ filter = Nanoc3::Filters::RelativizePaths.new
88
+
89
+ # Mock item
90
+ filter.instance_eval do
91
+ @item_rep = MiniTest::Mock.new
92
+ @item_rep.expect(:path, '/foo/bar/baz/')
93
+ end
94
+
95
+ # Set content
96
+ raw_content = %[stuff href="/foo" more stuff]
97
+ expected_content = %[stuff href="/foo" more stuff]
98
+
99
+ # Test
100
+ actual_content = filter.run(raw_content, :type => :html)
101
+ assert_equal(expected_content, actual_content)
102
+ end
103
+
104
+ def test_filter_html_root
105
+ # Create filter with mock item
106
+ filter = Nanoc3::Filters::RelativizePaths.new
107
+
108
+ # Mock item
109
+ filter.instance_eval do
110
+ @item_rep = MiniTest::Mock.new
111
+ @item_rep.expect(:path, '/woof/meow/')
112
+ end
113
+
114
+ # Set content
115
+ raw_content = %[<a href="/">foo</a>]
116
+ expected_content = %[<a href="../../">foo</a>]
117
+
118
+ # Test
119
+ actual_content = filter.run(raw_content, :type => :html)
120
+ assert_equal(expected_content, actual_content)
121
+ end
122
+
123
+ def test_filter_implicit
124
+ # Create filter with mock item
125
+ filter = Nanoc3::Filters::RelativizePaths.new
126
+
127
+ # Test
128
+ assert_raises(RuntimeError) do
129
+ filter.run("moo")
130
+ end
131
+ end
132
+
133
+ def test_filter_css_with_double_quotes
134
+ # Create filter with mock item
135
+ filter = Nanoc3::Filters::RelativizePaths.new
136
+
137
+ # Mock item
138
+ filter.instance_eval do
139
+ @item_rep = MiniTest::Mock.new
140
+ @item_rep.expect(:path, '/foo/bar/baz/')
141
+ end
142
+
143
+ # Set content
144
+ raw_content = %[background: url("/foo/bar/background.png");]
145
+ expected_content = %[background: url("../background.png");]
146
+
147
+ # Test
148
+ actual_content = filter.run(raw_content, :type => :css)
149
+ assert_equal(expected_content, actual_content)
150
+ end
151
+
152
+ def test_filter_css_with_single_quotes
153
+ # Create filter with mock item
154
+ filter = Nanoc3::Filters::RelativizePaths.new
155
+
156
+ # Mock item
157
+ filter.instance_eval do
158
+ @item_rep = MiniTest::Mock.new
159
+ @item_rep.expect(:path, '/foo/bar/baz/')
160
+ end
161
+
162
+ # Set content
163
+ raw_content = %[background: url('/foo/bar/background.png');]
164
+ expected_content = %[background: url('../background.png');]
165
+
166
+ # Test
167
+ actual_content = filter.run(raw_content, :type => :css)
168
+ assert_equal(expected_content, actual_content)
169
+ end
170
+
171
+ def test_filter_css_without_quotes
172
+ # Create filter with mock item
173
+ filter = Nanoc3::Filters::RelativizePaths.new
174
+
175
+ # Mock item
176
+ filter.instance_eval do
177
+ @item_rep = MiniTest::Mock.new
178
+ @item_rep.expect(:path, '/foo/bar/baz/')
179
+ end
180
+
181
+ # Set content
182
+ raw_content = %[background: url(/foo/bar/background.png);]
183
+ expected_content = %[background: url(../background.png);]
184
+
185
+ # Test
186
+ actual_content = filter.run(raw_content, :type => :css)
187
+ assert_equal(expected_content, actual_content)
188
+ end
189
+
190
+ def test_filter_css_multiple
191
+ # Create filter with mock item
192
+ filter = Nanoc3::Filters::RelativizePaths.new
193
+
194
+ # Mock item
195
+ filter.instance_eval do
196
+ @item_rep = MiniTest::Mock.new
197
+ @item_rep.expect(:path, '/foo/bar/baz/')
198
+ end
199
+
200
+ # Set content
201
+ raw_content = %[background: url(/foo/bar/a.png) url(/foo/bar/b.png);]
202
+ expected_content = %[background: url(../a.png) url(../b.png);]
203
+
204
+ # Test
205
+ actual_content = filter.run(raw_content, :type => :css)
206
+ assert_equal(expected_content, actual_content)
207
+ end
208
+
209
+ def test_filter_css_root
210
+ # It is probably a bit weird to have “url(/)” in CSS, but I’ve made a
211
+ # test case for this situation anyway. Can’t hurt…
212
+
213
+ # Create filter with mock item
214
+ filter = Nanoc3::Filters::RelativizePaths.new
215
+
216
+ # Mock item
217
+ filter.instance_eval do
218
+ @item_rep = MiniTest::Mock.new
219
+ @item_rep.expect(:path, '/woof/meow/')
220
+ end
221
+
222
+ # Set content
223
+ raw_content = %[background: url(/);]
224
+ expected_content = %[background: url(../../);]
225
+
226
+ # Test
227
+ actual_content = filter.run(raw_content, :type => :css)
228
+ assert_equal(expected_content, actual_content)
229
+ end
230
+
231
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/helper'
4
+
5
+ class Nanoc3::Filters::RubyPantsTest < MiniTest::Unit::TestCase
6
+
7
+ include Nanoc3::TestHelpers
8
+
9
+ def test_filter
10
+ if_have 'rubypants' do
11
+ # Get filter
12
+ filter = ::Nanoc3::Filters::RubyPants.new
13
+
14
+ # Run filter
15
+ result = filter.run("Wait---what?")
16
+ assert_equal("Wait&#8212;what?", result)
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,170 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/helper'
4
+
5
+ class Nanoc3::Filters::SassTest < MiniTest::Unit::TestCase
6
+
7
+ include Nanoc3::TestHelpers
8
+
9
+ def test_filter
10
+ if_have 'sass' do
11
+ # Get filter
12
+ filter = create_filter({ :foo => 'bar' })
13
+
14
+ # Run filter
15
+ result = filter.run(".foo #bar\n color: #f00")
16
+ assert_match(/.foo\s+#bar\s*\{\s*color:\s+(red|#f00);?\s*\}/, result)
17
+ end
18
+ end
19
+
20
+ def test_filter_with_params
21
+ if_have 'sass' do
22
+ # Create filter
23
+ filter = create_filter({ :foo => 'bar' })
24
+
25
+ # Check with compact
26
+ result = filter.run(".foo #bar\n color: #f00", :style => 'compact')
27
+ assert_match(/^\.foo #bar[\s\n]*\{[\s\n]*color:\s*(red|#f00);?[\s\n]*\}/m, result)
28
+
29
+ # Check with compressed
30
+ result = filter.run(".foo #bar\n color: #f00", :style => 'compressed')
31
+ assert_match(/^\.foo #bar[\s\n]*\{[\s\n]*color:\s*(red|#f00);?[\s\n]*\}/m, result)
32
+ end
33
+ end
34
+
35
+ def test_filter_error
36
+ if_have 'sass' do
37
+ # Create filter
38
+ filter = create_filter
39
+
40
+ # Run filter
41
+ raised = false
42
+ begin
43
+ filter.run('$*#&!@($')
44
+ rescue Sass::SyntaxError => e
45
+ assert_match ':1', e.backtrace[0]
46
+ raised = true
47
+ end
48
+ assert raised
49
+ end
50
+ end
51
+
52
+ def test_filter_can_import_external_files
53
+ if_have 'sass' do
54
+ # Create filter
55
+ filter = create_filter
56
+
57
+ # Create sample file
58
+ File.open('moo.sass', 'w') { |io| io.write "body\n color: red" }
59
+
60
+ # Run filter
61
+ filter.run('@import moo')
62
+ end
63
+ end
64
+
65
+ def test_filter_can_import_relative_files
66
+ if_have 'sass' do
67
+ # Create filter
68
+ filter = create_filter
69
+
70
+ # Create sample file
71
+ File.open('moo.sass', 'w') { |io| io.write %Q{@import subdir/relative} }
72
+ FileUtils.mkdir_p("subdir")
73
+ File.open('subdir/relative.sass', 'w') { |io| io.write "body\n color: red" }
74
+
75
+ # Run filter
76
+ filter.run('@import moo')
77
+ end
78
+ end
79
+
80
+ def test_filter_will_skip_items_without_filename
81
+ if_have 'sass' do
82
+ # Create filter
83
+ filter = create_filter
84
+
85
+ # Create sample file
86
+ File.open('moo.sass', 'w') { |io| io.write "body\n color: red" }
87
+
88
+ # Run filter
89
+ filter.run('@import moo')
90
+ end
91
+ end
92
+
93
+ def test_css_imports_work
94
+ if_have 'sass' do
95
+ # Create filter
96
+ filter = create_filter
97
+
98
+ # Run filter
99
+ filter.run('@import moo.css')
100
+ end
101
+ end
102
+
103
+ def test_recompile_includes
104
+ if_have 'sass' do
105
+ # Create site
106
+ Nanoc3::CLI::Base.new.run([ 'create_site', 'bar' ])
107
+ FileUtils.cd('bar') do
108
+ # Create two Sass files
109
+ Dir['content/*'].each { |i| FileUtils.rm(i) }
110
+ File.open('content/a.sass', 'w') do |io|
111
+ io.write('@import b.sass')
112
+ end
113
+ File.open('content/b.sass', 'w') do |io|
114
+ io.write("p\n color: red")
115
+ end
116
+
117
+ # Update rules
118
+ File.open('Rules', 'w') do |io|
119
+ io.write "compile '*' do\n"
120
+ io.write " filter :sass\n"
121
+ io.write "end\n"
122
+ io.write "\n"
123
+ io.write "route '/a/' do\n"
124
+ io.write " item.identifier.chop + '.css'\n"
125
+ io.write "end\n"
126
+ io.write "\n"
127
+ io.write "route '/b/' do\n"
128
+ io.write " nil\n"
129
+ io.write "end\n"
130
+ end
131
+
132
+ # Compile
133
+ site = Nanoc3::Site.new('.')
134
+ site.load_data
135
+ site.compiler.run
136
+
137
+ # Check
138
+ assert Dir['output/*'].size == 1
139
+ assert File.file?('output/a.css')
140
+ refute File.file?('output/b.css')
141
+ assert_match /^p\s*{\s*color:\s*red;?\s*}/, File.read('output/a.css')
142
+
143
+ # Update included file
144
+ File.open('content/b.sass', 'w') do |io|
145
+ io.write("p\n color: blue")
146
+ end
147
+
148
+ # Recompile
149
+ site = Nanoc3::Site.new('.')
150
+ site.load_data
151
+ site.compiler.run
152
+
153
+ # Recheck
154
+ assert Dir['output/*'].size == 1
155
+ assert File.file?('output/a.css')
156
+ refute File.file?('output/b.css')
157
+ assert_match /^p\s*{\s*color:\s*blue;?\s*}/, File.read('output/a.css')
158
+ end
159
+ end
160
+ end
161
+
162
+ private
163
+
164
+ def create_filter(params={})
165
+ items = [ Nanoc3::Item.new('blah', { :content_filename => 'xyzzy.sass' }, '/blah/') ]
166
+ params = { :item => items[0], :items => items }.merge(params)
167
+ ::Nanoc3::Filters::Sass.new(params)
168
+ end
169
+
170
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/helper'
4
+
5
+ class Nanoc3::Filters::SassTest < MiniTest::Unit::TestCase
6
+
7
+ include Nanoc3::TestHelpers
8
+
9
+ def test_filter
10
+ if_have 'sass' do
11
+ # Get filter
12
+ filter = ::Nanoc3::Filters::Sass.new({ :foo => 'bar' })
13
+
14
+ # Run filter
15
+ result = filter.run(".foo #bar\n color: #f00")
16
+ assert_match(/.foo\s+#bar\s*\{\s*color:\s+(red|#f00);?\s*\}/, result)
17
+ end
18
+ end
19
+
20
+ def test_filter_with_params
21
+ if_have 'sass' do
22
+ # Create filter
23
+ filter = ::Nanoc3::Filters::Sass.new({ :foo => 'bar' })
24
+
25
+ # Check with compact
26
+ result = filter.run(".foo #bar\n color: #f00", :style => 'compact')
27
+ assert_match(/^\.foo #bar[\s\n]*\{[\s\n]*color:\s*(red|#f00);?[\s\n]*\}/m, result)
28
+
29
+ # Check with compressed
30
+ result = filter.run(".foo #bar\n color: #f00", :style => 'compressed')
31
+ assert_match(/^\.foo #bar[\s\n]*\{[\s\n]*color:\s*(red|#f00);?[\s\n]*\}/m, result)
32
+ end
33
+ end
34
+
35
+ def test_filter_error
36
+ if_have 'sass' do
37
+ # Create filter
38
+ filter = ::Nanoc3::Filters::Sass.new({ :foo => 'bar' })
39
+
40
+ # Run filter
41
+ raised = false
42
+ begin
43
+ filter.run('$*#&!@($')
44
+ rescue Sass::SyntaxError => e
45
+ assert_match ':1', e.backtrace[0]
46
+ raised = true
47
+ end
48
+ assert raised
49
+ end
50
+ end
51
+
52
+ def test_filter_can_import_external_files
53
+ if_have 'sass' do
54
+ # Create filter
55
+ filter = ::Nanoc3::Filters::Sass.new(:items => [])
56
+
57
+ # Create sample file
58
+ File.open('moo.sass', 'w') { |io| io.write "body\n color: red" }
59
+
60
+ # Run filter
61
+ filter.run('@import moo')
62
+ end
63
+ end
64
+
65
+ def test_filter_can_import_relative_files
66
+ if_have 'sass' do
67
+ # Create filter
68
+ filter = ::Nanoc3::Filters::Sass.new(:items => [])
69
+
70
+ # Create sample file
71
+ File.open('moo.sass', 'w') { |io| io.write %Q{@import subdir/relative} }
72
+ FileUtils.mkdir_p("subdir")
73
+ File.open('subdir/relative.sass', 'w') { |io| io.write "body\n color: red" }
74
+
75
+ # Run filter
76
+ filter.run('@import moo')
77
+ end
78
+ end
79
+
80
+ def test_filter_will_skip_items_without_filename
81
+ if_have 'sass' do
82
+ # Create filter
83
+ filter = ::Nanoc3::Filters::Sass.new(:items => [ Nanoc3::Item.new('blah', {}, '/blah/') ])
84
+
85
+ # Create sample file
86
+ File.open('moo.sass', 'w') { |io| io.write "body\n color: red" }
87
+
88
+ # Run filter
89
+ filter.run('@import moo')
90
+ end
91
+ end
92
+
93
+ def test_css_imports_work
94
+ if_have 'sass' do
95
+ # Create filter
96
+ filter = ::Nanoc3::Filters::Sass.new(:items => [ Nanoc3::Item.new('blah', {}, '/blah/') ])
97
+
98
+ # Run filter
99
+ filter.run('@import moo.css')
100
+ end
101
+ end
102
+
103
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rubygems'
5
+
6
+ gemspec = File.expand_path("nanoc3.gemspec", Dir.pwd)
7
+ Gem::Specification.load(gemspec).dependencies.each do |dep|
8
+ gem dep.name, *dep.requirement.as_list
9
+ end
10
+ rescue LoadError => e
11
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+
3
+ # Set up gem loading (necessary for cri dependency)
4
+ require File.dirname(__FILE__) + '/gem_loader.rb'
5
+
6
+ # Load unit testing stuff
7
+ begin
8
+ require 'minitest/unit'
9
+ require 'minitest/spec'
10
+ require 'minitest/mock'
11
+ require 'mocha'
12
+ rescue => e
13
+ $stderr.puts "To run the nanoc unit tests, you need minitest and mocha."
14
+ raise e
15
+ end
16
+
17
+ # Load nanoc
18
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
19
+ require 'nanoc3'
20
+ require 'nanoc3/cli'
21
+ require 'nanoc3/tasks'
22
+
23
+ # Load miscellaneous requirements
24
+ require 'stringio'
25
+
26
+ module Nanoc3::TestHelpers
27
+
28
+ def if_have(*libs)
29
+ libs.each do |lib|
30
+ begin
31
+ require lib
32
+ rescue LoadError
33
+ skip "requiring #{lib} failed"
34
+ return
35
+ end
36
+ end
37
+
38
+ yield
39
+ end
40
+
41
+ def if_implemented
42
+ begin
43
+ yield
44
+ rescue NotImplementedError, NameError
45
+ skip $!
46
+ return
47
+ end
48
+ end
49
+
50
+ def setup
51
+ # Clean up
52
+ GC.start
53
+
54
+ # Go quiet
55
+ unless ENV['QUIET'] == 'false'
56
+ $stdout = StringIO.new
57
+ $stderr = StringIO.new
58
+ end
59
+
60
+ # Enter tmp
61
+ FileUtils.mkdir_p('tmp')
62
+ FileUtils.cd('tmp')
63
+ end
64
+
65
+ def teardown
66
+ # Exit tmp
67
+ FileUtils.cd('..')
68
+ FileUtils.rm_rf('tmp')
69
+
70
+ # Go unquiet
71
+ unless ENV['QUIET'] == 'false'
72
+ $stdout = STDOUT
73
+ $stderr = STDERR
74
+ end
75
+ end
76
+
77
+ # Adapted from http://github.com/lsegal/yard-examples/tree/master/doctest
78
+ def assert_examples_correct(object)
79
+ P(object).tags(:example).each do |example|
80
+ begin
81
+ # Get input and output
82
+ parts = example.text.split(/# ?=>/).map { |s| s.strip }
83
+ code = parts[0].strip
84
+ expected_out_raw = parts[1].strip
85
+
86
+ # Evaluate
87
+ expected_out = eval(parts[1])
88
+ actual_out = instance_eval("#{code}")
89
+ rescue Exception => e
90
+ e.message << " (code: #{code}; expected output: #{expected_out_raw})"
91
+ raise e
92
+ end
93
+
94
+ assert_equal expected_out, actual_out,
95
+ "Incorrect example: #{code}"
96
+ end
97
+ end
98
+
99
+ end