aerial 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.gitignore +1 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.md +74 -0
  4. data/Rakefile +96 -0
  5. data/VERSION +1 -0
  6. data/config/config.yml +19 -0
  7. data/config/deploy.rb +50 -0
  8. data/lib/aerial.rb +100 -0
  9. data/lib/aerial/article.rb +241 -0
  10. data/lib/aerial/base.rb +172 -0
  11. data/lib/aerial/comment.rb +160 -0
  12. data/lib/aerial/config.rb +41 -0
  13. data/lib/aerial/content.rb +74 -0
  14. data/lib/aerial/vendor/akismetor.rb +52 -0
  15. data/lib/aerial/vendor/cache.rb +139 -0
  16. data/lib/features/article.feature +10 -0
  17. data/lib/features/home.feature +16 -0
  18. data/lib/features/step_definitions/article_steps.rb +4 -0
  19. data/lib/features/step_definitions/home_steps.rb +8 -0
  20. data/lib/features/support/env.rb +38 -0
  21. data/lib/features/support/pages/article.rb +9 -0
  22. data/lib/features/support/pages/homepage.rb +9 -0
  23. data/lib/spec/aerial_spec.rb +203 -0
  24. data/lib/spec/article_spec.rb +338 -0
  25. data/lib/spec/base_spec.rb +65 -0
  26. data/lib/spec/comment_spec.rb +216 -0
  27. data/lib/spec/config_spec.rb +25 -0
  28. data/lib/spec/fixtures/articles/sample-article/sample-article.article +6 -0
  29. data/lib/spec/fixtures/articles/test-article-one/test-article.article +7 -0
  30. data/lib/spec/fixtures/articles/test-article-three/test-article.article +7 -0
  31. data/lib/spec/fixtures/articles/test-article-two/comment-missing-fields.comment +8 -0
  32. data/lib/spec/fixtures/articles/test-article-two/test-article.article +7 -0
  33. data/lib/spec/fixtures/articles/test-article-two/test-comment.comment +10 -0
  34. data/lib/spec/fixtures/config.yml +35 -0
  35. data/lib/spec/fixtures/public/javascripts/application.js +109 -0
  36. data/lib/spec/fixtures/public/javascripts/jquery-1.3.1.min.js +19 -0
  37. data/lib/spec/fixtures/public/javascripts/jquery.template.js +255 -0
  38. data/lib/spec/fixtures/views/article.haml +19 -0
  39. data/lib/spec/fixtures/views/articles.haml +2 -0
  40. data/lib/spec/fixtures/views/comment.haml +8 -0
  41. data/lib/spec/fixtures/views/home.haml +2 -0
  42. data/lib/spec/fixtures/views/layout.haml +22 -0
  43. data/lib/spec/fixtures/views/post.haml +27 -0
  44. data/lib/spec/fixtures/views/rss.haml +15 -0
  45. data/lib/spec/fixtures/views/sidebar.haml +21 -0
  46. data/lib/spec/fixtures/views/style.sass +163 -0
  47. data/lib/spec/spec_helper.rb +117 -0
  48. metadata +101 -0
