monad 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. data/CONTRIBUTING.md +68 -0
  2. data/Gemfile +2 -0
  3. data/LICENSE +21 -0
  4. data/README.md +88 -0
  5. data/Rakefile +136 -0
  6. data/bin/monad +102 -0
  7. data/cucumber.yml +3 -0
  8. data/features/create_sites.feature +112 -0
  9. data/features/data_sources.feature +76 -0
  10. data/features/drafts.feature +25 -0
  11. data/features/embed_filters.feature +60 -0
  12. data/features/markdown.feature +30 -0
  13. data/features/pagination.feature +54 -0
  14. data/features/permalinks.feature +65 -0
  15. data/features/post_data.feature +214 -0
  16. data/features/site_configuration.feature +206 -0
  17. data/features/site_data.feature +101 -0
  18. data/features/step_definitions/monad_steps.rb +175 -0
  19. data/features/support/env.rb +25 -0
  20. data/lib/monad.rb +90 -0
  21. data/lib/monad/command.rb +27 -0
  22. data/lib/monad/commands/build.rb +64 -0
  23. data/lib/monad/commands/doctor.rb +29 -0
  24. data/lib/monad/commands/new.rb +50 -0
  25. data/lib/monad/commands/serve.rb +33 -0
  26. data/lib/monad/configuration.rb +183 -0
  27. data/lib/monad/converter.rb +48 -0
  28. data/lib/monad/converters/identity.rb +21 -0
  29. data/lib/monad/converters/markdown.rb +43 -0
  30. data/lib/monad/converters/markdown/kramdown_parser.rb +44 -0
  31. data/lib/monad/converters/markdown/maruku_parser.rb +47 -0
  32. data/lib/monad/converters/markdown/rdiscount_parser.rb +35 -0
  33. data/lib/monad/converters/markdown/redcarpet_parser.rb +70 -0
  34. data/lib/monad/converters/textile.rb +50 -0
  35. data/lib/monad/convertible.rb +152 -0
  36. data/lib/monad/core_ext.rb +68 -0
  37. data/lib/monad/deprecator.rb +32 -0
  38. data/lib/monad/draft.rb +35 -0
  39. data/lib/monad/drivers/json_driver.rb +39 -0
  40. data/lib/monad/drivers/yaml_driver.rb +23 -0
  41. data/lib/monad/errors.rb +4 -0
  42. data/lib/monad/filters.rb +154 -0
  43. data/lib/monad/generator.rb +4 -0
  44. data/lib/monad/generators/pagination.rb +143 -0
  45. data/lib/monad/layout.rb +42 -0
  46. data/lib/monad/logger.rb +54 -0
  47. data/lib/monad/mime.types +85 -0
  48. data/lib/monad/page.rb +163 -0
  49. data/lib/monad/plugin.rb +75 -0
  50. data/lib/monad/post.rb +377 -0
  51. data/lib/monad/site.rb +455 -0
  52. data/lib/monad/static_file.rb +70 -0
  53. data/lib/monad/tags/gist.rb +30 -0
  54. data/lib/monad/tags/highlight.rb +85 -0
  55. data/lib/monad/tags/include.rb +37 -0
  56. data/lib/monad/tags/post_url.rb +61 -0
  57. data/lib/site_template/.gitignore +1 -0
  58. data/lib/site_template/_config.yml +2 -0
  59. data/lib/site_template/_layouts/default.html +46 -0
  60. data/lib/site_template/_layouts/post.html +9 -0
  61. data/lib/site_template/_posts/0000-00-00-welcome-to-monad.markdown.erb +24 -0
  62. data/lib/site_template/css/main.css +165 -0
  63. data/lib/site_template/css/syntax.css +60 -0
  64. data/lib/site_template/index.html +13 -0
  65. data/monad.gemspec +197 -0
  66. data/script/bootstrap +2 -0
  67. data/test/fixtures/broken_front_matter1.erb +5 -0
  68. data/test/fixtures/broken_front_matter2.erb +4 -0
  69. data/test/fixtures/broken_front_matter3.erb +7 -0
  70. data/test/fixtures/exploit_front_matter.erb +4 -0
  71. data/test/fixtures/front_matter.erb +4 -0
  72. data/test/fixtures/members.yaml +7 -0
  73. data/test/helper.rb +62 -0
  74. data/test/source/.htaccess +8 -0
  75. data/test/source/_includes/sig.markdown +3 -0
  76. data/test/source/_layouts/default.html +27 -0
  77. data/test/source/_layouts/simple.html +1 -0
  78. data/test/source/_plugins/dummy.rb +8 -0
  79. data/test/source/_posts/2008-02-02-not-published.textile +8 -0
  80. data/test/source/_posts/2008-02-02-published.textile +8 -0
  81. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  82. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  83. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  84. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  85. data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
  86. data/test/source/_posts/2009-01-27-categories.textile +7 -0
  87. data/test/source/_posts/2009-01-27-category.textile +7 -0
  88. data/test/source/_posts/2009-01-27-empty-categories.textile +7 -0
  89. data/test/source/_posts/2009-01-27-empty-category.textile +7 -0
  90. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  91. data/test/source/_posts/2009-05-18-empty-tag.textile +6 -0
  92. data/test/source/_posts/2009-05-18-empty-tags.textile +6 -0
  93. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  94. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  95. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  96. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  97. data/test/source/_posts/2010-01-08-triple-dash.markdown +5 -0
  98. data/test/source/_posts/2010-01-09-date-override.textile +7 -0
  99. data/test/source/_posts/2010-01-09-time-override.textile +7 -0
  100. data/test/source/_posts/2010-01-09-timezone-override.textile +7 -0
  101. data/test/source/_posts/2010-01-16-override-data.textile +4 -0
  102. data/test/source/_posts/2011-04-12-md-extension.md +7 -0
  103. data/test/source/_posts/2011-04-12-text-extension.text +0 -0
  104. data/test/source/_posts/2013-01-02-post-excerpt.markdown +14 -0
  105. data/test/source/_posts/2013-01-12-nil-layout.textile +6 -0
  106. data/test/source/_posts/2013-01-12-no-layout.textile +5 -0
  107. data/test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep +0 -0
  108. data/test/source/_posts/2013-04-11-custom-excerpt.markdown +10 -0
  109. data/test/source/_posts/2013-05-10-number-category.textile +7 -0
  110. data/test/source/_posts/es/2008-11-21-nested.textile +8 -0
  111. data/test/source/about.html +6 -0
  112. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  113. data/test/source/contacts.html +5 -0
  114. data/test/source/contacts/bar.html +5 -0
  115. data/test/source/contacts/index.html +5 -0
  116. data/test/source/css/screen.css +76 -0
  117. data/test/source/deal.with.dots.html +7 -0
  118. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  119. data/test/source/index.html +22 -0
  120. data/test/source/sitemap.xml +32 -0
  121. data/test/source/symlink-test/symlinked-file +22 -0
  122. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  123. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  124. data/test/suite.rb +11 -0
  125. data/test/test_command.rb +39 -0
  126. data/test/test_configuration.rb +137 -0
  127. data/test/test_convertible.rb +51 -0
  128. data/test/test_core_ext.rb +88 -0
  129. data/test/test_filters.rb +102 -0
  130. data/test/test_generated_site.rb +83 -0
  131. data/test/test_json_driver.rb +63 -0
  132. data/test/test_kramdown.rb +35 -0
  133. data/test/test_new_command.rb +104 -0
  134. data/test/test_page.rb +193 -0
  135. data/test/test_pager.rb +115 -0
  136. data/test/test_post.rb +573 -0
  137. data/test/test_rdiscount.rb +22 -0
  138. data/test/test_redcarpet.rb +61 -0
  139. data/test/test_redcloth.rb +86 -0
  140. data/test/test_site.rb +374 -0
  141. data/test/test_tags.rb +310 -0
  142. data/test/test_yaml_driver.rb +35 -0
  143. metadata +554 -0
