postmarkdown 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +3 -0
  5. data/Rakefile +24 -0
  6. data/app/controllers/application_controller.rb +2 -0
  7. data/app/controllers/posts_controller.rb +31 -0
  8. data/app/models/post.rb +149 -0
  9. data/app/views/layouts/postmarkdown.html.haml +16 -0
  10. data/app/views/posts/_feed_link.html.haml +2 -0
  11. data/app/views/posts/_post.html.haml +15 -0
  12. data/app/views/posts/feed.xml.builder +29 -0
  13. data/app/views/posts/index.html.haml +8 -0
  14. data/app/views/posts/show.html.haml +3 -0
  15. data/lib/generators/postmarkdown/install_generator.rb +19 -0
  16. data/lib/generators/postmarkdown/override_generator.rb +44 -0
  17. data/lib/generators/postmarkdown/post_generator.rb +33 -0
  18. data/lib/generators/postmarkdown/templates/example-post.markdown +67 -0
  19. data/lib/generators/postmarkdown/usage/install.txt +10 -0
  20. data/lib/generators/postmarkdown/usage/override.txt +9 -0
  21. data/lib/generators/postmarkdown/usage/post.txt +14 -0
  22. data/lib/postmarkdown.rb +5 -0
  23. data/lib/postmarkdown/config.rb +22 -0
  24. data/lib/postmarkdown/engine.rb +12 -0
  25. data/lib/postmarkdown/railtie.rb +18 -0
  26. data/lib/postmarkdown/routes.rb +29 -0
  27. data/lib/postmarkdown/util.rb +12 -0
  28. data/lib/postmarkdown/version.rb +3 -0
  29. data/postmarkdown.gemspec +35 -0
  30. data/public/stylesheets/postmarkdown/postmarkdown.css +67 -0
  31. data/readme.md +143 -0
  32. data/spec/acceptance/posts_spec.rb +167 -0
  33. data/spec/models/posts_spec.rb +72 -0
  34. data/spec/routing/posts_routing_spec.rb +80 -0
  35. data/spec/spec_helper.rb +12 -0
  36. data/spec/support/data/posts/2011-04-01-first-post.markdown +3 -0
  37. data/spec/support/data/posts/2011-04-28-image.markdown +3 -0
  38. data/spec/support/data/posts/2011-04-28-summary.markdown +8 -0
  39. data/spec/support/data/posts/2011-05-01-full-metadata.markdown +10 -0
  40. data/spec/support/data/posts/2011-05-02-md-file-extension.md +1 -0
  41. data/spec/support/data/posts/2011-05-02-mdown-file-extension.mdown +1 -0
  42. data/spec/support/data/posts/2011-05-02-mkd-file-extension.mkd +1 -0
  43. data/spec/support/data/posts/2015-02-13-custom-title.markdown +5 -0
  44. data/spec/support/data/posts/missing-date-from-filename.markdown +1 -0
  45. data/spec/support/rails_app/.gitignore +4 -0
  46. data/spec/support/rails_app/README +256 -0
  47. data/spec/support/rails_app/Rakefile +7 -0
  48. data/spec/support/rails_app/app/controllers/application_controller.rb +3 -0
  49. data/spec/support/rails_app/app/helpers/application_helper.rb +2 -0
  50. data/spec/support/rails_app/app/posts/2011-04-01-first-post.markdown +3 -0
  51. data/spec/support/rails_app/app/posts/2011-04-28-image.markdown +3 -0
  52. data/spec/support/rails_app/app/posts/2011-04-28-summary.markdown +8 -0
  53. data/spec/support/rails_app/app/posts/2011-05-01-full-metadata.markdown +13 -0
  54. data/spec/support/rails_app/app/posts/2015-02-13-custom-title.markdown +5 -0
  55. data/spec/support/rails_app/app/views/layouts/application.html.erb +14 -0
  56. data/spec/support/rails_app/config.ru +4 -0
  57. data/spec/support/rails_app/config/application.rb +42 -0
  58. data/spec/support/rails_app/config/boot.rb +10 -0
  59. data/spec/support/rails_app/config/database.yml +22 -0
  60. data/spec/support/rails_app/config/environment.rb +5 -0
  61. data/spec/support/rails_app/config/environments/development.rb +26 -0
  62. data/spec/support/rails_app/config/environments/production.rb +49 -0
  63. data/spec/support/rails_app/config/environments/test.rb +35 -0
  64. data/spec/support/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  65. data/spec/support/rails_app/config/initializers/inflections.rb +10 -0
  66. data/spec/support/rails_app/config/initializers/mime_types.rb +5 -0
  67. data/spec/support/rails_app/config/initializers/secret_token.rb +7 -0
  68. data/spec/support/rails_app/config/initializers/session_store.rb +8 -0
  69. data/spec/support/rails_app/config/locales/en.yml +5 -0
  70. data/spec/support/rails_app/config/routes.rb +3 -0
  71. data/spec/support/rails_app/db/seeds.rb +7 -0
  72. data/spec/support/rails_app/doc/README_FOR_APP +2 -0
  73. data/spec/support/rails_app/lib/tasks/.gitkeep +0 -0
  74. data/spec/support/rails_app/public/404.html +26 -0
  75. data/spec/support/rails_app/public/422.html +26 -0
  76. data/spec/support/rails_app/public/500.html +26 -0
  77. data/spec/support/rails_app/public/favicon.ico +0 -0
  78. data/spec/support/rails_app/public/images/rails.png +0 -0
  79. data/spec/support/rails_app/public/index.html +239 -0
  80. data/spec/support/rails_app/public/javascripts/application.js +2 -0
  81. data/spec/support/rails_app/public/javascripts/controls.js +965 -0
  82. data/spec/support/rails_app/public/javascripts/dragdrop.js +974 -0
  83. data/spec/support/rails_app/public/javascripts/effects.js +1123 -0
  84. data/spec/support/rails_app/public/javascripts/prototype.js +6001 -0
  85. data/spec/support/rails_app/public/javascripts/rails.js +191 -0
  86. data/spec/support/rails_app/public/robots.txt +5 -0
  87. data/spec/support/rails_app/public/stylesheets/.gitkeep +0 -0
  88. data/spec/support/rails_app/script/rails +6 -0
  89. data/spec/support/rails_app/test/performance/browsing_test.rb +9 -0
  90. data/spec/support/rails_app/test/test_helper.rb +13 -0
  91. data/spec/support/rails_app/vendor/plugins/.gitkeep +0 -0
  92. data/todo.txt +25 -0
  93. metadata +315 -0
