glinda 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,466 @@
1
+ require 'spec_helper'
2
+ require 'date'
3
+
4
+ URL = "http://toto.oz"
5
+ AUTHOR = "Glinda"
6
+
7
+ include Capybara::DSL
8
+ include Capybara::RSpecMatchers
9
+
10
+ describe Glinda do
11
+ before(:each) do
12
+ @config = Glinda::Config.new(:markdown => true, :author => AUTHOR, :url => URL)
13
+ @glinda = Rack::MockRequest.new(Glinda::Server.new(@config))
14
+ Glinda::Paths[:articles] = "spec/articles"
15
+ Glinda::Paths[:pages] = "spec/templates"
16
+ Glinda::Paths[:templates] = "spec/templates"
17
+ end
18
+
19
+ describe "GET /" do
20
+ let(:response) { @glinda.get('/') }
21
+
22
+ it "should return status code 200" do
23
+ response.status.should == 200
24
+ end
25
+
26
+ it "should not have an empty body" do
27
+ response.body.should_not be_empty
28
+ end
29
+
30
+ it "should set the content-type" do
31
+ response.content_type.should == "text/html"
32
+ end
33
+
34
+ it "should include 2 articles" do
35
+ visit '/'
36
+ page.all('#articles li').count.should == 3
37
+ end
38
+
39
+ it "should include an archive" do
40
+ visit '/'
41
+ page.all('#archives li').count.should == 2
42
+ end
43
+
44
+ context "with no articles" do
45
+ let(:response) { Rack::MockRequest.new(Glinda::Server.new(@config.merge(:ext => 'oxo'))).get('/') }
46
+
47
+ it "should return status code 200" do
48
+ response.status.should == 200
49
+ end
50
+
51
+ it "should not have an empty body" do
52
+ response.body.should_not be_empty
53
+ end
54
+ end
55
+
56
+ context "with a user-defined to_html" do
57
+ let(:response) do
58
+ @config[:to_html] = lambda do |path, page, binding|
59
+ ERB.new(File.read("#{path}/#{page}.rhtml")).result(binding)
60
+ end
61
+ @glinda.get('/')
62
+ end
63
+
64
+ it "should return status code 200" do
65
+ response.status.should == 200
66
+ end
67
+
68
+ it "should not have an empty body" do
69
+ response.body.should_not be_empty
70
+ end
71
+
72
+ it "should set the content-type" do
73
+ response.content_type.should == "text/html"
74
+ end
75
+
76
+ it "should include 2 articles" do
77
+ visit '/'
78
+ page.all('#articles li').count.should == 3
79
+ end
80
+
81
+ it "should include an archive" do
82
+ visit '/'
83
+ page.all('#archives li').count.should == 2
84
+ end
85
+
86
+ it "should set Etag header" do
87
+ response.headers.should include "ETag"
88
+ end
89
+
90
+ it "should set the ETag value" do
91
+ response.headers["ETag"].should_not be_empty
92
+ end
93
+ end
94
+ end
95
+
96
+ context "GET /about" do
97
+ let(:response) { @glinda.get('/about') }
98
+ it "should return status code 200" do
99
+ response.status.should == 200
100
+ end
101
+
102
+ it "should not have an empty body" do
103
+ response.body.should_not be_empty
104
+ end
105
+
106
+ it "should set the content-type" do
107
+ response.content_type.should == "text/html"
108
+ end
109
+
110
+ it "should have access to @articles" do
111
+ visit '/about'
112
+ page.find('#count').should have_content '5'
113
+ end
114
+ end
115
+
116
+ context "GET a single article" do
117
+ let(:response) { @glinda.get("/1900/05/17/the-wonderful-wizard-of-oz") }
118
+
119
+ it "should return status code 200" do
120
+ response.status.should == 200
121
+ end
122
+
123
+ it "should include the article" do
124
+ visit '/1900/05/17/the-wonderful-wizard-of-oz'
125
+ page.should have_content "Once upon a time"
126
+ end
127
+
128
+
129
+ it "should set the content-type" do
130
+ response.content_type.should == "text/html"
131
+ end
132
+ end
133
+
134
+ context "GET to the archive" do
135
+ context "through a year" do
136
+ before(:each) { visit '/2009' }
137
+
138
+ it "should return a 200" do
139
+ page.status_code.should == 200
140
+ end
141
+
142
+ it "should return the articles for that year" do
143
+ page.all('li.entry').count.should == 3
144
+ end
145
+ end
146
+
147
+ context "through a year & month" do
148
+ before(:each) { visit '/2009/12' }
149
+
150
+ it "should return a 200" do
151
+ page.status_code.should == 200
152
+ end
153
+
154
+ it "should return the articles for that year" do
155
+ page.all('li.entry').count.should == 2
156
+ end
157
+
158
+ it "should include the year and month" do
159
+ page.find("h1").should have_content("2009/12")
160
+ end
161
+ end
162
+ end
163
+
164
+ context "GET to an unknown route with a custom error" do
165
+ before(:each) do
166
+ @config[:error] = lambda {|code| "error: #{code}" }
167
+ Capybara.app = Glinda::Server.new(@config)
168
+ visit('/unknown')
169
+ end
170
+
171
+ it "should return a 404" do
172
+ page.status_code.should == 404
173
+ end
174
+
175
+ it "should display the custom error" do
176
+ page.should have_content "error: 404"
177
+ end
178
+ end
179
+
180
+ context "Request is invalid" do
181
+ let(:response) { @glinda.delete('/invalid') }
182
+ it "should return status code 400" do
183
+ response.status.should == 400
184
+ end
185
+ end
186
+
187
+ context "GET /index.xml (atom feed)" do
188
+ before(:each) do
189
+ visit '/index.xml'
190
+ end
191
+
192
+ it "should set content-type" do
193
+ page.response_headers['content-type'].should == 'application/xml'
194
+ end
195
+
196
+ it "be valid xml" do
197
+ page.all('feed entry').count.should > 0
198
+ end
199
+
200
+ it "should show a summary" do
201
+ page.should have_css 'feed entry summary'
202
+ end
203
+ end
204
+
205
+ context "GET /index?param=testparam (get parameter)" do
206
+ before :each do
207
+ visit 'index?param=testparam'
208
+ end
209
+
210
+ it "should return status code 200" do
211
+ page.status_code.should == 200
212
+ end
213
+
214
+ it "set content-type properly" do
215
+ page.response_headers['content-type'].should == 'text/html'
216
+ end
217
+
218
+ it "contain the env variable" do
219
+ page.should have_content 'env passed: true'
220
+ end
221
+
222
+ it "be able to access the HTTP GET Param" do
223
+ page.should have_content 'request method type: GET'
224
+ end
225
+
226
+ it "should access the http paramiter name value pair" do
227
+ page.should have_content 'request name value pair: param=testparam'
228
+ end
229
+ end
230
+
231
+
232
+
233
+ context "GET to a repo name" do
234
+ before(:all) do
235
+ class Glinda::Repo
236
+ def readme() "#{self[:name]}'s README" end
237
+ end
238
+ end
239
+
240
+ context "when the repo is in the :repos array" do
241
+ before(:each) do
242
+ @config[:github] = {:user => "cloudhead", :repos => ['the-repo']}
243
+ Capybara.app = Glinda::Server.new(@config)
244
+ visit '/the-repo'
245
+ end
246
+ it "should return the repo README" do
247
+ page.should have_content "the-repo's README"
248
+ end
249
+ end
250
+
251
+ context "when the repo is not in the :repos array" do
252
+ before :each do
253
+ @config[:github] = {:user => "cloudhead", :repos => []}
254
+ Capybara.app = Glinda::Server.new(@config)
255
+ visit '/the-repo'
256
+ end
257
+
258
+ it "should return a 404" do
259
+ page.status_code.should == 404
260
+ end
261
+ end
262
+ end
263
+
264
+ context "creating an article" do
265
+ before(:each) do
266
+ @config[:markdown] = true
267
+ @config[:date] = lambda {|t| "the time is #{t.strftime("%Y/%m/%d %H:%M")}" }
268
+ @config[:summary] = {:length => 50}
269
+ Capybara.app = Glinda::Server.new(@config)
270
+ end
271
+
272
+ context "with the bare essentials" do
273
+
274
+ let(:article) { Glinda::Article.new({ title: "Glinda & The Wizard of Oz.", body: "#Chapter I\nHello, *stranger*." }, @config) }
275
+
276
+ it { article.title.should == "Glinda & The Wizard of Oz." }
277
+ it "should parse the body as markdown" do
278
+ article.body.should == "<h1>Chapter I</h1>\n\n<p>Hello, <em>stranger</em>.</p>\n"
279
+ end
280
+
281
+ it "should create the appropriate slug" do
282
+ article.slug.should == "glinda-and-the-wizard-of-oz"
283
+ end
284
+
285
+ it "should set the date" do
286
+ article.date.should == "the time is #{Date.today.strftime("%Y/%m/%d %H:%M")}"
287
+ end
288
+
289
+ it "should create a summary" do
290
+ article.summary.should == article.body
291
+ end
292
+
293
+ it "should have an author" do
294
+ article.author.should == AUTHOR
295
+ end
296
+
297
+ it "should have a path" do
298
+ article.path.should == Date.today.strftime("/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
299
+ end
300
+
301
+ it "should have a URL" do
302
+ article.url.should == Date.today.strftime("#{URL}/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
303
+ end
304
+ end
305
+
306
+ context "with a user-defined summary" do
307
+ let(:article) do
308
+ Glinda::Article.new({
309
+ :title => "Glinda & The Wizard of Oz.",
310
+ :body => "Well,\nhello ~\n, *stranger*."
311
+ }, @config.merge(:markdown => false, :summary => {:max => 150, :delim => /~\n/}))
312
+ end
313
+
314
+ it "should split the article at the delmiter" do
315
+ article.summary.should == "Well,\nhello"
316
+ end
317
+
318
+ it "should not have the delimiter in the body" do
319
+ article.body. !~ /~/
320
+ end
321
+ end
322
+
323
+ context "with everything specified" do
324
+ let(:article) do
325
+ Glinda::Article.new({
326
+ :title => "The Wizard of Oz",
327
+ :body => ("a little bit of text." * 5) + "\n" + "filler" * 10,
328
+ :date => "19/10/1976",
329
+ :slug => "wizard-of-oz",
330
+ :author => "toetoe"
331
+ }, @config)
332
+ end
333
+
334
+ it "should parse the date" do
335
+ article[:date].month.should == 10
336
+ article[:date].year.should == 1976
337
+ end
338
+
339
+ it "should use the slug" do
340
+ article.slug.should == "wizard-of-oz"
341
+ end
342
+
343
+ it "should use the author" do
344
+ article.author.should == "toetoe"
345
+ end
346
+
347
+
348
+ context "and long first paragraph" do
349
+ it "should create a valid summary" do
350
+ article.summary.should == "<p>" + ("a little bit of text." * 5).chop + "&hellip;</p>\n"
351
+ end
352
+ end
353
+
354
+ context "and a short first paragraph" do
355
+ let(:article) do
356
+ @config[:markdown] = false
357
+ Glinda::Article.new({:body => "there ain't such thing as a free lunch\n" * 10}, @config)
358
+ end
359
+
360
+ it "should create a valid summary" do
361
+ article.summary.size.should <= 80
362
+ article.summary.size.should >= 75
363
+ end
364
+ end
365
+ end
366
+
367
+ context "in a subdirectory" do
368
+ context "with implicit leading forward slash" do
369
+ let(:article) do
370
+ conf = Glinda::Config.new({})
371
+ conf.set(:prefix, "blog")
372
+ Glinda::Article.new({
373
+ :title => "Glinda & The Wizard of Oz.",
374
+ :body => "#Chapter I\nhello, *stranger*."
375
+ }, conf)
376
+ end
377
+
378
+ it "should be in the directory" do
379
+ article.path.should == Date.today.strftime("/blog/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
380
+ end
381
+
382
+ end
383
+
384
+ context "with explicit leading forward slash" do
385
+ let(:article) do
386
+ conf = Glinda::Config.new({})
387
+ conf.set(:prefix, "/blog")
388
+ Glinda::Article.new({
389
+ :title => "Glinda & The Wizard of Oz.",
390
+ :body => "#Chapter I\nhello, *stranger*."
391
+ }, conf)
392
+ end
393
+
394
+ it "should be in the directory do" do
395
+ article.path.should == Date.today.strftime("/blog/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
396
+ end
397
+ end
398
+
399
+ context "with explicit trailing forward slash" do
400
+ let(:article) do
401
+ conf = Glinda::Config.new({})
402
+ conf.set(:prefix, "blog/")
403
+ Glinda::Article.new({
404
+ :title => "Glinda & The Wizard of Oz.",
405
+ :body => "#Chapter I\nhello, *stranger*."
406
+ }, conf)
407
+ end
408
+
409
+ it "should be in the directory do" do
410
+ article.path.should == Date.today.strftime("/blog/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
411
+ end
412
+ end
413
+ end
414
+ end
415
+
416
+ context "using Config#set with a hash" do
417
+ let(:conf) do
418
+ conf = Glinda::Config.new({})
419
+ conf.set(:summary, {:delim => /%/})
420
+ conf
421
+ end
422
+
423
+ it "should set summary delim to /%/" do
424
+ conf[:summary][:delim].source.should == "%"
425
+ end
426
+
427
+ it "should leave :max intact" do
428
+ conf[:summary][:max].should == 150
429
+ end
430
+ end
431
+
432
+ context "using Config#set with a block" do
433
+ let(:conf) do
434
+ conf = Glinda::Config.new({})
435
+ conf.set(:to_html) {|path, p, _| path + p }
436
+ conf
437
+ end
438
+
439
+ subject { conf[:to_html] }
440
+
441
+ it { should respond_to :call }
442
+ end
443
+
444
+ context "testing individual configuration parameters" do
445
+ context "generate error pages" do
446
+ let(:conf) do
447
+ conf = Glinda::Config.new({})
448
+ conf.set(:error) {|code| "error code #{code}" }
449
+ conf
450
+ end
451
+
452
+ it "should create an error" do
453
+ conf[:error].call(400).should == "error code 400"
454
+ end
455
+
456
+ end
457
+ end
458
+
459
+ context "extensions to the core Ruby library" do
460
+ it "should respond to iso8601" do
461
+ Date.today.should respond_to :iso8601
462
+ end
463
+ end
464
+ end
465
+
466
+
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'capybara'
4
+ require 'capybara/rspec'
5
+
6
+ $:.unshift File.dirname(__FILE__)
7
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
8
+
9
+ require 'glinda'
10
+
11
+ Capybara.app = Glinda::Server.new
12
+
@@ -0,0 +1 @@
1
+ <span id="count"><%= @articles.length %></span>
@@ -0,0 +1,5 @@
1
+ <h1><%= @path %></h1>
2
+ <% for entry in archives %>
3
+ <li class="entry"><%= entry.title %></li>
4
+ <% end %>
5
+
@@ -0,0 +1,4 @@
1
+ <h2><%= title %></h2>
2
+ <span><%= date %></h2>
3
+ <p><%= body %></p>
4
+
@@ -0,0 +1,21 @@
1
+ xml.instruct!
2
+ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
3
+ xml.title @config[:title]
4
+ xml.id @config[:url]
5
+ xml.updated articles.first[:date].iso8601 unless articles.empty?
6
+ xml.author { xml.name @config[:author] }
7
+
8
+ articles.each do |article|
9
+ xml.entry do
10
+ xml.title article.title
11
+ xml.link "rel" => "alternate", "href" => article.url
12
+ xml.id article.url
13
+ xml.published article[:date].iso8601
14
+ xml.updated article[:date].iso8601
15
+ xml.author { xml.name @config[:author] }
16
+ xml.summary article.summary, "type" => "html"
17
+ xml.content article.body, "type" => "html"
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,21 @@
1
+ xml.instruct!
2
+ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
3
+ xml.title @config[:title]
4
+ xml.id @config[:url]
5
+ xml.updated articles.first[:date].iso8601 unless articles.empty?
6
+ xml.author { xml.name @config[:author] }
7
+
8
+ articles.each do |article|
9
+ xml.entry do
10
+ xml.title article.title
11
+ xml.link "rel" => "alternate", "href" => article.url
12
+ xml.id article.url
13
+ xml.published article[:date].iso8601
14
+ xml.updated article[:date].iso8601
15
+ xml.author { xml.name @config[:author] }
16
+ xml.summary article.summary, "type" => "html"
17
+ xml.content article.body, "type" => "html"
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,13 @@
1
+ <ul id="articles">
2
+ <% for article in articles[0...3] %>
3
+ <li><%= article %></li>
4
+ <% end %>
5
+ </ul>
6
+ <div id="archives">
7
+ <%= archives[3...5] %>
8
+ </div>
9
+ <!-- testing env variable passing -->
10
+ <p>env passed: <%= env != nil %><br/></p>
11
+ <!-- testing get/post parameter passing -->
12
+ <p>request method type: <%= env['REQUEST_METHOD'] %><br/></p>
13
+ <p>request name value pair: <%= env['QUERY_STRING'] %><br/></p>
@@ -0,0 +1,4 @@
1
+ <html>
2
+ <%= yield %>
3
+ </html>
4
+
@@ -0,0 +1 @@
1
+ <%= readme %>