schnitzelpress 0.1.1 → 0.2.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.
- data/CHANGES.md +20 -3
- data/README.md +4 -2
- data/bin/schnitzelpress +1 -1
- data/lib/assets/js/jquery-1.7.1.js +673 -0
- data/lib/assets/js/jquery-ujs.js +373 -0
- data/lib/assets/js/jquery.cookie.js +47 -0
- data/lib/{public → assets}/js/schnitzelpress.js +7 -2
- data/lib/public/font/fontawesome-webfont.eot +0 -0
- data/lib/public/font/fontawesome-webfont.svg +175 -0
- data/lib/public/font/fontawesome-webfont.svgz +0 -0
- data/lib/public/font/fontawesome-webfont.ttf +0 -0
- data/lib/public/font/fontawesome-webfont.woff +0 -0
- data/lib/schnitzelpress.rb +21 -5
- data/lib/schnitzelpress/actions/admin.rb +21 -1
- data/lib/schnitzelpress/actions/assets.rb +36 -0
- data/lib/schnitzelpress/actions/auth.rb +16 -3
- data/lib/schnitzelpress/actions/blog.rb +10 -12
- data/lib/schnitzelpress/app.rb +16 -19
- data/lib/schnitzelpress/cache_control.rb +17 -0
- data/lib/schnitzelpress/cli.rb +40 -9
- data/lib/schnitzelpress/config.rb +43 -0
- data/lib/schnitzelpress/env.rb +5 -0
- data/lib/schnitzelpress/helpers.rb +168 -4
- data/lib/schnitzelpress/markdown_renderer.rb +2 -2
- data/lib/schnitzelpress/post.rb +2 -6
- data/lib/schnitzelpress/static.rb +1 -1
- data/lib/schnitzelpress/version.rb +2 -2
- data/lib/templates/new_blog/Gemfile +4 -5
- data/lib/templates/new_blog/Gemfile.lock.tt +137 -0
- data/lib/templates/new_blog/Procfile +1 -1
- data/lib/templates/new_blog/config.ru.tt +6 -17
- data/lib/views/admin/admin.haml +3 -2
- data/lib/views/admin/config.haml +27 -0
- data/lib/views/atom.haml +3 -3
- data/lib/views/index.haml +1 -1
- data/lib/views/layout.haml +15 -11
- data/lib/views/login.haml +4 -0
- data/lib/views/partials/_admin_post_list.haml +8 -8
- data/lib/views/partials/_disqus.haml +1 -1
- data/lib/views/partials/_gauges.haml +1 -1
- data/lib/views/partials/_google_analytics.haml +1 -1
- data/lib/views/partials/_post.haml +6 -5
- data/lib/views/partials/_post_form.haml +3 -1
- data/lib/views/post.haml +4 -1
- data/lib/views/schnitzelpress.scss +67 -3
- data/schnitzelpress.gemspec +5 -2
- data/spec/app_spec.rb +5 -11
- data/spec/assets_spec.rb +26 -0
- data/spec/factories.rb +1 -1
- data/spec/post_spec.rb +9 -2
- data/spec/spec_helper.rb +2 -1
- metadata +115 -71
- data/lib/schnitzelpress/rake.rb +0 -20
- data/lib/templates/new_blog/Rakefile +0 -2
- data/lib/templates/new_blog/app.rb.tt +0 -34
- data/lib/templates/new_blog/config/unicorn.rb +0 -5
- data/lib/templates/new_blog/public/.gitkeep +0 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
- set_page_title "Configuration"
|
2
|
+
|
3
|
+
%section
|
4
|
+
%form.post{:action => '/admin/config', :method => 'post'}
|
5
|
+
%h2 Blog
|
6
|
+
= form_field config, :blog_title
|
7
|
+
= form_field config, :blog_description
|
8
|
+
= form_field config, :blog_footer
|
9
|
+
|
10
|
+
%h2 Author
|
11
|
+
= form_field config, :author_name
|
12
|
+
|
13
|
+
%h2 External Services
|
14
|
+
= form_field config, :blog_feed_url, :label => "ATOM Feed URL", :hint => "This is what the /feed URL will redirect to. You can change this to eg. your FeedBurner URL."
|
15
|
+
.row
|
16
|
+
.six.columns
|
17
|
+
= form_field config, :disqus_id, :label => "Disqus shortname"
|
18
|
+
.six.columns
|
19
|
+
= form_field config, :twitter_id, :label => "Twitter user name"
|
20
|
+
.row
|
21
|
+
.six.columns
|
22
|
+
= form_field config, :google_analytics_id, :label => "Google Analytics ID"
|
23
|
+
.six.columns
|
24
|
+
= form_field config, :gauges_id, :label => "Gauges ID"
|
25
|
+
|
26
|
+
.buttons
|
27
|
+
%input{:type => 'submit', :value => 'Update Configuration'}
|
data/lib/views/atom.haml
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
!!! XML
|
2
2
|
%feed{:xmlns => 'http://www.w3.org/2005/Atom'}
|
3
|
-
%title=
|
3
|
+
%title= config.blog_title
|
4
4
|
%link{:href => url_for('/', :absolute => true)}
|
5
5
|
%id= base_url
|
6
6
|
- if @posts.any?
|
7
7
|
%updated= @posts.first.published_at
|
8
8
|
|
9
9
|
%author
|
10
|
-
%name=
|
10
|
+
%name= config.author_name
|
11
11
|
|
12
12
|
- @posts.each do |post|
|
13
13
|
%entry
|
@@ -17,7 +17,7 @@
|
|
17
17
|
%published= post.published_at
|
18
18
|
%updated= post.published_at
|
19
19
|
%author
|
20
|
-
%name=
|
20
|
+
%name= config.author_name
|
21
21
|
%content{:type => 'html'}
|
22
22
|
:cdata
|
23
23
|
#{post.to_html}
|
data/lib/views/index.haml
CHANGED
data/lib/views/layout.haml
CHANGED
@@ -1,28 +1,32 @@
|
|
1
1
|
!!! 5
|
2
2
|
%html
|
3
3
|
%head
|
4
|
-
%title= [@page_title,
|
4
|
+
%title= [@page_title, config.blog_title].compact.join(" | ")
|
5
5
|
%meta{ :"http-equiv" => "content-type", :content => "text/html; charset=UTF-8" }
|
6
6
|
%meta{ :name => "viewport", :content => "width=device-width, initial-scale=1.0" }
|
7
|
-
%link{ :href =>
|
8
|
-
%link{ :href =>
|
9
|
-
%script{ :type => 'text/javascript', :src => '//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js' }
|
10
|
-
%script{ :type => 'text/javascript', :src => '//browserid.org/include.js' }
|
11
|
-
%script{ :type => 'text/javascript', :src => '/js/schnitzelpress.js' }
|
7
|
+
%link{ :href => "/assets/schnitzelpress.#{ASSET_TIMESTAMP}.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }
|
8
|
+
%link{ :href => config.blog_feed_url, :title => "Subscribe via Atom Feed", :rel => 'alternate', :type => 'application/atom+xml' }
|
12
9
|
%body
|
13
10
|
.container
|
14
11
|
%header
|
15
12
|
.site-title
|
16
|
-
%a{:href => '/'}=
|
13
|
+
%a{:href => '/'}= h config.blog_title
|
17
14
|
- if @show_description
|
18
|
-
~ markdown
|
15
|
+
~ markdown config.blog_description
|
16
|
+
|
17
|
+
#actions.admin_only
|
18
|
+
= yield_content :actions
|
19
|
+
%a{:href => '/admin/'} #{icon 'cog'} Go To Admin
|
20
|
+
%a{:href => '/logout'} #{icon 'signout'} Logout
|
19
21
|
|
20
22
|
= yield
|
21
23
|
|
22
24
|
%footer
|
23
|
-
~ markdown
|
25
|
+
~ markdown config.blog_footer
|
24
26
|
|
25
|
-
- if production? &&
|
27
|
+
- if production? && config.google_analytics_id.present?
|
26
28
|
= partial 'google_analytics'
|
27
|
-
- if production? &&
|
29
|
+
- if production? && config.gauges_id.present?
|
28
30
|
= partial 'gauges'
|
31
|
+
|
32
|
+
%script{ :type => 'text/javascript', :src => "/assets/schnitzelpress.#{ASSET_TIMESTAMP}.js" }
|
data/lib/views/login.haml
CHANGED
@@ -6,6 +6,10 @@
|
|
6
6
|
|
7
7
|
%p
|
8
8
|
%a.button#browser_id{:href => '/auth/browser_id'} Log in with BrowserID
|
9
|
+
- if Schnitzelpress.env.development?
|
10
|
+
%a.green.button{:href => '/auth/developer'} Developer Login
|
9
11
|
|
10
12
|
%form{:method => 'post', :action => '/auth/browser_id/callback', :noValidate => 'noValidate'}
|
11
13
|
%input{:type => 'hidden', :name => 'assertion'}
|
14
|
+
|
15
|
+
%script{ :type => 'text/javascript', :src => '//browserid.org/include.js' }
|
@@ -1,11 +1,11 @@
|
|
1
1
|
- if posts.any?
|
2
2
|
%h2= title
|
3
|
-
|
3
|
+
.admin-post-list
|
4
4
|
- posts.each do |post|
|
5
|
-
|
6
|
-
|
7
|
-
%a
|
8
|
-
|
9
|
-
%a
|
10
|
-
|
11
|
-
=
|
5
|
+
.row
|
6
|
+
.ten.columns
|
7
|
+
%a{:href => "/admin/edit/#{post.id}"}= h (post.title || ("%s..." % post.body.first(50)))
|
8
|
+
.two.columns.icons
|
9
|
+
%a{:href => url_for(post)}= icon 'eye-open'
|
10
|
+
%a{:href => "/admin/edit/#{post.id}"}= icon 'edit'
|
11
|
+
= link_to_delete_post icon('trash'), post
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
:javascript
|
4
4
|
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
|
5
|
-
var disqus_shortname = '#{
|
5
|
+
var disqus_shortname = '#{config.disqus_id}';
|
6
6
|
var disqus_developer = #{production? ? 0 : 1};
|
7
7
|
var disqus_identifier = '#{disqus_identifier}';
|
8
8
|
|
@@ -5,7 +5,7 @@
|
|
5
5
|
t.type = 'text/javascript';
|
6
6
|
t.async = true;
|
7
7
|
t.id = 'gauges-tracker';
|
8
|
-
t.setAttribute('data-site-id', '#{
|
8
|
+
t.setAttribute('data-site-id', '#{config.gauges_id}');
|
9
9
|
t.src = '//secure.gaug.es/track.js';
|
10
10
|
var s = document.getElementsByTagName('script')[0];
|
11
11
|
s.parentNode.insertBefore(t, s);
|
@@ -4,13 +4,13 @@
|
|
4
4
|
- show_body ||= complete || !show_summary
|
5
5
|
- show_read_more ||= !complete && post.summary.present?
|
6
6
|
- show_permalink ||= true
|
7
|
-
- show_twitter ||= complete && post.post? &&
|
7
|
+
- show_twitter ||= complete && post.post? && config.twitter_id.present?
|
8
8
|
|
9
9
|
%article.post{:class => [post.status, post.link_post? ? 'link' : 'article']}
|
10
10
|
%header
|
11
11
|
- if show_title
|
12
12
|
%h1
|
13
|
-
%a{:href => post.link || post.to_url}= h post.title
|
13
|
+
%a.instapaper_title{:href => post.link || post.to_url}= h post.title
|
14
14
|
- if post.link_post?
|
15
15
|
%span.link-arrow ➝
|
16
16
|
|
@@ -19,11 +19,12 @@
|
|
19
19
|
~ markdown post.summary
|
20
20
|
- if show_read_more
|
21
21
|
%p
|
22
|
-
%a{:href => url_for(post)}= post.read_more.presence ||
|
22
|
+
%a{:href => url_for(post)}= post.read_more.presence || "Read Complete Article"
|
23
23
|
→
|
24
24
|
|
25
25
|
- if show_body
|
26
|
-
|
26
|
+
.instapaper_body
|
27
|
+
~ post.to_html
|
27
28
|
|
28
29
|
%footer
|
29
30
|
- if show_permalink
|
@@ -33,6 +34,6 @@
|
|
33
34
|
- if show_twitter
|
34
35
|
.social_media_buttons
|
35
36
|
- if show_twitter
|
36
|
-
%a{:href => "https://twitter.com/share", :class => "twitter-share-button", :data => {:via =>
|
37
|
+
%a{:href => "https://twitter.com/share", :class => "twitter-share-button", :data => {:via => config.twitter_id}}
|
37
38
|
:javascript
|
38
39
|
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
|
@@ -17,4 +17,6 @@
|
|
17
17
|
= form_field @post, :disqus
|
18
18
|
|
19
19
|
.buttons
|
20
|
-
%
|
20
|
+
%button.green{:type => 'submit'} #{icon 'ok'} #{@post.new_record? ? 'Create Post' : 'Update Post'}
|
21
|
+
or
|
22
|
+
= link_to_delete_post "delete this post", @post
|
data/lib/views/post.haml
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
- if @extra_posts
|
6
6
|
%section.extra_posts
|
7
7
|
%h1
|
8
|
-
%a{href
|
8
|
+
%a{:href => '/blog'}= @extra_posts.first
|
9
9
|
%ul
|
10
10
|
- for post in @extra_posts.second
|
11
11
|
%li
|
@@ -14,3 +14,6 @@
|
|
14
14
|
- if show_disqus? && @post.disqus?
|
15
15
|
%section.disqus
|
16
16
|
= partial 'disqus', :disqus_identifier => @post.disqus_identifier
|
17
|
+
|
18
|
+
- content_for :actions do
|
19
|
+
%a{:href => "/admin/edit/%s" % @post.id} #{icon 'edit'} Edit
|
@@ -8,6 +8,34 @@ body, .container {
|
|
8
8
|
background-image: url(/img/background.png);
|
9
9
|
}
|
10
10
|
|
11
|
+
.admin_only {
|
12
|
+
display: none;
|
13
|
+
body.show_admin & { display: block; }
|
14
|
+
}
|
15
|
+
|
16
|
+
/* action panel */
|
17
|
+
#actions {
|
18
|
+
@include small-type;
|
19
|
+
margin: 5px;
|
20
|
+
|
21
|
+
a {
|
22
|
+
display: inline-block;
|
23
|
+
padding: 3px 6px;
|
24
|
+
background-color: $color-text;
|
25
|
+
color: $color-background;
|
26
|
+
font-weight: bold;
|
27
|
+
text-decoration: none;
|
28
|
+
border-radius: 3px;
|
29
|
+
@include appear-on-hover;
|
30
|
+
}
|
31
|
+
|
32
|
+
@media only screen and (min-width: 641px) {
|
33
|
+
position: fixed;
|
34
|
+
top: 0px;
|
35
|
+
right: 0px;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
11
39
|
/* posts */
|
12
40
|
article.post {
|
13
41
|
header {
|
@@ -31,8 +59,7 @@ article.post {
|
|
31
59
|
@include animated;
|
32
60
|
|
33
61
|
margin: 2em 0;
|
34
|
-
|
35
|
-
&:hover { opacity: 1 }
|
62
|
+
@include appear-on-hover;
|
36
63
|
}
|
37
64
|
}
|
38
65
|
}
|
@@ -52,12 +79,35 @@ ul.admin {
|
|
52
79
|
}
|
53
80
|
}
|
54
81
|
|
55
|
-
|
82
|
+
div.admin-post-list {
|
56
83
|
padding: 5px 0;
|
84
|
+
margin: 1em 0;
|
57
85
|
max-height: 300px;
|
58
86
|
overflow: auto;
|
59
87
|
border-bottom: 1px dotted rgba($color-text, 0.5);
|
60
88
|
border-top: 1px dotted rgba($color-text, 0.5);
|
89
|
+
|
90
|
+
.icons {
|
91
|
+
display: none;
|
92
|
+
text-align: right;
|
93
|
+
a {
|
94
|
+
color: $color-footer;
|
95
|
+
&:hover { color: $color-text };
|
96
|
+
}
|
97
|
+
}
|
98
|
+
.row {
|
99
|
+
padding: 3px;
|
100
|
+
margin-bottom: 0;
|
101
|
+
&:hover {
|
102
|
+
background-color: rgba($color-text, 0.05);
|
103
|
+
.icons {
|
104
|
+
display: block;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
a {
|
109
|
+
border: none;
|
110
|
+
}
|
61
111
|
}
|
62
112
|
|
63
113
|
// forms
|
@@ -87,3 +137,17 @@ section.posts #welcome {
|
|
87
137
|
@include clearfix;
|
88
138
|
}
|
89
139
|
}
|
140
|
+
|
141
|
+
// font-awesome
|
142
|
+
@font-face {
|
143
|
+
font-family: 'FontAwesome';
|
144
|
+
src: url('/font/fontawesome-webfont.eot');
|
145
|
+
src: url('/font/fontawesome-webfont.eot?#iefix') format('embedded-opentype'), url('/font/fontawesome-webfont.woff') format('woff'), url('/font/fontawesome-webfont.ttf') format('truetype'), url('/font/fontawesome-webfont.svgz#FontAwesomeRegular') format('svg'), url('/font/fontawesome-webfont.svg#FontAwesomeRegular') format('svg');
|
146
|
+
font-weight: normal;
|
147
|
+
font-style: normal;
|
148
|
+
}
|
149
|
+
.font-awesome {
|
150
|
+
font-family: FontAwesome;
|
151
|
+
font-weight: normal;
|
152
|
+
font-style: normal;
|
153
|
+
}
|
data/schnitzelpress.gemspec
CHANGED
@@ -13,12 +13,14 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
14
|
gem.name = "schnitzelpress"
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.version =
|
16
|
+
gem.version = Schnitzelpress::VERSION
|
17
17
|
|
18
18
|
# base dependencies
|
19
19
|
gem.add_dependency 'rack', '~> 1.4.1'
|
20
20
|
gem.add_dependency 'rack-contrib', '~> 1.1.0'
|
21
|
+
gem.add_dependency 'rack-cache', '~> 1.1.0'
|
21
22
|
gem.add_dependency 'sinatra', '~> 1.3.2'
|
23
|
+
gem.add_dependency 'sinatra-contrib', '~> 1.3.1'
|
22
24
|
gem.add_dependency 'activesupport', '~> 3.2.0'
|
23
25
|
|
24
26
|
# database related
|
@@ -35,10 +37,11 @@ Gem::Specification.new do |gem|
|
|
35
37
|
gem.add_dependency 'sass', '~> 3.1.15'
|
36
38
|
gem.add_dependency 'redcarpet', '~> 2.1.0'
|
37
39
|
gem.add_dependency 'coderay', '~> 1.0.5'
|
38
|
-
gem.add_dependency 'schnitzelstyle', '~> 0.1.
|
40
|
+
gem.add_dependency 'schnitzelstyle', '~> 0.1.1'
|
39
41
|
gem.add_dependency 'i18n', '~> 0.6.0'
|
40
42
|
gem.add_dependency 'tilt', '~> 1.3.0'
|
41
43
|
gem.add_dependency 'ruby-oembed', '~> 0.8.5'
|
44
|
+
gem.add_dependency 'packr', '~> 3.1.1'
|
42
45
|
|
43
46
|
# CLI related
|
44
47
|
gem.add_dependency 'thor', '~> 0.14.6'
|
data/spec/app_spec.rb
CHANGED
@@ -1,16 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
configure do
|
5
|
-
set :blog_title, "A Test Blog"
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
describe SchnitzelPress::App do
|
3
|
+
describe Schnitzelpress::App do
|
10
4
|
include Rack::Test::Methods
|
11
5
|
|
12
6
|
def app
|
13
|
-
|
7
|
+
Schnitzelpress::App
|
14
8
|
end
|
15
9
|
|
16
10
|
describe 'the home page' do
|
@@ -23,7 +17,7 @@ describe SchnitzelPress::App do
|
|
23
17
|
subject { last_response }
|
24
18
|
|
25
19
|
it { should be_ok }
|
26
|
-
its(:body) { should have_tag 'title', :text =>
|
20
|
+
its(:body) { should have_tag 'title', :text => Schnitzelpress::Config.instance.blog_title }
|
27
21
|
its(:body) { should have_tag 'section.posts > article.post.published', :count => 5 }
|
28
22
|
its(:body) { should_not have_tag 'section.posts > article.post.draft' }
|
29
23
|
end
|
@@ -36,14 +30,14 @@ describe SchnitzelPress::App do
|
|
36
30
|
|
37
31
|
describe 'the public feed url' do
|
38
32
|
before do
|
39
|
-
|
33
|
+
Schnitzelpress::Config.instance.blog_feed_url = 'http://feeds.feedburner.com/example_org'
|
40
34
|
get '/feed'
|
41
35
|
end
|
42
36
|
|
43
37
|
subject { last_response }
|
44
38
|
it { should be_redirect }
|
45
39
|
its(:status) { should == 307 }
|
46
|
-
specify { subject["Location"].should == 'http://
|
40
|
+
specify { subject["Location"].should == 'http://example.org/blog.atom' }
|
47
41
|
end
|
48
42
|
|
49
43
|
describe 'viewing a single post' do
|
data/spec/assets_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Schnitzelpress::Actions::Assets' do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
Schnitzelpress::App
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '/assets/schnitzelpress.*.js' do
|
11
|
+
before do
|
12
|
+
Schnitzelpress::JavascriptPacker.should_receive(:pack_javascripts!).and_return('{123}')
|
13
|
+
get '/assets/schnitzelpress.123.js'
|
14
|
+
end
|
15
|
+
subject { last_response }
|
16
|
+
it { should be_ok }
|
17
|
+
its(:body) { should == '{123}' }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '/assets/schnitzelpress.*.css' do
|
21
|
+
before { get '/assets/schnitzelpress.123.css' }
|
22
|
+
subject { last_response }
|
23
|
+
it { should be_ok }
|
24
|
+
its(:content_type) { should == 'text/css;charset=utf-8' }
|
25
|
+
end
|
26
|
+
end
|
data/spec/factories.rb
CHANGED
data/spec/post_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Schnitzelpress::Post do
|
4
4
|
subject do
|
5
5
|
Factory.build(:post)
|
6
6
|
end
|
@@ -81,7 +81,7 @@ describe SchnitzelPress::Post do
|
|
81
81
|
it 'should return the latest published posts' do
|
82
82
|
2.times { Factory :draft_post }
|
83
83
|
5.times { Factory :published_post }
|
84
|
-
|
84
|
+
Schnitzelpress::Post.latest.size.should == 5
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -91,4 +91,11 @@ describe SchnitzelPress::Post do
|
|
91
91
|
its(:month) { should == 01 }
|
92
92
|
its(:day) { should == 02 }
|
93
93
|
end
|
94
|
+
|
95
|
+
context 'to_url' do
|
96
|
+
it 'should produce double-digit months and days' do
|
97
|
+
@post = Factory.build(:post, :published_at => '2012-1-1 12:00:00', :slug => 'test')
|
98
|
+
@post.to_url.should == '/2012/01/01/test/'
|
99
|
+
end
|
100
|
+
end
|
94
101
|
end
|