aerial 0.0.0

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 (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