ruhoh 0.0.2 → 0.0.3
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.
- 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>
|