@@ -0,0 +1,10 @@
1
+ Description:
2
+ This generator will create the directory structure and routes required by Postmarkdown. As an added bonus, it will create an example post for the current date.
3
+
4
+ Example:
5
+ $ rails generate postmarkdown:install
6
+
7
+ This will:
8
+ - Create the directory `app/posts/`.
9
+ - Generate an example post using today's date: `app/posts/{{CURRENT_DATE}}-example-post.markdown`.
10
+ - Add default routes.
@@ -0,0 +1,9 @@
1
+ Description:
2
+ This generator will override either the Post model, controller or views.
3
+
4
+ Examples:
5
+ $ rails generate postmarkdown:override --all # overrides all of the things
6
+ $ rails generate postmarkdown:override --controller # overrides file `app/controllers/posts_controller.rb`
7
+ $ rails generate postmarkdown:override --model # overrides file `app/models/post.rb`
8
+ $ rails generate postmarkdown:override --views # overrides all files in directory `app/views/posts/`
9
+ $ rails generate postmarkdown:override --theme # overrides the layout and stylesheet
@@ -0,0 +1,14 @@
1
+ Description:
2
+ This generator will produce a new post by creating a markdown file in the `app/posts/` directory. The filename for the new file will be generated using the slug and publish date specified.
3
+
4
+ Example 1:
5
+ $ rails generate postmarkdown:post example-1
6
+
7
+ This will:
8
+ - Generate a new post using the slug specified and today's date: `app/posts/{{CURRENT_DATE}}-example-1.markdown`.
9
+
10
+ Example 2:
11
+ $ rails generate postmarkdown:post example-2 --date=2012-04-10
12
+
13
+ This will:
14
+ - Generate a new post using the slug and publish date specified: `app/posts/2012-04-10-example-2.markdown`.
@@ -0,0 +1,5 @@
1
+ require 'postmarkdown/engine'
2
+ require 'postmarkdown/config'
3
+ require 'postmarkdown/routes'
4
+ require 'postmarkdown/railtie'
5
+ require 'postmarkdown/util'
@@ -0,0 +1,22 @@
1
+ module Postmarkdown
2
+ module Config
3
+ extend self
4
+
5
+ @options = {}
6
+ attr_accessor :options
7
+ end
8
+ end
9
+
10
+ Postmarkdown::Config.options[:feed_title] = nil
11
+
12
+ Postmarkdown::Config.options[:permalink_format] = :day
13
+
14
+ Postmarkdown::Config.options[:use_theme] = false
15
+
16
+ Postmarkdown::Config.options[:permalink_regex] = {}
17
+ Postmarkdown::Config.options[:permalink_regex][:day] = %r[\d{4}/\d{2}/\d{2}/[^/]+]
18
+ Postmarkdown::Config.options[:permalink_regex][:month] = %r[\d{4}/\d{2}/[^/]+]
19
+ Postmarkdown::Config.options[:permalink_regex][:year] = %r[\d{4}/[^/]+]
20
+ Postmarkdown::Config.options[:permalink_regex][:slug] = %r[[^/]+]
21
+
22
+ Postmarkdown::Config.options[:markdown_file_extensions] = %w(md mkd mdown markdown)
@@ -0,0 +1,12 @@
1
+ module Postmarkdown
2
+ require 'postmarkdown'
3
+ require 'rails'
4
+ require 'gravtastic'
5
+ require 'rdiscount'
6
+ require 'nokogiri'
7
+ require 'haml'
8
+ require 'kaminari'
9
+
10
+ class Engine < Rails::Engine
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ module Postmarkdown
2
+ class Railtie < Rails::Railtie
3
+ initializer :before_initialize do
4
+ require 'rack'
5
+ Rails.configuration.middleware.insert_before('Rack::Sendfile', 'Rack::Static',
6
+ :urls => ['/stylesheets/postmarkdown'],
7
+ :root => "#{postmarkdown_root}/public"
8
+ )
9
+ ActionController::Base.prepend_view_path("#{postmarkdown_root}/app/views")
10
+ end
11
+
12
+ private
13
+
14
+ def postmarkdown_root
15
+ File.expand_path(File.dirname(__FILE__) + '/../..')
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ class ActionDispatch::Routing::Mapper
2
+ require 'postmarkdown/util'
3
+
4
+ def postmarkdown(options = {})
5
+ options.reverse_merge!({ :as => :posts, :permalink_format => :day })
6
+
7
+ get "/#{options[:as]}(/:year(/:month(/:day)))" => 'posts#index', :as => :posts, :constraints => { :year => /\d{4}/, :month => /\d{2}/, :day => /\d{2}/}
8
+ get "/#{options[:as]}/feed" => 'posts#feed', :as => :posts_feed, :format => :xml
9
+ get "/#{options[:as]}/*id" => 'posts#show', :as => :post, :constraints => { :id => postmarkdown_permalink_regex(options) }
10
+
11
+ postmarkdown_feed_title(options[:as])
12
+ end
13
+
14
+ private
15
+
16
+ def postmarkdown_permalink_regex(options)
17
+ Postmarkdown::Config.options[:permalink_format] = options[:permalink_format]
18
+ Postmarkdown::Config.options[:permalink_regex].try(:[], options[:permalink_format]) or raise_postmarkdown_permalink_error
19
+ end
20
+
21
+ def postmarkdown_feed_title(path)
22
+ Postmarkdown::Config.options[:feed_title] ||= "#{Postmarkdown::Util.app_name} #{path.to_s.tr('/', '_').humanize.titleize}"
23
+ end
24
+
25
+ def raise_postmarkdown_permalink_error
26
+ possible_options = Postmarkdown::Config.options[:permalink_regex].map { |k,v| k.inspect }.join(', ')
27
+ raise "Postmarkdown Routing Error: Invalid :permalink_format option #{Postmarkdown::Config.options[:permalink_format].inspect} - must be one of the following: #{possible_options}"
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ module Postmarkdown
2
+ module Util
3
+ def self.app_name
4
+ Rails.application.class.name.split('::')[0..-2].join.titleize
5
+ end
6
+
7
+ def self.git_config(name)
8
+ value = `git config --get #{name}`.chomp
9
+ value if $?.success?
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Postmarkdown
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'postmarkdown/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'postmarkdown'
7
+ s.version = Postmarkdown::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Jason Weathered', 'Nathanael Kane', 'Odin Dutton', 'Adrian Smith']
10
+ s.email = ['jason.weathered@ennova.com.au', 'nate.kane@ennova.com.au', 'odin.dutton@ennova.com.au', 'adrian.smith@ennova.com.au']
11
+ s.licenses = ['MIT']
12
+
13
+ s.homepage = ''
14
+ s.summary = %q{A simple Rails blog engine powered by markdown.}
15
+ s.description = s.summary
16
+
17
+ s.rubyforge_project = 'postmarkdown'
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ['lib', 'public']
23
+
24
+ s.add_dependency 'rails', '~> 3.0'
25
+ s.add_dependency 'haml', '~> 3.1'
26
+ s.add_dependency 'gravtastic'
27
+ s.add_dependency 'nokogiri'
28
+ s.add_dependency 'rdiscount'
29
+ s.add_dependency 'kaminari'
30
+
31
+ s.add_development_dependency 'rspec-rails', '~> 2.5'
32
+ s.add_development_dependency 'capybara', '~> 1.0.0.beta'
33
+ s.add_development_dependency 'sqlite3'
34
+ s.add_development_dependency 'delorean', '>= 0.2'
35
+ end
@@ -0,0 +1,67 @@
1
+ /* -- Reset ----------------------------------------------------------------- */
2
+ body,div,dl,dt,dd,ul,ol,li,h1,h2,h4,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0}
3
+ table{border-collapse:collapse;border-spacing:0}
4
+ fieldset,img{border:0}
5
+ address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit}
6
+ del,ins{text-decoration:none}
7
+ li{list-style:none}
8
+ caption,th{text-align:left}
9
+ h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}
10
+ q:before,q:after{content:''}
11
+ abbr,acronym{border:0;font-variant:normal}
12
+ legend{color:#000}
13
+ input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit}
14
+ input,button,textarea,select{font-size:100%}
15
+ sup,sub{vertical-align:baseline}
16
+ header, nav, section, article, footer{display:block;}
17
+
18
+ /* -- Global ---------------------------------------------------------------- */
19
+ html{background:#F3F3F3;text-shadow:0px 1px 0px #fff;}
20
+ body{width:760px;margin:40px auto;font:14px/140% 'Helvetica Neue', Arial, Helvetica, Sans-Serif;}
21
+ a{color:#222;}
22
+
23
+ h1, h2, h3, h4, h5, h6{font-weight:bold;}
24
+ h1{font-size:26px;margin-bottom:5px;}
25
+ h1 a{text-decoration:none;}
26
+ h2{font-size:24px;padding-top:10px;margin:30px 0 20px;border-top:2px solid #ccc;}
27
+ h3{font-size:20px;margin-bottom:20px;}
28
+ h4{font-size:18px;margin-bottom:10px;}
29
+ h5, h6{font-size:16px;margin-bottom:5px;}
30
+
31
+ p{margin-bottom:20px;}
32
+ em{font-style:italic;}
33
+ sup{font-size:12px;vertical-align:super;}
34
+ sub{font-size:12px;vertical-align:sub;}
35
+ del{color:#666;font-style:line-through;}
36
+ abbr{border-bottom:1px dotted #bbb;color:#666;text-transform:uppercase;}
37
+ code{background:#eee;padding:2px 5px;font-family:Monospace;}
38
+ small{color:#999;font-size:12px;}
39
+ strong{font-weight:bold;}
40
+ blockquote{color:#666;font-size:16px;margin-left:20px;font-family:Georgia, Serif;}
41
+
42
+ /* code */
43
+ pre{background:#eee;margin-bottom:20px;padding:10px;border:1px solid #ccc;border-width:1px 0;}
44
+
45
+ /* lists */
46
+ ol, ul{margin:0 0 20px 20px;}
47
+ ol li{list-style:decimal inside;}
48
+ ul li{list-style:disc inside;}
49
+
50
+ /* -- Header ---------------------------------------------------------------- */
51
+ header#header {margin-bottom:40px;}
52
+ header#header h1 {font-size:42px;margin-bottom:10px;font-family:Georgia, Serif;font-weight:normal;}
53
+ header#header p {color:#999;}
54
+
55
+ /* -- Content --------------------------------------------------------------- */
56
+ section#content{}
57
+
58
+ section#content section article p{margin-bottom:10px;}
59
+
60
+ section#content article{margin-bottom:40px;}
61
+ section#content article header{overflow:hidden;}
62
+ section#content article header h1{}
63
+ section#content article header img{display:none;}
64
+ section#content article header .meta{color:#999;font-size:12px;}
65
+
66
+ /* -- Footer ---------------------------------------------------------------- */
67
+ footer{margin-bottom:20px;}
@@ -0,0 +1,143 @@
1
+ # Postmarkdown
2
+
3
+ A simple Rails blog engine powered by Markdown.
4
+
5
+ Postmarkdown is compatible with Rails 3 only and the gem is (soon to be) hosted on [RubyGems.org](http://rubygems.org).
6
+
7
+ ## Features
8
+
9
+ * Markdown files for blog posts
10
+ * No database
11
+ * RSS Feed
12
+ * Customizable Routes
13
+ * Built-in minimal theme (optional)
14
+ * HTML5
15
+ * Rails engine (so you can override models, views, controllers, etc)
16
+ * Easily customized
17
+
18
+ ## Installation
19
+
20
+ Simply add Postmarkdown to your Gemfile and bundle it up:
21
+
22
+ gem 'postmarkdown'
23
+
24
+ Then, run the generator to setup Postmarkdown for your application:
25
+
26
+ $ rails generate postmarkdown:install
27
+
28
+ The above command performs the following actions:
29
+
30
+ * Create the directory `app/posts/`. This directory is where your markdown files will live.
31
+ * Generate an example post using today's date, eg. `app/posts/2011-01-01-example-post.markdown`.
32
+ * Add some routes. By default the routes are setup underneath the path `/posts/*`, to customize these routes check out the Customizing Routes section below.
33
+
34
+ ## Usage
35
+
36
+ ### Generate a new Post
37
+
38
+ Here's an example of how to generate a new post using a slug and publish date:
39
+
40
+ $ rails generate postmarkdown:post test-post --date=2011-01-01
41
+
42
+ The above command will create the file `app/posts/2011-01-01-test-post.markdown`, which you can edit and add content to.
43
+
44
+ ### View the Post
45
+
46
+ Open `http://localhost:3000/posts` in your browser and you should be able to navigate to your new post. The URL for your new post is `http://localhost:3000/posts/2011/01/01/test-post`.
47
+
48
+ ## Overriding Files
49
+
50
+ The easiest way to customize the Postmarkdown functionality or appearance is by using the override generator. This generator can copy files from the Postmarkdown core and place them into your Rails app. For example:
51
+
52
+ $ rails generate postmarkdown:override --all # overrides all of the things
53
+ $ rails generate postmarkdown:override --controller # overrides `app/controllers/posts_controller.rb`
54
+ $ rails generate postmarkdown:override --model # overrides `app/models/post.rb`
55
+ $ rails generate postmarkdown:override --views # overrides all files in directory `app/views/posts/`
56
+ $ rails generate postmarkdown:override --theme # overrides the layout and stylesheet
57
+
58
+ ## RSS Feed
59
+
60
+ Postmarkdown comes prepared with a fully functional RSS feed.
61
+
62
+ You can take advantage of the built-in feed by adding the feed link to your HTML head tag. For example, simply add the following to your default layout:
63
+
64
+ <head>
65
+ <!-- include your stylesheets and javascript here... -->
66
+ <%= yield :head %>
67
+ </head>
68
+
69
+ To customize the feed title, add the following to an initializer (`config/initializers/postmarkdown.rb`):
70
+
71
+ Postmarkdown::Config.options[:feed_title] = 'Custom Blog Title Goes Here'
72
+
73
+ To link to the feed in your app, simply use the route helper: `<%= link_to 'RSS Feed', posts_feed_path %>`
74
+
75
+ ## Built-in Theme
76
+
77
+ Postmarkdown comes with minimal built-in theme for your convenience. To turn on the theme, add the following to an initializer (`config/initializers/postmarkdown.rb`):
78
+
79
+ Postmarkdown::Config.options[:use_theme] = true
80
+
81
+ ## Customizing Routes
82
+
83
+ By default Postmarkdown will setup all routes to go through the `/posts/*` path. For example:
84
+
85
+ http://example.com/posts # lists all posts
86
+ http://example.com/posts/2011 # lists all posts from 2011
87
+ http://example.com/posts/2011/01 # lists all posts from January 2011
88
+ http://example.com/posts/2011/01/01 # lists all posts from the 1st of January 2011
89
+ http://example.com/posts/2011/01/01/test-post # show the specified post
90
+
91
+ You can change the default route path by modifying the 'postmarkdown' line in `routes.rb`. For example:
92
+
93
+ postmarkdown :as => :blog
94
+
95
+ This will produce the following routes:
96
+
97
+ http://example.com/blog # lists all posts
98
+ http://example.com/blog/2011 # lists all posts from 2011
99
+ http://example.com/blog/2011/01 # lists all posts from January 2011
100
+ http://example.com/blog/2011/01/01 # lists all posts from the 1st of January 2011
101
+ http://example.com/blog/2011/01/01/test-post # show the specified post
102
+
103
+ You can also customize the `posts#show` route via the `:permalink_format` option:
104
+
105
+ postmarkdown :as => :blog, :permalink_format => :day # URL: http://example.com/blog/2011/01/01/test-post
106
+ postmarkdown :as => :blog, :permalink_format => :month # URL: http://example.com/blog/2011/01/test-post
107
+ postmarkdown :as => :blog, :permalink_format => :year # URL: http://example.com/blog/2011/test-post
108
+ postmarkdown :as => :blog, :permalink_format => :slug # URL: http://example.com/blog/test-post
109
+
110
+ What about mapping Postmarkdown to root? We got you covered:
111
+
112
+ postmarkdown :as => ''
113
+ root :to => 'posts#index'
114
+
115
+ ## Example Directory Structure
116
+
117
+ ├── app
118
+ │   ├── controllers
119
+ │   ├── helpers
120
+ │   ├── mailers
121
+ │   ├── models
122
+ │   ├── posts (where your markdown files live)
123
+ │   │   ├── 2011-04-01-example-1.markdown
124
+ │   │   ├── 2011-04-02-example-2.markdown
125
+ │   │   ├── 2011-04-03-example-3.markdown
126
+ │   │   ├── 2011-04-04-example-4.markdown
127
+ │   └── views
128
+ │   └── posts (overridable)
129
+ │   ├── _feed_link.html.haml
130
+ │   ├── _post.html.haml
131
+ │   ├── feed.xml.builder
132
+ │   ├── index.html.haml
133
+ │   └── show.html.haml
134
+
135
+ ## TODO
136
+
137
+ * Syntax highlighting for code blocks
138
+ * Generated routes should show example usage
139
+ * Support more file formats, eg. textile
140
+
141
+ ## License
142
+
143
+ MIT License. Copyright 2011 Ennova.
@@ -0,0 +1,167 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Post views', :type => :request do
4
+ before do
5
+ time_travel_to '2011-05-01'
6
+ Post.reset!
7
+ end
8
+
9
+ after { back_to_the_present }
10
+
11
+ context 'Posts#index' do
12
+ before { visit posts_path }
13
+
14
+ it 'should show published posts' do
15
+ # 2011-05-01-full-metadata (published today)
16
+ page.should have_content('Post with full metadata') # title
17
+ page.should have_content('Posted on 1 May 2011') # publish date
18
+ page.should have_content('by John Smith') # author
19
+ page.should have_content('This is another custom & test summary.') # summary
20
+
21
+ # 2011-04-28-summary
22
+ page.should have_content('A Test Post') # title
23
+ page.should have_content('Posted on 28 April 2011') # publish date
24
+ page.should have_content('This is a custom & test summary.') # summary
25
+
26
+ # 2011-04-28-image
27
+ page.should have_content('Image') # title
28
+ page.should have_content('Posted on 28 April 2011') # publish date
29
+ page.should have_content('Image description.') # summary
30
+
31
+ # 2011-04-01-first-post
32
+ page.should have_content('First Post') # title
33
+ page.should have_content('Posted on 1 April 2011') # publish date
34
+ page.should have_content('Lorem ipsum dolor sit amet') # part of summary
35
+ end
36
+
37
+ it 'should not show unpublished posts' do
38
+ # 2015-02-13-custom-title (not published yet)
39
+ page.should_not have_content('This is a custom title') # title
40
+ page.should_not have_content('Content goes here.') # summary
41
+ end
42
+
43
+ it 'should have the correct number of posts' do
44
+ all('section#posts article.post').size.should == 4
45
+ end
46
+ end
47
+
48
+ context 'Posts#index with no posts' do
49
+ it 'should show a message' do
50
+ time_travel_to '2010-05-01'
51
+ visit posts_path
52
+
53
+ page.should have_content('No posts found.')
54
+ page.should_not have_content('First Post')
55
+ end
56
+ end
57
+
58
+ context 'Posts#index with year' do
59
+ before { visit posts_path(:year => '2011') }
60
+
61
+ it 'should show posts inside the date range' do
62
+ page.should have_content('Post with full metadata')
63
+ page.should have_content('A Test Post')
64
+ page.should have_content('Image')
65
+ page.should have_content('First Post')
66
+ end
67
+ end
68
+
69
+ context 'Posts#index with year and month' do
70
+ before { visit posts_path(:year => '2011', :month => '04') }
71
+
72
+ it 'should show posts inside the date range' do
73
+ page.should have_content('A Test Post')
74
+ page.should have_content('Image')
75
+ page.should have_content('First Post')
76
+ end
77
+
78
+ it 'should not show posts outside the date range' do
79
+ page.should_not have_content('Post with full metadata')
80
+ end
81
+ end
82
+
83
+ context 'Posts#index with year, month and day' do
84
+ before { visit posts_path(:year => '2011', :month => '04', :day => '01') }
85
+
86
+ it 'should show posts inside the date range' do
87
+ page.should have_content('First Post')
88
+ end
89
+
90
+ it 'should not show posts outside the date range' do
91
+ page.should_not have_content('A Test Post')
92
+ page.should_not have_content('Image')
93
+ page.should_not have_content('Post with full metadata')
94
+ end
95
+ end
96
+
97
+ context 'Posts#show' do
98
+ before { visit post_path('2011/05/01/full-metadata') }
99
+
100
+ it 'should have content' do
101
+ page.should have_content('Post with full metadata') # title
102
+ page.should have_content('Posted on 1 May 2011') # publish date
103
+ page.should have_content('by John Smith') # author
104
+
105
+ # body
106
+ page.should have_content('First paragraph of content.')
107
+ page.should have_content('Second paragraph of content.')
108
+ end
109
+
110
+ it 'should not show the summary' do
111
+ page.should_not have_content('This is another custom & test summary.')
112
+ end
113
+
114
+ it 'should preserve whitespace on code blocks' do
115
+ page.source.should match '<pre><code>First line of code.&#x000A; Second line of code.&#x000A;</code></pre>'
116
+ end
117
+ end
118
+
119
+ context 'Posts#feed' do
120
+ before { visit posts_feed_path }
121
+
122
+ it 'should be xml format type' do
123
+ page.response_headers['Content-Type'].should == 'application/atom+xml; charset=utf-8'
124
+ end
125
+
126
+ it 'should be valid xml' do
127
+ lambda do
128
+ Nokogiri::XML::Reader(page.source)
129
+ end.should_not raise_error
130
+ end
131
+
132
+ it 'should contain the correct number of entries' do
133
+ Nokogiri::XML(page.source).search('entry').size.should == 4
134
+ end
135
+
136
+ it 'should contain an entry that is properly constructed' do
137
+ entry = Nokogiri::XML(page.source).search('entry').first
138
+
139
+ entry.search('title').text.should == 'Post with full metadata'
140
+ entry.search('author').first.search('name').text.should == 'John Smith'
141
+ entry.search('author').first.search('email').text.should == 'john.smith@example.com'
142
+ entry.search('published').text.should == '2011-05-01T00:00:00Z'
143
+ entry.search('content').text == "\n <p>First paragraph of content.</p>\n\n<p>Second paragraph of content.</p>\n\n "
144
+ end
145
+ end
146
+
147
+ context 'Posts#show with invalid slug' do
148
+ it 'should raise an not found exception' do
149
+ lambda do
150
+ visit post_path('2011/05/01/invalid')
151
+ end.should raise_error(ActiveRecord::RecordNotFound)
152
+ end
153
+ end
154
+
155
+ context 'theme' do
156
+ it 'should not use the built-in layout by default' do
157
+ visit posts_path
158
+ page.should_not have_content('A postmarkdown blog')
159
+ end
160
+
161
+ it 'should use the built-in layout when the global option is set' do
162
+ Postmarkdown::Config.options[:use_theme] = true
163
+ visit posts_path
164
+ page.should have_content('A postmarkdown blog')
165
+ end
166
+ end
167
+ end