@@ -0,0 +1,338 @@
1
+ require "#{File.dirname(__FILE__)}/spec_helper"
2
+
3
+ describe 'article' do
4
+
5
+ before do
6
+ setup_repo
7
+ end
8
+
9
+ describe "when finding an article" do
10
+
11
+ before(:each) do
12
+ @article = Article.with_name("test-article-one")
13
+ end
14
+
15
+ it "should find an article with .article extenstion " do
16
+ @article.should_not be_nil
17
+ end
18
+
19
+ it "should assign the article's author" do
20
+ @article.author.should == "Matt Sears"
21
+ end
22
+
23
+ it "should assign the article title" do
24
+ @article.title.should == "This is the first article"
25
+ end
26
+
27
+ it "should assign the file name of the article" do
28
+ @article.file_name.should == "test-article.article"
29
+ end
30
+
31
+ it "should assing a list of tags" do
32
+ @article.tags.should == ["ruby", "sinatra", "git"]
33
+ end
34
+
35
+ it "should assign the article date" do
36
+ @article.id.should_not be_empty
37
+ end
38
+
39
+ it "should assign the article a publication date" do
40
+ @article.published_at.should == DateTime.new(y=2009,m=1,d=31)
41
+ end
42
+
43
+ it "should assign the article a body attribute" do
44
+ @article.body.should == "Lorem ipsum dolor sit amet, adipisicing **elit**, sed do eiusmod
45
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
46
+ end
47
+
48
+ it "should convert body text to body html" do
49
+ @article.body_html.should have_tag('//strong').with_text('elit')
50
+ end
51
+
52
+ it "should calculate a permalink based on the directory the article is saved in" do
53
+ @article.permalink.should == "/2009/1/31/test-article"
54
+ end
55
+
56
+ end
57
+
58
+ describe "when opening the article with the blob id" do
59
+
60
+ before(:each) do
61
+ article_id = Article.with_name("test-article-one").id
62
+ @article = Article.open(article_id, :fast => true)
63
+ end
64
+
65
+ it "should return a valid article object" do
66
+ @article.should_not be_nil
67
+ end
68
+
69
+ it "should be an instance of an Article object" do
70
+ @article.should be_instance_of(Article)
71
+ end
72
+
73
+ end
74
+
75
+ describe "when finding the first article by the id" do
76
+
77
+ before(:each) do
78
+ article_id = Article.with_name("test-article-one").id
79
+ @article = Article.find(article_id)
80
+ end
81
+
82
+ it "should return a valid article object with the id" do
83
+ @article.should_not be_nil
84
+ end
85
+
86
+ it "should assign a file name to the article " do
87
+ @article.file_name.should == "test-article.article"
88
+ end
89
+
90
+ it "should assign a tree id of the article" do
91
+ @article.archive_name.should == "test-article-one"
92
+ end
93
+
94
+ it "should find the file path of where the article is stored" do
95
+ @article.expand_path.should == "#{@repo_path}/articles/test-article-one/test-article.article"
96
+ end
97
+
98
+ it "should be an instance of an Article object" do
99
+ @article.should be_instance_of(Article)
100
+ end
101
+
102
+ end
103
+
104
+ describe "when articles don't exitst" do
105
+
106
+ it "should raise error when article could not be found" do
107
+ lambda {
108
+ @article = Article.find("doesn't exists")
109
+ }.should raise_error(RuntimeError)
110
+ end
111
+
112
+
113
+ it "should raise error when article blob doesn't exist" do
114
+ lambda {
115
+ @article = Article.open("doesn't exists")
116
+ }.should raise_error(RuntimeError)
117
+ end
118
+
119
+ end
120
+
121
+ describe "when finding the second article by the id" do
122
+
123
+ before(:each) do
124
+ article_id = Article.with_name("test-article-two").id
125
+ @article = Article.find(article_id)
126
+ end
127
+
128
+ it "should find the second article and not the first" do
129
+ @article.should_not be_nil
130
+ end
131
+
132
+ it "should assign a tree id of the article" do
133
+ @article.archive_name.should == "test-article-two"
134
+ end
135
+
136
+ end
137
+
138
+ describe "when finding an article by permalink" do
139
+
140
+ before(:each) do
141
+ @article = Article.find_by_permalink("/2009/1/31/test-article")
142
+ end
143
+
144
+ it "should return an article with a valid permalink" do
145
+ @article.should be_instance_of(Article)
146
+ end
147
+
148
+ it "should return nil if article can't be found" do
149
+ Article.find_by_permalink("does-not-exist").should == false
150
+ end
151
+
152
+ after(:each) do
153
+ @article = nil
154
+ end
155
+ end
156
+
157
+ describe "finding all articles" do
158
+
159
+ before do
160
+ @articles = Article.find_all
161
+ end
162
+
163
+ it "should return an array of article objects" do
164
+ @articles.should be_instance_of(Array)
165
+ end
166
+
167
+ it "should contain more than one Article" do
168
+ @articles.size.should == 4
169
+ end
170
+
171
+ it "should contain a comments array even if empty" do
172
+ @articles.each do |article|
173
+ article.comments.should_not be_nil
174
+ end
175
+ end
176
+
177
+ after do
178
+ @articles = nil
179
+ end
180
+
181
+ end
182
+
183
+ describe "finding all articles with a specific tag" do
184
+
185
+ before do
186
+ @tag = "sinatra"
187
+ @articles = Article.with_tag(@tag)
188
+ end
189
+
190
+ it "should return an array of articles" do
191
+ @articles.should be_instance_of(Array)
192
+ end
193
+
194
+ it "should contain more than one Article" do
195
+ @articles.size.should == 3
196
+ end
197
+
198
+ it "should include articles with a specific task" do
199
+ @articles.each { |article| article.tags.should include(@tag)}
200
+ end
201
+
202
+ end
203
+
204
+ describe "finding all articles by publication date" do
205
+
206
+ before do
207
+ @articles = Article.with_date(2009, 12)
208
+ end
209
+
210
+ it "should return an array of articles" do
211
+ @articles.should be_instance_of(Array)
212
+ end
213
+
214
+ it "should return 2 articles" do
215
+ @articles.size.should == 2
216
+ end
217
+
218
+ it "should return 2 articles published in the 12th month" do
219
+ @articles.each { |a| a.published_at.month.should == 12}
220
+ end
221
+
222
+ it "should return 2 articles published in the year 2009" do
223
+ @articles.each { |a| a.published_at.year.should == 2009}
224
+ end
225
+
226
+ it "should find articles with dates in string format" do
227
+ articles = Article.with_date("2009", "01")
228
+ articles.should_not be_empty
229
+ end
230
+
231
+ end
232
+
233
+
234
+ describe "calling Article.archives" do
235
+
236
+ before do
237
+ @archives = Article.archives
238
+ end
239
+
240
+ it "should return an array" do
241
+ @archives.should be_instance_of(Hash)
242
+ end
243
+
244
+ it "should return a list of publication dates" do
245
+ @archives.should == {["2009/01", "January 2009"]=>2, ["2009/12", "December 2009"]=>2}
246
+ end
247
+
248
+ end
249
+
250
+ describe "calling Article.exists?" do
251
+
252
+ it "should determine if an article exists" do
253
+ Article.exists?("test-article-two").should == true
254
+ end
255
+
256
+ it "should return false when article doesn't exist" do
257
+ Article.exists?("ghost-article").should == false
258
+ end
259
+
260
+ end
261
+
262
+ describe "calling Article.comments" do
263
+
264
+ before(:each) do
265
+ @article_two = Article.with_name("test-article-two")
266
+ end
267
+
268
+ it "should not be nil" do
269
+ @article_two.should_not be_nil
270
+ end
271
+
272
+ it "should have comments attached to the article" do
273
+ @article_two.comments.size.should == 2
274
+ end
275
+
276
+ it "should have a valid comment" do
277
+ @article_two.comments.first.author.should == "Anonymous Coward"
278
+ end
279
+
280
+ end
281
+
282
+ describe "calling Article.recent" do
283
+
284
+ before(:each) do
285
+ @articles = Article.recent(:limit => 2)
286
+ end
287
+
288
+ it "should return an array of arricles" do
289
+ @articles.should_not be_nil
290
+ end
291
+
292
+ it "should limit the number of articles" do
293
+ @articles.size.should == 2
294
+ end
295
+
296
+ end
297
+
298
+ describe "calling Article.tags" do
299
+
300
+ before(:each) do
301
+ @tags = Article.tags
302
+ end
303
+
304
+ it "should return an array even if empty" do
305
+ @tags.should be_instance_of(Array)
306
+ end
307
+
308
+ it "should return a list of tag strings" do
309
+ @tags.size.should == 3
310
+ end
311
+
312
+ end
313
+
314
+ describe "adding comments to an Article" do
315
+
316
+ before(:each) do
317
+ @article = Article.with_name("test-article-one")
318
+ @comment = Comment.new(:author => "Matt Sears",
319
+ :body => "Comment content",
320
+ :email => "matt@mattsears.com",
321
+ :published => Date.today,
322
+ :homepage => "http://example.com")
323
+ end
324
+
325
+ it "should add a new comment with no errors" do
326
+ @article.add_comment(@comment).should_not be_nil
327
+ end
328
+
329
+ it "should increase the size of the Article's comments" do
330
+ @article.comments.should be_empty
331
+ @article.add_comment(@comment)
332
+ retrieve_article = Article.with_name("test-article-one")
333
+ retrieve_article.comments.size.should == 1
334
+ end
335
+
336
+ end
337
+
338
+ end
@@ -0,0 +1,65 @@
1
+ require "#{File.dirname(__FILE__)}/spec_helper"
2
+
3
+ describe 'article' do
4
+
5
+ before do
6
+ setup_repo
7
+ end
8
+
9
+ it "should provide an interface to the logger when debug mode is on" do
10
+ Aerial.debug = true
11
+ Aerial.log("testing the logger!").should == true
12
+ end
13
+
14
+ it "should not log messages when debug mode is off" do
15
+ Aerial.debug = false
16
+ Aerial.log("this should not log").should be_nil
17
+ end
18
+
19
+ describe Aerial::Helper do
20
+
21
+ it "should return 'Never' for invalid dates" do
22
+ humanized_date("Invalid Date").should == "Never"
23
+ end
24
+
25
+ it "should properly format a valid date" do
26
+ humanized_date(DateTime.now).should_not == "Never"
27
+ end
28
+
29
+ it "should create a list of hyperlinks for each tag" do
30
+ tags = ["ruby", "sinatra"]
31
+ link_to_tags(tags).should == "<a href='/tags/ruby' rel='ruby'>ruby</a>, <a href='/tags/sinatra' rel='sinatra'>sinatra</a>"
32
+ end
33
+
34
+ it "should default the current path to 'index' for the root of the application" do
35
+ request.stub!(:env).and_return('/')
36
+ path.should == "index"
37
+ end
38
+
39
+ end
40
+
41
+ describe Aerial::Git do
42
+
43
+ before do
44
+ Aerial.repo.stub!(:add).and_return(true)
45
+ Aerial.repo.stub!(:commit_index).and_return(true)
46
+ Aerial.repo.status.untracked.stub!(:empty?).and_return(false)
47
+ end
48
+
49
+ it "should commit changes" do
50
+ Aerial::Git.commit("/path/to/change", "message").should == true
51
+ end
52
+
53
+ it "should commit all changes" do
54
+ Aerial::Git.commit_all.should == true
55
+ end
56
+
57
+ it "should add the remote repository " do
58
+ Aerial::Git.push
59
+ end
60
+
61
+ end
62
+
63
+
64
+
65
+ end
@@ -0,0 +1,216 @@
1
+ require "#{File.dirname(__FILE__)}/spec_helper"
2
+
3
+ describe 'comment' do
4
+
5
+ before do
6
+ setup_repo
7
+ @article_one = Article.with_name("test-article-one")
8
+ @article_two = Article.with_name("test-article-two")
9
+ @comment = Comment.new
10
+ Akismetor.stub!(:spam?).and_return(false)
11
+ end
12
+
13
+ it "should ensure url is clean" do
14
+ ['http://example.com', 'example.com'].each do |url_str|
15
+ comment = Comment.new(:homepage => url_str)
16
+ comment.homepage.should == 'http://example.com'
17
+ end
18
+ end
19
+
20
+ describe "when finding comments" do
21
+
22
+ before(:each) do
23
+ @article = Article.with_name("test-article-two")
24
+ @comments = @article.comments
25
+ @comment = @comments.find{ |c| c.file_name == "test-comment.comment"}
26
+ end
27
+
28
+ it "should be an instance of an array" do
29
+ @comments.should be_instance_of(Array)
30
+ end
31
+
32
+ it "should find all comments with an article id" do
33
+ @comments.should_not be_empty
34
+ end
35
+
36
+ it "should assign an id to the comment" do
37
+ @comment.object_id.should_not be_nil
38
+ end
39
+
40
+ it "should assign a file name of the comment" do
41
+ @comment.file_name.should == "test-comment.comment"
42
+ end
43
+
44
+ it "should assign an author of the comment" do
45
+ @comment.author.should == "Anonymous Coward"
46
+ end
47
+
48
+ it "should assign an email of the commenter" do
49
+ @comment.email.should == "anonymous@coward.com"
50
+ end
51
+
52
+ it "should assign an IP address of the commenter" do
53
+ @comment.user_ip.should == "127.0.0.1"
54
+ end
55
+
56
+ it "should assign a homepage of the commenter" do
57
+ @comment.homepage.should == "http://littlelines.com"
58
+ end
59
+
60
+ it "should assign a referrer of the commenter" do
61
+ @comment.referrer.should == "http://mattsears.com"
62
+ end
63
+
64
+ it "should assign a user-agent of the commenter" do
65
+ @comment.user_agent.should == "CERN-LineMode/2.15 libwww/2.17b3"
66
+ end
67
+
68
+ it "should format the string version of the comment" do
69
+ comment = Comment.new(:author => "author", :email => "test@test.com")
70
+ comment.to_s.should == "Author: author \nPublished: #{comment.published_at} \nEmail: test@test.com \n"
71
+ end
72
+
73
+ describe "without a homepage field" do
74
+
75
+ before do
76
+ @comment = @comments.find{ |c| c.file_name == "comment-missing-fields.comment"}
77
+ end
78
+
79
+ it "should leave the homepage field blank" do
80
+ @comment.homepage.should be_blank
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
87
+ describe "when creating new comments" do
88
+
89
+ before do
90
+ @article = Article.with_name("test-article-two")
91
+ @comment = Comment.create(@article.archive_name,
92
+ :author => "Matt Sears",
93
+ :body => "Comment content",
94
+ :email => "matt@mattsears.com",
95
+ :published => Date.today,
96
+ :homepage => "http://example.com")
97
+ end
98
+
99
+ it "should return a valid Comment object" do
100
+ @comment.should be_instance_of(Comment)
101
+ @comment.valid?.should == true
102
+ end
103
+
104
+ it "should return invalid if Comment doesn not contain all require fields" do
105
+ @comment.email = ""
106
+ @comment.valid?.should == false
107
+ end
108
+
109
+ it "should not create the comment if it is not valid" do
110
+ @comment = Comment.create(@article, :author => "Matt").should == false
111
+ end
112
+
113
+ it "should create a new instance" do
114
+ @comment.should_not be_nil
115
+ @comment.author.should == "Matt Sears"
116
+ @comment.body.should == "Comment content"
117
+ end
118
+
119
+ it "should generate a file name based on the author and current time" do
120
+ @comment.name.should =~ /matt@mattsears.com.comment/
121
+ end
122
+
123
+ it "should calculate the absoulte path to the comment file" do
124
+ @comment.expand_file.should == File.join(@repo_path,
125
+ Aerial.config.articles.dir,
126
+ @article.archive_name,
127
+ @comment.name)
128
+ end
129
+
130
+ it "should calculate the absoulte path of the comment's archive directory" do
131
+ @comment.archive_path.should == File.join(@repo_path,
132
+ Aerial.config.articles.dir,
133
+ @article.archive_name)
134
+ end
135
+
136
+ it "should write a new comment to disk" do
137
+ File.exists?(@comment.expand_file).should == true
138
+ end
139
+
140
+ after(:each) do
141
+ @comment = nil
142
+ end
143
+
144
+ end
145
+
146
+ describe "when saving Comments" do
147
+
148
+ before do
149
+ @article = Article.with_name("test-article-two")
150
+ @comment = Comment.new(:author => "Matt Sears",
151
+ :body => "Comment content",
152
+ :email => "matt@mattsears.com",
153
+ :published => Date.today,
154
+ :homepage => "http://example.com")
155
+ end
156
+
157
+ it "should NOT have written a new comment to disk yet" do
158
+ @comment.expand_file.should be_nil
159
+ end
160
+
161
+ it "should save a comment to a valid archive path" do
162
+ @comment.save(@article.archive_name).should == @comment
163
+ end
164
+
165
+ it "should write the comment to the article's archive path" do
166
+ @comment.save(@article.archive_name).should_not be_nil
167
+ @comment.expand_file.should == File.join(@repo_path,
168
+ Aerial.config.articles.dir,
169
+ @article.archive_name,
170
+ @comment.name)
171
+ end
172
+
173
+ it "should assign a publication date of the comment" do
174
+ @comment.save(@article.archive_name).should == @comment
175
+ @comment.published_at.should be_instance_of(DateTime)
176
+ end
177
+
178
+ it "should write a new comment to disk" do
179
+ @comment.save(@article.archive_name)
180
+ File.exists?(@comment.expand_file).should == true
181
+ end
182
+
183
+ after do
184
+ File.delete @comment.expand_file if @comment.expand_file
185
+ end
186
+
187
+ end
188
+
189
+ describe "when handling spam" do
190
+
191
+ before do
192
+ @article = Article.with_name("test-article-two")
193
+ @comment = Comment.new(:author => "Spammer",
194
+ :body => "Something spammy",
195
+ :email => "spam@example.com",
196
+ :published => Date.today,
197
+ :homepage => "http://spam.com")
198
+ Akismetor.stub!(:spam?).and_return(true)
199
+ @comment.save(@article.archive_name)
200
+ end
201
+
202
+ it "should flag the comment as suspicious" do
203
+ @comment.suspicious?.should == true
204
+ end
205
+
206
+ it "should flag the comment is spam if Akismetor says so" do
207
+ @comment.expand_file.should =~ /.spam/
208
+ end
209
+
210
+ after do
211
+ File.delete @comment.expand_file if @comment.expand_file
212
+ end
213
+
214
+ end
215
+
216
+ end