@@ -0,0 +1,115 @@
1
+ require 'helper'
2
+
3
+ class TestPager < Test::Unit::TestCase
4
+
5
+ should "calculate number of pages" do
6
+ assert_equal(0, Pager.calculate_pages([], '2'))
7
+ assert_equal(1, Pager.calculate_pages([1], '2'))
8
+ assert_equal(1, Pager.calculate_pages([1,2], '2'))
9
+ assert_equal(2, Pager.calculate_pages([1,2,3], '2'))
10
+ assert_equal(2, Pager.calculate_pages([1,2,3,4], '2'))
11
+ assert_equal(3, Pager.calculate_pages([1,2,3,4,5], '2'))
12
+ end
13
+
14
+ context "pagination disabled" do
15
+ setup do
16
+ stub(Monad).configuration do
17
+ Monad::Configuration::DEFAULTS.merge({
18
+ 'source' => source_dir,
19
+ 'destination' => dest_dir
20
+ })
21
+ end
22
+ @config = Monad.configuration
23
+ end
24
+
25
+ should "report that pagination is disabled" do
26
+ page = OpenStruct.new({ :name => 'index.html', :dir => '/' })
27
+ assert !Pager.pagination_enabled?(@config, page)
28
+ end
29
+
30
+ end
31
+
32
+ context "pagination enabled for 2" do
33
+ setup do
34
+ stub(Monad).configuration do
35
+ Monad::Configuration::DEFAULTS.merge({
36
+ 'source' => source_dir,
37
+ 'destination' => dest_dir,
38
+ 'paginate' => 2
39
+ })
40
+ end
41
+
42
+ @config = Monad.configuration
43
+ @site = Site.new(@config)
44
+ @site.process
45
+ @posts = @site.posts
46
+ end
47
+
48
+ should "report that pagination is enabled" do
49
+ page = OpenStruct.new({ :name => 'index.html', :dir => '/' })
50
+ assert Pager.pagination_enabled?(@config, page)
51
+ end
52
+
53
+ context "with 4 posts" do
54
+ setup do
55
+ @posts = @site.posts[1..4] # limit to 4
56
+ end
57
+
58
+ should "create first pager" do
59
+ pager = Pager.new(@config, 1, @posts)
60
+ assert_equal(2, pager.posts.size)
61
+ assert_equal(2, pager.total_pages)
62
+ assert_nil(pager.previous_page)
63
+ assert_equal(2, pager.next_page)
64
+ end
65
+
66
+ should "create second pager" do
67
+ pager = Pager.new(@config, 2, @posts)
68
+ assert_equal(2, pager.posts.size)
69
+ assert_equal(2, pager.total_pages)
70
+ assert_equal(1, pager.previous_page)
71
+ assert_nil(pager.next_page)
72
+ end
73
+
74
+ should "not create third pager" do
75
+ assert_raise(RuntimeError) { Pager.new(@config, 3, @posts) }
76
+ end
77
+
78
+ end
79
+
80
+ context "with 5 posts" do
81
+ setup do
82
+ @posts = @site.posts[1..5] # limit to 5
83
+ end
84
+
85
+ should "create first pager" do
86
+ pager = Pager.new(@config, 1, @posts)
87
+ assert_equal(2, pager.posts.size)
88
+ assert_equal(3, pager.total_pages)
89
+ assert_nil(pager.previous_page)
90
+ assert_equal(2, pager.next_page)
91
+ end
92
+
93
+ should "create second pager" do
94
+ pager = Pager.new(@config, 2, @posts)
95
+ assert_equal(2, pager.posts.size)
96
+ assert_equal(3, pager.total_pages)
97
+ assert_equal(1, pager.previous_page)
98
+ assert_equal(3, pager.next_page)
99
+ end
100
+
101
+ should "create third pager" do
102
+ pager = Pager.new(@config, 3, @posts)
103
+ assert_equal(1, pager.posts.size)
104
+ assert_equal(3, pager.total_pages)
105
+ assert_equal(2, pager.previous_page)
106
+ assert_nil(pager.next_page)
107
+ end
108
+
109
+ should "not create fourth pager" do
110
+ assert_raise(RuntimeError) { Pager.new(@config, 4, @posts) }
111
+ end
112
+
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,573 @@
1
+ require 'helper'
2
+
3
+ class TestPost < Test::Unit::TestCase
4
+ def setup_post(file)
5
+ Post.new(@site, source_dir, '', file)
6
+ end
7
+
8
+ def do_render(post)
9
+ layouts = { "default" => Layout.new(@site, source_dir('_layouts'), "simple.html")}
10
+ post.render(layouts, {"site" => {"posts" => []}})
11
+ end
12
+
13
+ context "A Post" do
14
+ setup do
15
+ clear_dest
16
+ stub(Monad).configuration { Monad::Configuration::DEFAULTS }
17
+ @site = Site.new(Monad.configuration)
18
+ end
19
+
20
+ should "ensure valid posts are valid" do
21
+ assert Post.valid?("2008-09-09-foo-bar.textile")
22
+ assert Post.valid?("foo/bar/2008-09-09-foo-bar.textile")
23
+
24
+ assert !Post.valid?("lol2008-09-09-foo-bar.textile")
25
+ assert !Post.valid?("blah")
26
+ end
27
+
28
+ context "processing posts" do
29
+ setup do
30
+ @post = Post.allocate
31
+ @post.site = @site
32
+
33
+ @real_file = "2008-10-18-foo-bar.textile"
34
+ @fake_file = "2008-09-09-foo-bar.textile"
35
+ @source = source_dir('_posts')
36
+ end
37
+
38
+ should "keep date, title, and markup type" do
39
+ @post.categories = []
40
+ @post.process(@fake_file)
41
+
42
+ assert_equal Time.parse("2008-09-09"), @post.date
43
+ assert_equal "foo-bar", @post.slug
44
+ assert_equal ".textile", @post.ext
45
+ assert_equal "/2008/09/09", @post.dir
46
+ assert_equal "/2008/09/09/foo-bar", @post.id
47
+ end
48
+
49
+ should "create url based on date and title" do
50
+ @post.categories = []
51
+ @post.process(@fake_file)
52
+ assert_equal "/2008/09/09/foo-bar.html", @post.url
53
+ end
54
+
55
+ should "raise a good error on invalid post date" do
56
+ assert_raise Monad::FatalException do
57
+ @post.process("2009-27-03-foo-bar.textile")
58
+ end
59
+ end
60
+
61
+ should "CGI escape urls" do
62
+ @post.categories = []
63
+ @post.process("2009-03-12-hash-#1.markdown")
64
+ assert_equal "/2009/03/12/hash-%231.html", @post.url
65
+ assert_equal "/2009/03/12/hash-#1", @post.id
66
+ end
67
+
68
+ should "respect permalink in yaml front matter" do
69
+ file = "2008-12-03-permalinked-post.textile"
70
+ @post.process(file)
71
+ @post.read_yaml(@source, file)
72
+
73
+ assert_equal "my_category/permalinked-post", @post.permalink
74
+ assert_equal "/my_category", @post.dir
75
+ assert_equal "/my_category/permalinked-post", @post.url
76
+ end
77
+
78
+ context "with CRLF linebreaks" do
79
+ setup do
80
+ @real_file = "2009-05-24-yaml-linebreak.markdown"
81
+ @source = source_dir('win/_posts')
82
+ end
83
+ should "read yaml front-matter" do
84
+ @post.read_yaml(@source, @real_file)
85
+
86
+ assert_equal({"title" => "Test title", "layout" => "post", "tag" => "Ruby"}, @post.data)
87
+ assert_equal "This is the content", @post.content
88
+ end
89
+ end
90
+
91
+ context "with embedded triple dash" do
92
+ setup do
93
+ @real_file = "2010-01-08-triple-dash.markdown"
94
+ end
95
+ should "consume the embedded dashes" do
96
+ @post.read_yaml(@source, @real_file)
97
+
98
+ assert_equal({"title" => "Foo --- Bar"}, @post.data)
99
+ assert_equal "Triple the fun!", @post.content
100
+ end
101
+ end
102
+
103
+ context "with site wide permalink" do
104
+ setup do
105
+ @post.categories = []
106
+ end
107
+
108
+ context "with unspecified (date) style" do
109
+ setup do
110
+ @post.process(@fake_file)
111
+ end
112
+
113
+ should "process the url correctly" do
114
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
115
+ assert_equal "/2008/09/09/foo-bar.html", @post.url
116
+ end
117
+ end
118
+
119
+ context "with unspecified (date) style and a category" do
120
+ setup do
121
+ @post.categories << "beer"
122
+ @post.process(@fake_file)
123
+ end
124
+
125
+ should "process the url correctly" do
126
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
127
+ assert_equal "/beer/2008/09/09/foo-bar.html", @post.url
128
+ end
129
+ end
130
+
131
+ context "with unspecified (date) style and a numeric category" do
132
+ setup do
133
+ @post.categories << 2013
134
+ @post.process(@fake_file)
135
+ end
136
+
137
+ should "process the url correctly" do
138
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
139
+ assert_equal "/2013/2008/09/09/foo-bar.html", @post.url
140
+ end
141
+ end
142
+
143
+ context "with specified layout of nil" do
144
+ setup do
145
+ file = '2013-01-12-nil-layout.textile'
146
+ @post = setup_post(file)
147
+ @post.process(file)
148
+ end
149
+
150
+ should "layout of nil is respected" do
151
+ assert_equal "nil", @post.data["layout"]
152
+ end
153
+ end
154
+
155
+ context "with unspecified (date) style and categories" do
156
+ setup do
157
+ @post.categories << "food"
158
+ @post.categories << "beer"
159
+ @post.process(@fake_file)
160
+ end
161
+
162
+ should "process the url correctly" do
163
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
164
+ assert_equal "/food/beer/2008/09/09/foo-bar.html", @post.url
165
+ end
166
+ end
167
+
168
+ context "with space (categories)" do
169
+ setup do
170
+ @post.categories << "French cuisine"
171
+ @post.categories << "Belgian beer"
172
+ @post.process(@fake_file)
173
+ end
174
+
175
+ should "process the url correctly" do
176
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
177
+ assert_equal "/French%20cuisine/Belgian%20beer/2008/09/09/foo-bar.html", @post.url
178
+ end
179
+ end
180
+
181
+ context "with none style" do
182
+ setup do
183
+ @post.site.permalink_style = :none
184
+ @post.process(@fake_file)
185
+ end
186
+
187
+ should "process the url correctly" do
188
+ assert_equal "/:categories/:title.html", @post.template
189
+ assert_equal "/foo-bar.html", @post.url
190
+ end
191
+ end
192
+
193
+ context "with pretty style" do
194
+ setup do
195
+ @post.site.permalink_style = :pretty
196
+ @post.process(@fake_file)
197
+ end
198
+
199
+ should "process the url correctly" do
200
+ assert_equal "/:categories/:year/:month/:day/:title/", @post.template
201
+ assert_equal "/2008/09/09/foo-bar/", @post.url
202
+ end
203
+ end
204
+
205
+ context "with ordinal style" do
206
+ setup do
207
+ @post.site.permalink_style = :ordinal
208
+ @post.process(@fake_file)
209
+ end
210
+
211
+ should "process the url correctly" do
212
+ assert_equal "/:categories/:year/:y_day/:title.html", @post.template
213
+ assert_equal "/2008/253/foo-bar.html", @post.url
214
+ end
215
+ end
216
+
217
+ context "with custom date permalink" do
218
+ setup do
219
+ @post.site.permalink_style = '/:categories/:year/:i_month/:i_day/:title/'
220
+ @post.process(@fake_file)
221
+ end
222
+
223
+ should "process the url correctly" do
224
+ assert_equal "/2008/9/9/foo-bar/", @post.url
225
+ end
226
+ end
227
+
228
+ context "with custom abbreviated month date permalink" do
229
+ setup do
230
+ @post.site.permalink_style = '/:categories/:year/:short_month/:day/:title/'
231
+ @post.process(@fake_file)
232
+ end
233
+
234
+ should "process the url correctly" do
235
+ assert_equal "/2008/Sep/09/foo-bar/", @post.url
236
+ end
237
+ end
238
+
239
+ context "with prefix style and no extension" do
240
+ setup do
241
+ @post.site.permalink_style = "/prefix/:title"
242
+ @post.process(@fake_file)
243
+ end
244
+
245
+ should "process the url correctly" do
246
+ assert_equal "/prefix/:title", @post.template
247
+ assert_equal "/prefix/foo-bar", @post.url
248
+ end
249
+ end
250
+ end
251
+
252
+ should "read yaml front-matter" do
253
+ @post.read_yaml(@source, @real_file)
254
+
255
+ assert_equal({"title" => "Foo Bar", "layout" => "default"}, @post.data)
256
+ assert_equal "h1. {{ page.title }}\n\nBest *post* ever", @post.content
257
+ end
258
+
259
+ should "transform textile" do
260
+ @post.process(@real_file)
261
+ @post.read_yaml(@source, @real_file)
262
+ @post.transform
263
+
264
+ assert_equal "<h1>{{ page.title }}</h1>\n<p>Best <strong>post</strong> ever</p>", @post.content
265
+ end
266
+
267
+ context "#excerpt" do
268
+ setup do
269
+ file = "2013-01-02-post-excerpt.markdown"
270
+ @post.process(file)
271
+ @post.read_yaml(@source, file)
272
+ @post.transform
273
+ end
274
+
275
+ should "return first paragraph by default" do
276
+ assert @post.excerpt.include?("First paragraph"), "contains first paragraph"
277
+ assert !@post.excerpt.include?("Second paragraph"), "does not contains second paragraph"
278
+ assert !@post.excerpt.include?("Third paragraph"), "does not contains third paragraph"
279
+ end
280
+
281
+ should "correctly resolve link references" do
282
+ assert @post.excerpt.include?("www.monadrb.com"), "contains referenced link URL"
283
+ end
284
+
285
+ should "return rendered HTML" do
286
+ assert_equal "<p>First paragraph with <a href='http://www.monadrb.com/'>link ref</a>.</p>",
287
+ @post.excerpt
288
+ end
289
+
290
+ context "with excerpt_separator setting" do
291
+ setup do
292
+ file = "2013-01-02-post-excerpt.markdown"
293
+
294
+ @post.site.config['excerpt_separator'] = "\n---\n"
295
+
296
+ @post.process(file)
297
+ @post.read_yaml(@source, file)
298
+ @post.transform
299
+ end
300
+
301
+ should "respect given separator" do
302
+ assert @post.excerpt.include?("First paragraph"), "contains first paragraph"
303
+ assert @post.excerpt.include?("Second paragraph"), "contains second paragraph"
304
+ assert !@post.excerpt.include?("Third paragraph"), "does not contains third paragraph"
305
+ end
306
+
307
+ should "replace separator with new-lines" do
308
+ assert !@post.excerpt.include?("---"), "does not contains separator"
309
+ end
310
+ end
311
+
312
+ context "with custom excerpt" do
313
+ setup do
314
+ file = "2013-04-11-custom-excerpt.markdown"
315
+ @post = setup_post(file)
316
+ do_render(@post)
317
+ end
318
+
319
+ should "use custom excerpt" do
320
+ assert_equal("I can set a custom excerpt", @post.excerpt)
321
+ end
322
+
323
+ should "expose custom excerpt to liquid" do
324
+ assert @post.content.include?("I can use the excerpt: <quote>I can set a custom excerpt</quote>"), "Exposes incorrect excerpt to liquid."
325
+ end
326
+
327
+ end
328
+
329
+ end
330
+ end
331
+
332
+ context "when in a site" do
333
+ setup do
334
+ clear_dest
335
+ stub(Monad).configuration { Monad::Configuration::DEFAULTS }
336
+ @site = Site.new(Monad.configuration)
337
+ @site.posts = [setup_post('2008-02-02-published.textile'),
338
+ setup_post('2009-01-27-categories.textile')]
339
+ end
340
+
341
+ should "have next post" do
342
+ assert_equal(@site.posts.last, @site.posts.first.next)
343
+ end
344
+
345
+ should "have previous post" do
346
+ assert_equal(@site.posts.first, @site.posts.last.previous)
347
+ end
348
+
349
+ should "not have previous post if first" do
350
+ assert_equal(nil, @site.posts.first.previous)
351
+ end
352
+
353
+ should "not have next post if last" do
354
+ assert_equal(nil, @site.posts.last.next)
355
+ end
356
+ end
357
+
358
+ context "initializing posts" do
359
+ should "publish when published yaml is no specified" do
360
+ post = setup_post("2008-02-02-published.textile")
361
+ assert_equal true, post.published
362
+ end
363
+
364
+ should "not published when published yaml is false" do
365
+ post = setup_post("2008-02-02-not-published.textile")
366
+ assert_equal false, post.published
367
+ end
368
+
369
+ should "recognize date in yaml" do
370
+ post = setup_post("2010-01-09-date-override.textile")
371
+ do_render(post)
372
+ assert_equal Time, post.date.class
373
+ assert_equal Time, post.to_liquid["date"].class
374
+ assert_equal "/2010/01/10/date-override.html", post.url
375
+ assert_equal "<p>Post with a front matter date</p>\n<p>10 Jan 2010</p>", post.output
376
+ end
377
+
378
+ should "recognize time in yaml" do
379
+ post = setup_post("2010-01-09-time-override.textile")
380
+ do_render(post)
381
+ assert_equal Time, post.date.class
382
+ assert_equal Time, post.to_liquid["date"].class
383
+ assert_equal "/2010/01/10/time-override.html", post.url
384
+ assert_equal "<p>Post with a front matter time</p>\n<p>10 Jan 2010</p>", post.output
385
+ end
386
+
387
+ should "recognize time with timezone in yaml" do
388
+ post = setup_post("2010-01-09-timezone-override.textile")
389
+ do_render(post)
390
+ assert_equal Time, post.date.class
391
+ assert_equal Time, post.to_liquid["date"].class
392
+ assert_equal "/2010/01/10/timezone-override.html", post.url
393
+ assert_equal "<p>Post with a front matter time with timezone</p>\n<p>10 Jan 2010</p>", post.output
394
+ end
395
+
396
+ should "to_liquid prioritizes post attributes over data" do
397
+ post = setup_post("2010-01-16-override-data.textile")
398
+ assert_equal Array, post.tags.class
399
+ assert_equal Array, post.to_liquid["tags"].class
400
+ assert_equal Time, post.date.class
401
+ assert_equal Time, post.to_liquid["date"].class
402
+ end
403
+
404
+ should "recognize category in yaml" do
405
+ post = setup_post("2009-01-27-category.textile")
406
+ assert post.categories.include?('foo')
407
+ end
408
+
409
+ should "recognize several categories in yaml" do
410
+ post = setup_post("2009-01-27-categories.textile")
411
+ assert post.categories.include?('foo')
412
+ assert post.categories.include?('bar')
413
+ assert post.categories.include?('baz')
414
+ end
415
+
416
+ should "recognize empty category in yaml" do
417
+ post = setup_post("2009-01-27-empty-category.textile")
418
+ assert_equal [], post.categories
419
+ end
420
+
421
+ should "recognize empty categories in yaml" do
422
+ post = setup_post("2009-01-27-empty-categories.textile")
423
+ assert_equal [], post.categories
424
+ end
425
+
426
+ should "recognize number category in yaml" do
427
+ post = setup_post("2013-05-10-number-category.textile")
428
+ assert post.categories.include?('2013')
429
+ assert !post.categories.include?(2013)
430
+ end
431
+
432
+ should "recognize tag in yaml" do
433
+ post = setup_post("2009-05-18-tag.textile")
434
+ assert post.tags.include?('code')
435
+ end
436
+
437
+ should "recognize tags in yaml" do
438
+ post = setup_post("2009-05-18-tags.textile")
439
+ assert post.tags.include?('food')
440
+ assert post.tags.include?('cooking')
441
+ assert post.tags.include?('pizza')
442
+ end
443
+
444
+ should "recognize empty tag in yaml" do
445
+ post = setup_post("2009-05-18-empty-tag.textile")
446
+ assert_equal [], post.tags
447
+ end
448
+
449
+ should "recognize empty tags in yaml" do
450
+ post = setup_post("2009-05-18-empty-tags.textile")
451
+ assert_equal [], post.tags
452
+ end
453
+
454
+ should "allow no yaml" do
455
+ post = setup_post("2009-06-22-no-yaml.textile")
456
+ assert_equal "No YAML.", post.content
457
+ end
458
+
459
+ should "allow empty yaml" do
460
+ post = setup_post("2009-06-22-empty-yaml.textile")
461
+ assert_equal "Empty YAML.", post.content
462
+ end
463
+
464
+ context "rendering" do
465
+ setup do
466
+ clear_dest
467
+ end
468
+
469
+ should "render properly" do
470
+ post = setup_post("2008-10-18-foo-bar.textile")
471
+ do_render(post)
472
+ assert_equal "<<< <h1>Foo Bar</h1>\n<p>Best <strong>post</strong> ever</p> >>>", post.output
473
+ end
474
+
475
+ should "write properly" do
476
+ post = setup_post("2008-10-18-foo-bar.textile")
477
+ do_render(post)
478
+ post.write(dest_dir)
479
+
480
+ assert File.directory?(dest_dir)
481
+ assert File.exists?(File.join(dest_dir, '2008', '10', '18', 'foo-bar.html'))
482
+ end
483
+
484
+ should "write properly without html extension" do
485
+ post = setup_post("2008-10-18-foo-bar.textile")
486
+ post.site.permalink_style = ":title"
487
+ do_render(post)
488
+ post.write(dest_dir)
489
+
490
+ assert File.directory?(dest_dir)
491
+ assert File.exists?(File.join(dest_dir, 'foo-bar', 'index.html'))
492
+ end
493
+
494
+ should "insert data" do
495
+ post = setup_post("2008-11-21-complex.textile")
496
+ do_render(post)
497
+
498
+ assert_equal "<<< <p>url: /2008/11/21/complex.html<br />\ndate: #{Time.parse("2008-11-21")}<br />\nid: /2008/11/21/complex</p> >>>", post.output
499
+ end
500
+
501
+ should "include templates" do
502
+ post = setup_post("2008-12-13-include.markdown")
503
+ post.site.source = File.join(File.dirname(__FILE__), 'source')
504
+ do_render(post)
505
+
506
+ assert_equal "<<< <hr />\n<p>Tom Preston-Werner github.com/mojombo</p>\n\n<p>This <em>is</em> cool</p> >>>", post.output
507
+ end
508
+
509
+ should "render date specified in front matter properly" do
510
+ post = setup_post("2010-01-09-date-override.textile")
511
+ do_render(post)
512
+
513
+ assert_equal "<p>Post with a front matter date</p>\n<p>10 Jan 2010</p>", post.output
514
+ end
515
+
516
+ should "render time specified in front matter properly" do
517
+ post = setup_post("2010-01-09-time-override.textile")
518
+ do_render(post)
519
+
520
+ assert_equal "<p>Post with a front matter time</p>\n<p>10 Jan 2010</p>", post.output
521
+ end
522
+
523
+ end
524
+ end
525
+
526
+ should "generate categories and topics" do
527
+ post = Post.new(@site, File.join(File.dirname(__FILE__), *%w[source]), 'foo', 'bar/2008-12-12-topical-post.textile')
528
+ assert_equal ['foo'], post.categories
529
+ end
530
+ end
531
+
532
+ context "converter file extension settings" do
533
+ setup do
534
+ stub(Monad).configuration { Monad::Configuration::DEFAULTS }
535
+ @site = Site.new(Monad.configuration)
536
+ end
537
+
538
+ should "process .md as markdown under default configuration" do
539
+ post = setup_post '2011-04-12-md-extension.md'
540
+ conv = post.converter
541
+ assert conv.kind_of? Monad::Converters::Markdown
542
+ end
543
+
544
+ should "process .text as identity under default configuration" do
545
+ post = setup_post '2011-04-12-text-extension.text'
546
+ conv = post.converter
547
+ assert conv.kind_of? Monad::Converters::Identity
548
+ end
549
+
550
+ should "process .text as markdown under alternate configuration" do
551
+ @site.config['markdown_ext'] = 'markdown,mdw,mdwn,md,text'
552
+ post = setup_post '2011-04-12-text-extension.text'
553
+ conv = post.converter
554
+ assert conv.kind_of? Monad::Converters::Markdown
555
+ end
556
+
557
+ should "process .md as markdown under alternate configuration" do
558
+ @site.config['markdown_ext'] = 'markdown,mkd,mkdn,md,text'
559
+ post = setup_post '2011-04-12-text-extension.text'
560
+ conv = post.converter
561
+ assert conv.kind_of? Monad::Converters::Markdown
562
+ end
563
+
564
+ should "process .text as textile under alternate configuration" do
565
+ @site.config['textile_ext'] = 'textile,text'
566
+ post = setup_post '2011-04-12-text-extension.text'
567
+ conv = post.converter
568
+ assert conv.kind_of? Monad::Converters::Textile
569
+ end
570
+
571
+ end
572
+
573
+ end