ruhoh 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +13 -0
- data/README.md +5 -53
- data/Rakefile +56 -0
- data/bin/ruhoh +23 -14
- data/lib/ruhoh/client/client.rb +310 -0
- data/lib/ruhoh/client/help.yml +56 -0
- data/lib/ruhoh/compiler.rb +16 -19
- data/lib/ruhoh/converters/converter.rb +30 -3
- data/lib/ruhoh/db.rb +7 -17
- data/lib/ruhoh/deployers/s3.rb +71 -0
- data/lib/ruhoh/friend.rb +71 -0
- data/lib/ruhoh/page.rb +41 -11
- data/lib/ruhoh/parsers/drafts.rb +54 -0
- data/lib/ruhoh/parsers/layouts.rb +14 -9
- data/lib/ruhoh/parsers/pages.rb +47 -35
- data/lib/ruhoh/parsers/partials.rb +14 -2
- data/lib/ruhoh/parsers/posts.rb +139 -88
- data/lib/ruhoh/parsers/routes.rb +4 -8
- data/lib/ruhoh/parsers/site.rb +2 -8
- data/lib/ruhoh/previewer.rb +48 -0
- data/lib/ruhoh/templaters/base.rb +53 -0
- data/lib/ruhoh/templaters/helpers.rb +159 -0
- data/lib/ruhoh/templaters/rmustache.rb +29 -0
- data/lib/ruhoh/utils.rb +25 -7
- data/lib/ruhoh/version.rb +1 -1
- data/lib/ruhoh/watch.rb +22 -9
- data/lib/ruhoh.rb +74 -29
- data/ruhoh.gemspec +70 -9
- data/scaffolds/blog/_config.yml +33 -0
- data/scaffolds/blog/_drafts/.gitkeep +0 -0
- data/scaffolds/blog/_posts/.gitkeep +0 -0
- data/scaffolds/blog/_site.yml +16 -0
- data/scaffolds/blog/_templates/partials/categories_list +3 -0
- data/scaffolds/blog/_templates/partials/pages_list +7 -0
- data/scaffolds/blog/_templates/partials/posts_collate +9 -0
- data/scaffolds/blog/_templates/partials/posts_list +1 -0
- data/scaffolds/blog/_templates/partials/tags_list +3 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/default.css +52 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/desert.css +34 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/sons-of-obsidian.css +117 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/sunburst.css +51 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/twitter-bootstrap.css +30 -0
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/css/bootstrap.min.css +689 -0
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/img/glyphicons-halflings.png +0 -0
- data/scaffolds/blog/_templates/themes/twitter/css/style.css +68 -0
- data/scaffolds/blog/_templates/themes/twitter/layouts/default.html +64 -0
- data/scaffolds/blog/_templates/themes/twitter/layouts/page.html +13 -0
- data/scaffolds/blog/_templates/themes/twitter/layouts/post.html +55 -0
- data/scaffolds/blog/_templates/themes/twitter/manifest.yml +11 -0
- data/scaffolds/blog/about.md +5 -0
- data/scaffolds/blog/archive.html +11 -0
- data/scaffolds/blog/categories.html +21 -0
- data/scaffolds/blog/config.ru +9 -0
- data/scaffolds/blog/index.html +13 -0
- data/scaffolds/blog/pages.html +14 -0
- data/scaffolds/blog/tags.html +21 -0
- data/scaffolds/layout.html +3 -0
- data/scaffolds/page.html +6 -0
- data/scaffolds/post.html +8 -0
- data/scaffolds/theme/css/style.css +0 -0
- data/scaffolds/theme/images/.gitkeep +0 -0
- data/scaffolds/theme/layouts/default.html +17 -0
- data/scaffolds/theme/layouts/page.html +7 -0
- data/scaffolds/theme/layouts/post.html +8 -0
- data/scaffolds/theme/partials/.gitkeep +0 -0
- data/spec/db_spec.rb +88 -0
- data/spec/page_spec.rb +200 -0
- data/spec/parsers/layouts_spec.rb +32 -0
- data/spec/parsers/pages_spec.rb +97 -0
- data/spec/parsers/posts_spec.rb +301 -0
- data/spec/parsers/routes_spec.rb +45 -0
- data/spec/parsers/site_spec.rb +32 -0
- data/spec/setup_spec.rb +72 -0
- data/spec/spec_helper.rb +23 -0
- data/system_partials/analytics/getclicky +12 -0
- data/system_partials/analytics/google +11 -0
- data/system_partials/comments/disqus +13 -0
- data/system_partials/comments/facebook +9 -0
- data/system_partials/comments/intensedebate +6 -0
- data/system_partials/comments/livefyre +6 -0
- data/system_partials/syntax/google_prettify +11 -0
- metadata +84 -23
- data/lib/ruhoh/client.rb +0 -28
- data/lib/ruhoh/preview.rb +0 -36
- data/lib/ruhoh/templaters/helper_mustache.rb +0 -109
- data/lib/ruhoh/templaters/templater.rb +0 -39
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Layouts
|
4
|
+
|
5
|
+
describe Ruhoh::Parsers::Layouts do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({'theme' => "twitter"})
|
9
|
+
Ruhoh.setup(SampleSitePath)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#generate" do
|
13
|
+
let(:layouts){
|
14
|
+
Ruhoh::Parsers::Layouts.generate
|
15
|
+
}
|
16
|
+
|
17
|
+
it 'should extract the correct layouts from a theme.' do
|
18
|
+
layouts.keys.sort.should == ['default', 'page', 'post']
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should return a hash for each layout containing the keys "data" and "content"' do
|
22
|
+
layouts.each_value { |value|
|
23
|
+
value.should have_key("data")
|
24
|
+
value.should have_key("content")
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Pages
|
4
|
+
|
5
|
+
describe Ruhoh::Parsers::Pages do
|
6
|
+
|
7
|
+
describe "#generate" do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({'theme' => "twitter"})
|
11
|
+
Ruhoh.setup(SampleSitePath)
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:pages){
|
15
|
+
Ruhoh::Parsers::Pages.generate
|
16
|
+
}
|
17
|
+
|
18
|
+
it 'should extract valid pages from source directory.' do
|
19
|
+
pages.keys.sort.should == ['about.md', 'archive.html', 'categories.html', 'index.md', 'pages.md', 'tags.html']
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should return a properly formatted hash for each page' do
|
23
|
+
pages.each_value { |value|
|
24
|
+
value.should have_key("layout")
|
25
|
+
value.should have_key("id")
|
26
|
+
value.should have_key("url")
|
27
|
+
value.should have_key("title")
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#is_valid_page?" do
|
34
|
+
|
35
|
+
context "No user specified exclusions in config." do
|
36
|
+
|
37
|
+
before(:each) do
|
38
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({'theme' => "twitter"})
|
39
|
+
Ruhoh.setup(SampleSitePath)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return true for a valid page filepath" do
|
43
|
+
filepath = 'about.md'
|
44
|
+
Ruhoh::Parsers::Pages.is_valid_page?(filepath).should == true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return false for a filepath beginning with _" do
|
48
|
+
filepath = '_blah/about.md'
|
49
|
+
Ruhoh::Parsers::Pages.is_valid_page?(filepath).should == false
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return false for a filepath beginning with ." do
|
53
|
+
filepath = '.vim'
|
54
|
+
Ruhoh::Parsers::Pages.is_valid_page?(filepath).should == false
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context "Exclude array is passed into config." do
|
60
|
+
|
61
|
+
it "should return false for a filepath matching a string in exclude array" do
|
62
|
+
filepath = 'about.md'
|
63
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({
|
64
|
+
'theme' => "twitter",
|
65
|
+
'exclude' => filepath
|
66
|
+
})
|
67
|
+
Ruhoh.setup(SampleSitePath)
|
68
|
+
|
69
|
+
Ruhoh::Parsers::Pages.is_valid_page?(filepath).should == false
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return false for a filepath matching a regular expression in exclude array" do
|
73
|
+
filepath1 = 'test/about.md'
|
74
|
+
filepath2 = 'test/yay.md'
|
75
|
+
filepath3 = 'vest/yay.md'
|
76
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({
|
77
|
+
'theme' => "twitter",
|
78
|
+
'exclude' => /^test/
|
79
|
+
})
|
80
|
+
Ruhoh.setup(SampleSitePath)
|
81
|
+
|
82
|
+
Ruhoh::Parsers::Pages.is_valid_page?(filepath1).should == false
|
83
|
+
Ruhoh::Parsers::Pages.is_valid_page?(filepath2).should == false
|
84
|
+
Ruhoh::Parsers::Pages.is_valid_page?(filepath3).should == true
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
pending "#titleize"
|
93
|
+
pending "#permalink"
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,301 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Posts
|
4
|
+
|
5
|
+
describe Ruhoh::Parsers::Posts do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({'theme' => "twitter"})
|
9
|
+
Ruhoh.setup(SampleSitePath)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#generate" do
|
13
|
+
|
14
|
+
it 'should return a valid data structures for core API' do
|
15
|
+
posts = Ruhoh::Parsers::Posts.generate
|
16
|
+
|
17
|
+
posts['dictionary'].should be_a_kind_of(Hash)
|
18
|
+
posts['chronological'].should be_a_kind_of(Array)
|
19
|
+
posts['collated'].should be_a_kind_of(Array)
|
20
|
+
posts['tags'].should be_a_kind_of(Hash)
|
21
|
+
posts['categories'].should be_a_kind_of(Hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#process" do
|
27
|
+
|
28
|
+
context "A valid post" do
|
29
|
+
pending 'should extract valid posts from source directory.' do
|
30
|
+
Ruhoh::Parsers::Posts.process
|
31
|
+
dictionary.keys.sort.should == ['_posts/2012-01-01-hello-world.md']
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should return a properly formatted hash for each post' do
|
35
|
+
dictionary = Ruhoh::Parsers::Posts.process
|
36
|
+
|
37
|
+
dictionary.each_value { |value|
|
38
|
+
value.should have_key("layout")
|
39
|
+
value.should have_key("id")
|
40
|
+
value.should have_key("url")
|
41
|
+
value.should have_key("title")
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "A post with an invalid filename format" do
|
47
|
+
it "should omit the post file and record it as invalid post" do
|
48
|
+
post_path = 'test/hello-world.md'
|
49
|
+
Ruhoh::Parsers::Posts.should_receive(:files).and_return([post_path])
|
50
|
+
Ruhoh::Utils.stub(:parse_file).and_return({"data" => {"date" => "2012-01-01"}})
|
51
|
+
|
52
|
+
dictionary = Ruhoh::Parsers::Posts.process
|
53
|
+
|
54
|
+
dictionary.should_not include(post_path)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "A post with an invalid date in the filename" do
|
59
|
+
it "should omit the post file and record it as invalid post" do
|
60
|
+
post_path = 'test/2012-51-01-hello-world.md'
|
61
|
+
Ruhoh::Parsers::Posts.should_receive(:files).and_return([post_path])
|
62
|
+
Ruhoh::Utils.stub(:parse_file).and_return({"data" => {"title" => "meep"}})
|
63
|
+
|
64
|
+
dictionary = Ruhoh::Parsers::Posts.process
|
65
|
+
|
66
|
+
dictionary.should_not include(post_path)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "A post with an invalid date in the YAML Front Matter" do
|
71
|
+
it "should omit the post file and record it as invalid post" do
|
72
|
+
post_path = 'test/2012-01-01-hello-world.md'
|
73
|
+
Ruhoh::Parsers::Posts.should_receive(:files).and_return([post_path])
|
74
|
+
Ruhoh::Utils.stub(:parse_file).and_return({"data" => {"date" => "2012-51-01"}})
|
75
|
+
|
76
|
+
dictionary = Ruhoh::Parsers::Posts.process
|
77
|
+
|
78
|
+
dictionary.should_not include(post_path)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "A post with no YAML Front Matter" do
|
83
|
+
it "should omit the post file and record it as invalid post" do
|
84
|
+
post_path = 'test/2012-01-01-hello-world.md'
|
85
|
+
Ruhoh::Parsers::Posts.should_receive(:files).and_return([post_path])
|
86
|
+
Ruhoh::Utils.stub(:parse_file).and_return({})
|
87
|
+
|
88
|
+
dictionary = Ruhoh::Parsers::Posts.process
|
89
|
+
|
90
|
+
dictionary.should_not include(post_path)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#parse_filename" do
|
97
|
+
it "should parse a post filename into corresponding metadata" do
|
98
|
+
filename = '_posts/2011-10-10-my-post-title.md'
|
99
|
+
data = Ruhoh::Parsers::Posts.parse_filename(filename)
|
100
|
+
|
101
|
+
data['path'].should == "_posts/"
|
102
|
+
data['date'].should == "2011-10-10"
|
103
|
+
data['slug'].should == "my-post-title"
|
104
|
+
data['extension'].should == ".md"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should return a blank hash if the filename format is invalid" do
|
108
|
+
filename = '_posts/my-post-title.md'
|
109
|
+
data = Ruhoh::Parsers::Posts.parse_filename(filename)
|
110
|
+
data.should == {}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#permalink" do
|
115
|
+
it "should return the default permalink style (/:categories/:year/:month/:day/:title.html)" do
|
116
|
+
post = {"date" => "2012-01-02", "title" => "My Blog Post"}
|
117
|
+
#post = {"date" => "2012-01-02", "title" => "My Blog Post", 'permalink' => :date }
|
118
|
+
permalink = Ruhoh::Parsers::Posts.permalink(post)
|
119
|
+
permalink.should == '/2012/01/02/my-blog-post.html'
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return the post specific permalink style" do
|
123
|
+
post = {"date" => "2012-01-02", "title" => "My Blog Post", 'permalink' => '/:categories/:title' }
|
124
|
+
permalink = Ruhoh::Parsers::Posts.permalink(post)
|
125
|
+
permalink.should == '/my-blog-post'
|
126
|
+
end
|
127
|
+
|
128
|
+
context "A post with one category" do
|
129
|
+
it "should include the category path in the permalink." do
|
130
|
+
post = {"date" => "2012-01-02", "title" => "My Blog Post", 'categories'=> 'ruby/lessons/beginner', 'permalink' => '/:categories/:title' }
|
131
|
+
permalink = Ruhoh::Parsers::Posts.permalink(post)
|
132
|
+
permalink.should == '/ruby/lessons/beginner/my-blog-post'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "A post belonging in two separate categories" do
|
137
|
+
it "should include the first category path in the permalink." do
|
138
|
+
post = {"date" => "2012-01-02", "title" => "My Blog Post", 'categories'=> ['web', 'ruby/lessons/beginner'], 'permalink' => '/:categories/:title' }
|
139
|
+
permalink = Ruhoh::Parsers::Posts.permalink(post)
|
140
|
+
permalink.should == '/web/my-blog-post'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "A post having special characters in the title" do
|
145
|
+
it "should escape those characters." do
|
146
|
+
post = {"date" => "2012-01-02", "title" => "=) My Blog Post!", 'permalink' => '/:title' }
|
147
|
+
permalink = Ruhoh::Parsers::Posts.permalink(post)
|
148
|
+
permalink.should_not == '/=)-my-blog-post-!'
|
149
|
+
permalink.should == '/%3D%29-my-blog-post%21'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "#titleize" do
|
155
|
+
it "should prettify a filename slug for use as a title/header" do
|
156
|
+
file_slug = 'my-post-title'
|
157
|
+
title = Ruhoh::Parsers::Posts.titleize(file_slug)
|
158
|
+
title.should == "My Post Title"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "helpers" do
|
163
|
+
let(:dictionary_stub) {
|
164
|
+
{
|
165
|
+
"a" => {"date"=>"2011-01-01", "id" => "a"},
|
166
|
+
"b" => {"date"=>"2011-02-01", "id" => "b"},
|
167
|
+
"c" => {"date"=>"2012-01-01", "id" => "c"},
|
168
|
+
"d" => {"date"=>"2010-08-01", "id" => "d"},
|
169
|
+
}
|
170
|
+
}
|
171
|
+
let(:ordered_posts_stub) {
|
172
|
+
[
|
173
|
+
{"date"=>"2012-01-01", "id" => "c"},
|
174
|
+
{"date"=>"2011-02-01", "id" => "b"},
|
175
|
+
{"date"=>"2011-01-01", "id" => "a"},
|
176
|
+
{"date"=>"2010-08-01", "id" => "d"},
|
177
|
+
]
|
178
|
+
}
|
179
|
+
let(:collated_stub) {
|
180
|
+
[
|
181
|
+
{"year"=>"2012", "months"=>[{"month"=>"January", "posts"=>["c"]}]},
|
182
|
+
{"year"=>"2011", "months"=>[{"month"=>"February", "posts"=>["b"]}, {"month"=>"January", "posts"=>["a"]}]},
|
183
|
+
{"year"=>"2010", "months"=>[{"month"=>"August", "posts"=>["d"]}]}
|
184
|
+
]
|
185
|
+
}
|
186
|
+
|
187
|
+
describe "#ordered_posts" do
|
188
|
+
it "should order a dictionary hash by date descending and return an Array" do
|
189
|
+
ordered_posts = Ruhoh::Parsers::Posts.ordered_posts(dictionary_stub)
|
190
|
+
|
191
|
+
ordered_posts.should be_a_kind_of(Array)
|
192
|
+
ordered_posts.should == ordered_posts_stub
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "#build_chronology" do
|
197
|
+
it 'should return an array of ids ordered by date descending' do
|
198
|
+
chrono = Ruhoh::Parsers::Posts.build_chronology(ordered_posts_stub)
|
199
|
+
chrono.should == ['c', 'b', 'a', 'd']
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe "#collate" do
|
204
|
+
it 'should return an array of years with nested months and nested, ordered post ids for each month.' do
|
205
|
+
collated = Ruhoh::Parsers::Posts.collate(ordered_posts_stub)
|
206
|
+
collated.should == collated_stub
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "#parse_tags" do
|
213
|
+
let(:ordered_posts_stub) {
|
214
|
+
[
|
215
|
+
{"id" => "c", "tags" => ['apple', 'orange']},
|
216
|
+
{"id" => "b", "tags" => ['apple', 'pear']},
|
217
|
+
{"id" => "a", "tags" => ['banana']},
|
218
|
+
{"id" => "d", "tags" => 'kiwi' },
|
219
|
+
]
|
220
|
+
}
|
221
|
+
let(:tags){
|
222
|
+
Ruhoh::Parsers::Posts.parse_tags(ordered_posts_stub)
|
223
|
+
}
|
224
|
+
|
225
|
+
it 'should return a dictionary of all tags on posts' do
|
226
|
+
tags.keys.sort.should == ['apple', 'banana', 'kiwi', 'orange', 'pear']
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should return a dictionary containing tag objects having name, count and posts' do
|
230
|
+
tags.each_value { |tag|
|
231
|
+
tag.should have_key("name")
|
232
|
+
tag.should have_key("count")
|
233
|
+
tag.should have_key("posts")
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should return a dictionary with tag objects having correct post id references.' do
|
238
|
+
tags['apple']['posts'].should == ['c', 'b']
|
239
|
+
tags['banana']['posts'].should == ['a']
|
240
|
+
tags['kiwi']['posts'].should == ['d']
|
241
|
+
tags['orange']['posts'].should == ['c']
|
242
|
+
tags['pear']['posts'].should == ['b']
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should return a dictionary containing correct tag counts' do
|
246
|
+
tags['apple']['count'].should == 2
|
247
|
+
tags['banana']['count'].should == 1
|
248
|
+
tags['kiwi']['count'].should == 1
|
249
|
+
tags['orange']['count'].should == 1
|
250
|
+
tags['pear']['count'].should == 1
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
describe "#parse_categories" do
|
256
|
+
let(:ordered_posts_stub) {
|
257
|
+
[
|
258
|
+
{"id" => "c", "categories" => ['web', ['ruby', 'tutorials']] },
|
259
|
+
{"id" => "b", "categories" => ['web', ['ruby']] },
|
260
|
+
{"id" => "a", "categories" => ['web', 'python'] },
|
261
|
+
{"id" => "d", "categories" => 'erlang' },
|
262
|
+
]
|
263
|
+
}
|
264
|
+
|
265
|
+
let(:categories) {
|
266
|
+
categories = Ruhoh::Parsers::Posts.parse_categories(ordered_posts_stub)
|
267
|
+
}
|
268
|
+
|
269
|
+
it 'should return a dictionary of all post categories' do
|
270
|
+
categories.keys.sort.should == ['erlang', 'python', 'ruby', 'ruby/tutorials', 'web']
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should return a dictionary containing category objects having name, count and posts' do
|
274
|
+
categories.each_value { |cat|
|
275
|
+
cat.should have_key("name")
|
276
|
+
cat.should have_key("count")
|
277
|
+
cat.should have_key("posts")
|
278
|
+
}
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'should return a dictionary with category objects having correct post id references.' do
|
282
|
+
categories['erlang']['posts'].should == ['d']
|
283
|
+
categories['python']['posts'].should == ['a']
|
284
|
+
categories['ruby']['posts'].should == ['b']
|
285
|
+
categories['ruby/tutorials']['posts'].should == ['c']
|
286
|
+
categories['web']['posts'].should == ['c','b','a']
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'should return a dictionary containing correct tag counts' do
|
290
|
+
categories['erlang']['count'].should == 1
|
291
|
+
categories['python']['count'].should == 1
|
292
|
+
categories['ruby']['count'].should == 1
|
293
|
+
categories['ruby/tutorials']['count'].should == 1
|
294
|
+
categories['web']['count'].should == 3
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Routes
|
4
|
+
|
5
|
+
describe Ruhoh::Parsers::Routes do
|
6
|
+
|
7
|
+
describe "#generate" do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({'theme' => "twitter"})
|
11
|
+
Ruhoh.setup(SampleSitePath)
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:pages){
|
15
|
+
{
|
16
|
+
"blah.md" => {'url' => '/blah.html', "id" => "blah.md"},
|
17
|
+
"yes.md" => {'url' => '/yes.html', "id" => "yes.md"},
|
18
|
+
"no.md" => {'url' => '/no.html', "id" => "no.md"},
|
19
|
+
}
|
20
|
+
}
|
21
|
+
let(:posts){
|
22
|
+
{
|
23
|
+
"dictionary" => {
|
24
|
+
"post1.md" => {'url' => '/post1.html', "id" => "post1.md"},
|
25
|
+
"post2.md" => {'url' => '/post2.html', "id" => "post2.md"},
|
26
|
+
"post3.md" => {'url' => '/post3.html', "id" => "post3.md"},
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
it 'should return a dictionary/hash with urls as keys that map to post/draft/page ids as values' do
|
32
|
+
Ruhoh::DB.should_receive(:pages).and_return(pages)
|
33
|
+
Ruhoh::DB.should_receive(:posts).and_return(posts)
|
34
|
+
|
35
|
+
routes = Ruhoh::Parsers::Routes.generate
|
36
|
+
|
37
|
+
routes.should be_a_kind_of(Hash)
|
38
|
+
routes.keys.sort.should == ['/blah.html', '/no.html', '/post1.html', '/post2.html', '/post3.html', '/yes.html']
|
39
|
+
routes.values.sort.should == ['blah.md', 'no.md', 'post1.md', 'post2.md', 'post3.md', 'yes.md']
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Site
|
4
|
+
|
5
|
+
describe Ruhoh::Parsers::Site do
|
6
|
+
|
7
|
+
describe "#generate" do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({'theme' => "twitter"})
|
11
|
+
Ruhoh.setup(SampleSitePath)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should parse the config and site yaml files' do
|
15
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).with(Ruhoh.paths.site_source, Ruhoh.files.site).and_return({})
|
16
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).with(Ruhoh.paths.site_source, Ruhoh.files.config).and_return({})
|
17
|
+
|
18
|
+
Ruhoh::Parsers::Site.generate
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should return a site hash with config set as value to key "config" ' do
|
22
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).with(Ruhoh.paths.site_source, Ruhoh.files.site).and_return({"nav" => [1,2,3]})
|
23
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).with(Ruhoh.paths.site_source, Ruhoh.files.config).and_return({"theme" => "orange"})
|
24
|
+
|
25
|
+
site = Ruhoh::Parsers::Site.generate
|
26
|
+
site.should == { "nav" => [1,2,3], "config" => {"theme" => "orange"} }
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/spec/setup_spec.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Setup
|
4
|
+
|
5
|
+
describe "Setup" do
|
6
|
+
|
7
|
+
describe "#setup" do
|
8
|
+
|
9
|
+
it 'should setup config, paths, and filters' do
|
10
|
+
Ruhoh.should_receive(:setup_config)
|
11
|
+
Ruhoh.should_receive(:setup_paths)
|
12
|
+
Ruhoh.should_receive(:setup_filters)
|
13
|
+
Ruhoh.setup
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#setup_config" do
|
19
|
+
|
20
|
+
context "Invalid _config.yml file" do
|
21
|
+
|
22
|
+
it 'should raise an exception if theme is not specified.' do
|
23
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({})
|
24
|
+
lambda { Ruhoh.setup_config }.should raise_error
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context "Valid _config.yml file" do
|
30
|
+
|
31
|
+
it 'should setup the config struct based on configuration input.' do
|
32
|
+
custom_permalink = '/my/custom/link'
|
33
|
+
custom_theme = 'table'
|
34
|
+
custom_exclude = ['.secret']
|
35
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({
|
36
|
+
"permalink" => custom_permalink,
|
37
|
+
"theme" => custom_theme,
|
38
|
+
'exclude' => custom_exclude
|
39
|
+
})
|
40
|
+
|
41
|
+
Ruhoh.setup_config
|
42
|
+
|
43
|
+
Ruhoh.config.permalink.should == custom_permalink
|
44
|
+
Ruhoh.config.theme.should == custom_theme
|
45
|
+
Ruhoh.config.theme_path.should == "/_templates/themes/#{custom_theme}"
|
46
|
+
Ruhoh.config.exclude.should == custom_exclude
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#setup_filters" do
|
54
|
+
|
55
|
+
it 'should add custom exclude filters to the filters variable' do
|
56
|
+
custom_exclude = ['.secret', /^test/]
|
57
|
+
Ruhoh::Utils.should_receive(:parse_file_as_yaml).and_return({
|
58
|
+
'theme' => "twitter",
|
59
|
+
'exclude' => custom_exclude
|
60
|
+
})
|
61
|
+
Ruhoh.setup_config
|
62
|
+
Ruhoh.setup_filters
|
63
|
+
|
64
|
+
Ruhoh.filters.pages['names'].should include('.secret')
|
65
|
+
Ruhoh.filters.pages['regexes'].should include(/^test/)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
|
11
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
12
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
13
|
+
require 'ruhoh'
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.after(:each) do
|
17
|
+
# Reset all configuration variables after each test.
|
18
|
+
Ruhoh.reset
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
SampleSitePath = File.expand_path(File.join(File.dirname(__FILE__), '../scaffolds/blog'))
|
23
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<script type="text/javascript">
|
2
|
+
var clicky_site_ids = clicky_site_ids || [];
|
3
|
+
clicky_site_ids.push({{ site.config.analytics.getclicky.site_id }});
|
4
|
+
(function() {
|
5
|
+
var s = document.createElement('script');
|
6
|
+
s.type = 'text/javascript';
|
7
|
+
s.async = true;
|
8
|
+
s.src = '//static.getclicky.com/js';
|
9
|
+
( document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] ).appendChild( s );
|
10
|
+
})();
|
11
|
+
</script>
|
12
|
+
<noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/{{ site.config.analytics.getclicky.site_id }}ns.gif" /></p></noscript>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<script type="text/javascript">
|
2
|
+
var _gaq = _gaq || [];
|
3
|
+
_gaq.push(['_setAccount', '{{ site.config.analytics.google.tracking_id }}']);
|
4
|
+
_gaq.push(['_trackPageview']);
|
5
|
+
|
6
|
+
(function() {
|
7
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
8
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
9
|
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
10
|
+
})();
|
11
|
+
</script>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div id="disqus_thread"></div>
|
2
|
+
<script type="text/javascript">
|
3
|
+
{{^site.production }}var disqus_developer = 1;{{/site.production}}
|
4
|
+
var disqus_shortname = '{{ site.config.comments.disqus.short_name }}'; // required: replace example with your forum shortname
|
5
|
+
/* * * DON'T EDIT BELOW THIS LINE * * */
|
6
|
+
(function() {
|
7
|
+
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
8
|
+
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
9
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
10
|
+
})();
|
11
|
+
</script>
|
12
|
+
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
13
|
+
<a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<div id="fb-root"></div>
|
2
|
+
<script>(function(d, s, id) {
|
3
|
+
var js, fjs = d.getElementsByTagName(s)[0];
|
4
|
+
if (d.getElementById(id)) return;
|
5
|
+
js = d.createElement(s); js.id = id;
|
6
|
+
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId={{ site.config.comments.facebook.appid }}";
|
7
|
+
fjs.parentNode.insertBefore(js, fjs);
|
8
|
+
}(document, 'script', 'facebook-jssdk'));</script>
|
9
|
+
<div class="fb-comments" data-href="{{ site.production_url }}" data-num-posts="{{ site.config.comments.facebook.num_posts }}" data-width="{{ site.config.comments.facebook.width }}" data-colorscheme="{{ site.config.comments.facebook.colorscheme }}"></div>
|