doculab 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +133 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.rdoc +3 -0
  6. data/Rakefile +74 -0
  7. data/VERSION +1 -0
  8. data/app/controllers/doculab/docs_controller.rb +50 -0
  9. data/app/helpers/doculab/docs_helper.rb +15 -0
  10. data/app/helpers/doculab/table_of_contents_helper.rb +34 -0
  11. data/app/models/doculab/doc.rb +61 -0
  12. data/app/models/doculab/table_of_contents.rb +88 -0
  13. data/app/sweepers/doculab/cache_sweeper.rb +17 -0
  14. data/config/cucumber.yml +8 -0
  15. data/config/rails_template.rb +0 -0
  16. data/config/routes.rb +6 -0
  17. data/doculab.gemspec +145 -0
  18. data/features/step_definitions/doc_steps.rb +16 -0
  19. data/features/step_definitions/web_steps.rb +219 -0
  20. data/features/support/env.rb +34 -0
  21. data/features/support/paths.rb +28 -0
  22. data/features/viewing_docs.feature +10 -0
  23. data/lib/doculab/engine.rb +43 -0
  24. data/lib/doculab.rb +53 -0
  25. data/lib/tasks/doculab.rake +15 -0
  26. data/spec/controllers/docs_controller_spec.rb +62 -0
  27. data/spec/dummy/Rakefile +7 -0
  28. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  29. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  30. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/spec/dummy/config/application.rb +45 -0
  32. data/spec/dummy/config/boot.rb +10 -0
  33. data/spec/dummy/config/database.yml +22 -0
  34. data/spec/dummy/config/environment.rb +5 -0
  35. data/spec/dummy/config/environments/development.rb +22 -0
  36. data/spec/dummy/config/environments/production.rb +49 -0
  37. data/spec/dummy/config/environments/test.rb +35 -0
  38. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  39. data/spec/dummy/config/initializers/doculab.rb +1 -0
  40. data/spec/dummy/config/initializers/inflections.rb +10 -0
  41. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  42. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  43. data/spec/dummy/config/initializers/session_store.rb +8 -0
  44. data/spec/dummy/config/locales/en.yml +5 -0
  45. data/spec/dummy/config/routes.rb +58 -0
  46. data/spec/dummy/config.ru +4 -0
  47. data/spec/dummy/doculab/docs/overview.textile +1 -0
  48. data/spec/dummy/doculab/layouts/custom.html.erb +17 -0
  49. data/spec/dummy/doculab/layouts/docs.html.erb +17 -0
  50. data/spec/dummy/public/404.html +26 -0
  51. data/spec/dummy/public/422.html +26 -0
  52. data/spec/dummy/public/500.html +26 -0
  53. data/spec/dummy/public/favicon.ico +0 -0
  54. data/spec/dummy/public/javascripts/application.js +2 -0
  55. data/spec/dummy/public/javascripts/controls.js +965 -0
  56. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  57. data/spec/dummy/public/javascripts/effects.js +1123 -0
  58. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  59. data/spec/dummy/public/javascripts/rails.js +175 -0
  60. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  61. data/spec/dummy/script/rails +6 -0
  62. data/spec/integration/navigation_spec.rb +9 -0
  63. data/spec/models/doc_spec.rb +47 -0
  64. data/spec/spec_helper.rb +58 -0
  65. metadata +265 -0
data/doculab.gemspec ADDED
@@ -0,0 +1,145 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{doculab}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Klett"]
12
+ s.date = %q{2010-08-18}
13
+ s.description = %q{A Rails Engine for a simple file-based CMS, suitable for a documentation site. Originally created to power the Chargify documentation at http://docs.chargify.com}
14
+ s.email = %q{michael@webadvocate.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "MIT-LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "app/controllers/doculab/docs_controller.rb",
27
+ "app/helpers/doculab/docs_helper.rb",
28
+ "app/helpers/doculab/table_of_contents_helper.rb",
29
+ "app/models/doculab/doc.rb",
30
+ "app/models/doculab/table_of_contents.rb",
31
+ "app/sweepers/doculab/cache_sweeper.rb",
32
+ "config/cucumber.yml",
33
+ "config/rails_template.rb",
34
+ "config/routes.rb",
35
+ "doculab.gemspec",
36
+ "features/step_definitions/doc_steps.rb",
37
+ "features/step_definitions/web_steps.rb",
38
+ "features/support/env.rb",
39
+ "features/support/paths.rb",
40
+ "features/viewing_docs.feature",
41
+ "lib/doculab.rb",
42
+ "lib/doculab/engine.rb",
43
+ "lib/tasks/doculab.rake",
44
+ "spec/controllers/docs_controller_spec.rb",
45
+ "spec/dummy/Rakefile",
46
+ "spec/dummy/app/controllers/application_controller.rb",
47
+ "spec/dummy/app/helpers/application_helper.rb",
48
+ "spec/dummy/app/views/layouts/application.html.erb",
49
+ "spec/dummy/config.ru",
50
+ "spec/dummy/config/application.rb",
51
+ "spec/dummy/config/boot.rb",
52
+ "spec/dummy/config/database.yml",
53
+ "spec/dummy/config/environment.rb",
54
+ "spec/dummy/config/environments/development.rb",
55
+ "spec/dummy/config/environments/production.rb",
56
+ "spec/dummy/config/environments/test.rb",
57
+ "spec/dummy/config/initializers/backtrace_silencers.rb",
58
+ "spec/dummy/config/initializers/doculab.rb",
59
+ "spec/dummy/config/initializers/inflections.rb",
60
+ "spec/dummy/config/initializers/mime_types.rb",
61
+ "spec/dummy/config/initializers/secret_token.rb",
62
+ "spec/dummy/config/initializers/session_store.rb",
63
+ "spec/dummy/config/locales/en.yml",
64
+ "spec/dummy/config/routes.rb",
65
+ "spec/dummy/doculab/docs/overview.textile",
66
+ "spec/dummy/doculab/layouts/custom.html.erb",
67
+ "spec/dummy/doculab/layouts/docs.html.erb",
68
+ "spec/dummy/public/404.html",
69
+ "spec/dummy/public/422.html",
70
+ "spec/dummy/public/500.html",
71
+ "spec/dummy/public/favicon.ico",
72
+ "spec/dummy/public/javascripts/application.js",
73
+ "spec/dummy/public/javascripts/controls.js",
74
+ "spec/dummy/public/javascripts/dragdrop.js",
75
+ "spec/dummy/public/javascripts/effects.js",
76
+ "spec/dummy/public/javascripts/prototype.js",
77
+ "spec/dummy/public/javascripts/rails.js",
78
+ "spec/dummy/public/stylesheets/.gitkeep",
79
+ "spec/dummy/script/rails",
80
+ "spec/integration/navigation_spec.rb",
81
+ "spec/models/doc_spec.rb",
82
+ "spec/spec_helper.rb"
83
+ ]
84
+ s.homepage = %q{http://github.com/grasshopperlabs/doculab}
85
+ s.rdoc_options = ["--charset=UTF-8"]
86
+ s.require_paths = ["lib"]
87
+ s.rubygems_version = %q{1.3.7}
88
+ s.summary = %q{A Rails Engine for creating a simple documentation site}
89
+ s.test_files = [
90
+ "spec/controllers/docs_controller_spec.rb",
91
+ "spec/dummy/app/controllers/application_controller.rb",
92
+ "spec/dummy/app/helpers/application_helper.rb",
93
+ "spec/dummy/config/application.rb",
94
+ "spec/dummy/config/boot.rb",
95
+ "spec/dummy/config/environment.rb",
96
+ "spec/dummy/config/environments/development.rb",
97
+ "spec/dummy/config/environments/production.rb",
98
+ "spec/dummy/config/environments/test.rb",
99
+ "spec/dummy/config/initializers/backtrace_silencers.rb",
100
+ "spec/dummy/config/initializers/doculab.rb",
101
+ "spec/dummy/config/initializers/inflections.rb",
102
+ "spec/dummy/config/initializers/mime_types.rb",
103
+ "spec/dummy/config/initializers/secret_token.rb",
104
+ "spec/dummy/config/initializers/session_store.rb",
105
+ "spec/dummy/config/routes.rb",
106
+ "spec/integration/navigation_spec.rb",
107
+ "spec/models/doc_spec.rb",
108
+ "spec/spec_helper.rb"
109
+ ]
110
+
111
+ if s.respond_to? :specification_version then
112
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
113
+ s.specification_version = 3
114
+
115
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
116
+ s.add_runtime_dependency(%q<tilt>, [">= 0"])
117
+ s.add_runtime_dependency(%q<RedCloth>, [">= 0"])
118
+ s.add_development_dependency(%q<rails>, [">= 3.0.0.rc"])
119
+ s.add_development_dependency(%q<rspec-rails>, [">= 2.0.0.beta"])
120
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
121
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
122
+ s.add_development_dependency(%q<cucumber-rails>, [">= 0"])
123
+ s.add_development_dependency(%q<capybara>, [">= 0"])
124
+ else
125
+ s.add_dependency(%q<tilt>, [">= 0"])
126
+ s.add_dependency(%q<RedCloth>, [">= 0"])
127
+ s.add_dependency(%q<rails>, [">= 3.0.0.rc"])
128
+ s.add_dependency(%q<rspec-rails>, [">= 2.0.0.beta"])
129
+ s.add_dependency(%q<jeweler>, [">= 0"])
130
+ s.add_dependency(%q<cucumber>, [">= 0"])
131
+ s.add_dependency(%q<cucumber-rails>, [">= 0"])
132
+ s.add_dependency(%q<capybara>, [">= 0"])
133
+ end
134
+ else
135
+ s.add_dependency(%q<tilt>, [">= 0"])
136
+ s.add_dependency(%q<RedCloth>, [">= 0"])
137
+ s.add_dependency(%q<rails>, [">= 3.0.0.rc"])
138
+ s.add_dependency(%q<rspec-rails>, [">= 2.0.0.beta"])
139
+ s.add_dependency(%q<jeweler>, [">= 0"])
140
+ s.add_dependency(%q<cucumber>, [">= 0"])
141
+ s.add_dependency(%q<cucumber-rails>, [">= 0"])
142
+ s.add_dependency(%q<capybara>, [">= 0"])
143
+ end
144
+ end
145
+
@@ -0,0 +1,16 @@
1
+ Given /^there is a valid doc file$/ do
2
+ if filename = first_existing_doc_filename
3
+ permalink = filename.split(".").first
4
+ else
5
+ permalink = nil
6
+ end
7
+ @doc = Doculab::Doc.find(permalink)
8
+ end
9
+
10
+ Then /^I should see the doc content$/ do
11
+ Then %{I should see "#{@doc.content}"}
12
+ end
13
+
14
+ def first_existing_doc_filename
15
+ Doculab::Doc.filenames.first
16
+ end
@@ -0,0 +1,219 @@
1
+ # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
2
+ # It is recommended to regenerate this file in the future when you upgrade to a
3
+ # newer version of cucumber-rails. Consider adding your own code to a new file
4
+ # instead of editing this one. Cucumber will automatically load all features/**/*.rb
5
+ # files.
6
+
7
+
8
+ require 'uri'
9
+ require 'cgi'
10
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
11
+
12
+ module WithinHelpers
13
+ def with_scope(locator)
14
+ locator ? within(locator) { yield } : yield
15
+ end
16
+ end
17
+ World(WithinHelpers)
18
+
19
+ Given /^(?:|I )am on (.+)$/ do |page_name|
20
+ visit path_to(page_name)
21
+ end
22
+
23
+ When /^(?:|I )go to (.+)$/ do |page_name|
24
+ visit path_to(page_name)
25
+ end
26
+
27
+ When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector|
28
+ with_scope(selector) do
29
+ click_button(button)
30
+ end
31
+ end
32
+
33
+ When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector|
34
+ with_scope(selector) do
35
+ click_link(link)
36
+ end
37
+ end
38
+
39
+ When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field, value, selector|
40
+ with_scope(selector) do
41
+ fill_in(field, :with => value)
42
+ end
43
+ end
44
+
45
+ When /^(?:|I )fill in "([^"]*)" for "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
46
+ with_scope(selector) do
47
+ fill_in(field, :with => value)
48
+ end
49
+ end
50
+
51
+ # Use this to fill in an entire form with data from a table. Example:
52
+ #
53
+ # When I fill in the following:
54
+ # | Account Number | 5002 |
55
+ # | Expiry date | 2009-11-01 |
56
+ # | Note | Nice guy |
57
+ # | Wants Email? | |
58
+ #
59
+ # TODO: Add support for checkbox, select og option
60
+ # based on naming conventions.
61
+ #
62
+ When /^(?:|I )fill in the following(?: within "([^"]*)")?:$/ do |selector, fields|
63
+ with_scope(selector) do
64
+ fields.rows_hash.each do |name, value|
65
+ When %{I fill in "#{name}" with "#{value}"}
66
+ end
67
+ end
68
+ end
69
+
70
+ When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
71
+ with_scope(selector) do
72
+ select(value, :from => field)
73
+ end
74
+ end
75
+
76
+ When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
77
+ with_scope(selector) do
78
+ check(field)
79
+ end
80
+ end
81
+
82
+ When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
83
+ with_scope(selector) do
84
+ uncheck(field)
85
+ end
86
+ end
87
+
88
+ When /^(?:|I )choose "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
89
+ with_scope(selector) do
90
+ choose(field)
91
+ end
92
+ end
93
+
94
+ When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector|
95
+ with_scope(selector) do
96
+ attach_file(field, path)
97
+ end
98
+ end
99
+
100
+ Then /^(?:|I )should see JSON:$/ do |expected_json|
101
+ require 'json'
102
+ expected = JSON.pretty_generate(JSON.parse(expected_json))
103
+ actual = JSON.pretty_generate(JSON.parse(response.body))
104
+ expected.should == actual
105
+ end
106
+
107
+ Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
108
+ with_scope(selector) do
109
+ if page.respond_to? :should
110
+ page.should have_content(text)
111
+ else
112
+ assert page.has_content?(text)
113
+ end
114
+ end
115
+ end
116
+
117
+ Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
118
+ regexp = Regexp.new(regexp)
119
+ with_scope(selector) do
120
+ if page.respond_to? :should
121
+ page.should have_xpath('//*', :text => regexp)
122
+ else
123
+ assert page.has_xpath?('//*', :text => regexp)
124
+ end
125
+ end
126
+ end
127
+
128
+ Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
129
+ with_scope(selector) do
130
+ if page.respond_to? :should
131
+ page.should have_no_content(text)
132
+ else
133
+ assert page.has_no_content?(text)
134
+ end
135
+ end
136
+ end
137
+
138
+ Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
139
+ regexp = Regexp.new(regexp)
140
+ with_scope(selector) do
141
+ if page.respond_to? :should
142
+ page.should have_no_xpath('//*', :text => regexp)
143
+ else
144
+ assert page.has_no_xpath?('//*', :text => regexp)
145
+ end
146
+ end
147
+ end
148
+
149
+ Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |field, selector, value|
150
+ with_scope(selector) do
151
+ field = find_field(field)
152
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
153
+ if field_value.respond_to? :should
154
+ field_value.should =~ /#{value}/
155
+ else
156
+ assert_match(/#{value}/, field_value)
157
+ end
158
+ end
159
+ end
160
+
161
+ Then /^the "([^"]*)" field(?: within "([^"]*)")? should not contain "([^"]*)"$/ do |field, selector, value|
162
+ with_scope(selector) do
163
+ field = find_field(field)
164
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
165
+ if field_value.respond_to? :should_not
166
+ field_value.should_not =~ /#{value}/
167
+ else
168
+ assert_no_match(/#{value}/, field_value)
169
+ end
170
+ end
171
+ end
172
+
173
+ Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be checked$/ do |label, selector|
174
+ with_scope(selector) do
175
+ field_checked = find_field(label)['checked']
176
+ if field_checked.respond_to? :should
177
+ field_checked.should be_true
178
+ else
179
+ assert field_checked
180
+ end
181
+ end
182
+ end
183
+
184
+ Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector|
185
+ with_scope(selector) do
186
+ field_checked = find_field(label)['checked']
187
+ if field_checked.respond_to? :should
188
+ field_checked.should be_false
189
+ else
190
+ assert !field_checked
191
+ end
192
+ end
193
+ end
194
+
195
+ Then /^(?:|I )should be on (.+)$/ do |page_name|
196
+ current_path = URI.parse(current_url).path
197
+ if current_path.respond_to? :should
198
+ current_path.should == path_to(page_name)
199
+ else
200
+ assert_equal path_to(page_name), current_path
201
+ end
202
+ end
203
+
204
+ Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
205
+ query = URI.parse(current_url).query
206
+ actual_params = query ? CGI.parse(query) : {}
207
+ expected_params = {}
208
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
209
+
210
+ if actual_params.respond_to? :should
211
+ actual_params.should == expected_params
212
+ else
213
+ assert_equal expected_params, actual_params
214
+ end
215
+ end
216
+
217
+ Then /^show me the page$/ do
218
+ save_and_open_page
219
+ end
@@ -0,0 +1,34 @@
1
+ # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
2
+ # It is recommended to regenerate this file in the future when you upgrade to a
3
+ # newer version of cucumber-rails. Consider adding your own code to a new file
4
+ # instead of editing this one. Cucumber will automatically load all features/**/*.rb
5
+ # files.
6
+
7
+ ENV["RAILS_ENV"] ||= "test"
8
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec/dummy/config/environment')
9
+
10
+ require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
11
+ require 'cucumber/rails/rspec'
12
+ require 'cucumber/rails/world'
13
+ require 'cucumber/web/tableish'
14
+
15
+ require 'capybara/rails'
16
+ require 'capybara/cucumber'
17
+ require 'capybara/session'
18
+ require 'cucumber/rails/capybara_javascript_emulation' # Lets you click links with onclick javascript handlers without using @culerity or @javascript
19
+ # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
20
+ # order to ease the transition to Capybara we set the default here. If you'd
21
+ # prefer to use XPath just remove this line and adjust any selectors in your
22
+ # steps to use the XPath syntax.
23
+ Capybara.default_selector = :css
24
+
25
+ # If you set this to false, any error raised from within your app will bubble
26
+ # up to your step definition and out to cucumber unless you catch it somewhere
27
+ # on the way. You can make Rails rescue errors and render error pages on a
28
+ # per-scenario basis by tagging a scenario or feature with the @allow-rescue tag.
29
+ #
30
+ # If you set this to true, Rails will rescue all errors and render error
31
+ # pages, more or less in the same way your application would behave in the
32
+ # default production environment. It's not recommended to do this for all
33
+ # of your scenarios, as this makes it hard to discover errors in your application.
34
+ ActionController::Base.allow_rescue = false
@@ -0,0 +1,28 @@
1
+ module NavigationHelpers
2
+ # Maps a name to a path. Used by the
3
+ #
4
+ # When /^I go to (.+)$/ do |page_name|
5
+ #
6
+ # step definition in web_steps.rb
7
+ #
8
+ def path_to(page_name)
9
+ case page_name
10
+
11
+ when /the home\s?page/
12
+ '/'
13
+ when /the doculab doc/
14
+ doculab_doc_path(@doc.permalink)
15
+ else
16
+ begin
17
+ page_name =~ /the (.*) page/
18
+ path_components = $1.split(/\s+/)
19
+ self.send(path_components.push('path').join('_').to_sym)
20
+ rescue Object => e
21
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
22
+ "Now, go and add a mapping in #{__FILE__}"
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ World(NavigationHelpers)
@@ -0,0 +1,10 @@
1
+ Feature: Viewing document pages
2
+
3
+ In order to be enlightened
4
+ As a website visitor
5
+ I want to view document pages
6
+
7
+ Scenario: View an existing document page written in textile
8
+ Given there is a valid doc file
9
+ When I go to the doculab doc
10
+ Then I should see the doc content
@@ -0,0 +1,43 @@
1
+ class Engine < Rails::Engine
2
+ initializer "doculab.add_view_paths", :before => :add_view_paths do |app|
3
+ app.config.paths.app.views << Rails.root.join("doculab").to_s
4
+ end
5
+
6
+ initializer "doculab.table_of_contents_preparation", :before => :add_to_prepare_blocks do |app|
7
+ app.config.to_prepare do
8
+ table_of_contents = Engine.table_of_contents_path
9
+ begin
10
+ load table_of_contents
11
+ rescue LoadError
12
+ Doculab::TableOfContents.define do; end
13
+ if %w(production development).include?(Rails.env)
14
+ Engine.print_warning(:table_of_contents)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ initializer "doculab.sweep_cache" do |app|
21
+ Doculab::CacheSweeper.sweep!
22
+ end
23
+
24
+ def self.table_of_contents_path
25
+ Rails.root.join("doculab", "meta", "table_of_contents.rb").to_s
26
+ end
27
+
28
+ def self.print_warning(message_key)
29
+ message = case message_key
30
+ when :table_of_contents
31
+ "There is no Table of Contents defined at #{table_of_contents_path}"
32
+ else
33
+ nil
34
+ end
35
+
36
+ if message.present?
37
+ message = "=> Doculab WARNING: #{message}"
38
+ puts message
39
+ Rails.logger.info message
40
+ end
41
+ end
42
+
43
+ end
data/lib/doculab.rb ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.setup
5
+ Bundler.require
6
+ require 'doculab/engine'
7
+
8
+ module Doculab
9
+ # What are you documenting?
10
+ mattr_accessor :project_name
11
+
12
+ # Documentation title, used on the index page and in the <title> tag.
13
+ # Default is "#{project_name} Documentation"
14
+ #
15
+ # Set this in your configuration via:
16
+ #
17
+ # Doculab.title = "Super Amazing Documentation"
18
+ mattr_writer :title
19
+ def self.title
20
+ @@title ||= [Doculab.project_name, "Documentation"].reject(&:blank?).join(' ')
21
+ end
22
+
23
+ # Normally, routes for Doculab are set up based off of "root":
24
+ #
25
+ # http://docs.example.com/ # => Renders the index doc
26
+ # http://docs.example.com/overview # => Renders the "overview" doc
27
+ #
28
+ # Setting the route base can put Doculab routes in a "sub-directory":
29
+ #
30
+ # Doculab.route_base = "my-docs"
31
+ #
32
+ # http://docs.example.com/my-docs/ # => Renders the index page
33
+ # http://docs.example.com/my-docs/overview # => Renders the "overview" doc
34
+ mattr_accessor :route_base
35
+
36
+ # Define the layout to use for your "main layout", as found in the doculab/layouts directory.
37
+ # Defaults to "docs" (which equates to docs.html.erb)
38
+ mattr_writer :main_layout
39
+ def self.main_layout
40
+ @@main_layout ||= 'docs'
41
+ end
42
+
43
+ # You may optionally define a separate layout for the index page. One use for this is to
44
+ # create a richer homepage with search boxes and cool stuff that's harder to do in
45
+ # index.textile.
46
+ #
47
+ # Consider making this "nested layout" as described in
48
+ # http://edgeguides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts
49
+ mattr_writer :index_layout
50
+ def self.index_layout
51
+ @@index_layout ||= main_layout
52
+ end
53
+ end
@@ -0,0 +1,15 @@
1
+ namespace :doculab do
2
+ desc "Bootstrap a doculab directory within your project"
3
+ task :bootstrap do
4
+ puts "Hello Bootstrap!"
5
+ end
6
+
7
+ desc "Generate blank doc files for all pages defined in the Table of Contents which do not yet exist"
8
+ task :skeleton => :environment do
9
+ Doculab::TableOfContents.pages.each do |page|
10
+ unless File.exist?(page.filename)
11
+ FileUtils.touch(page.filename)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Doculab::DocsController do
4
+ describe "layout selection" do
5
+ before(:each) do
6
+ reset_layouts!
7
+ end
8
+
9
+ after(:each) do
10
+ reset_layouts!
11
+ end
12
+
13
+ context "with the default layouts" do
14
+ it "uses the 'docs' layout for the index page" do
15
+ get :index
16
+ controller.send(:_layout).should == 'docs'
17
+ end
18
+
19
+ it "uses the 'docs' layout for a doc page" do
20
+ get :show, :permalink => good_permalink
21
+ controller.send(:_layout).should == 'docs'
22
+ end
23
+ end
24
+
25
+ context "with a custom main_layout" do
26
+ before(:each) do
27
+ Doculab.main_layout = 'custom'
28
+ end
29
+
30
+ it "uses the 'custom' layout for the index page" do
31
+ get :index
32
+ controller.send(:_layout).should == 'custom'
33
+ end
34
+
35
+ it "uses the 'custom' layout for a doc page" do
36
+ get :show, :permalink => good_permalink
37
+ controller.send(:_layout).should == 'custom'
38
+ end
39
+ end
40
+
41
+ context "with a custom index_layout" do
42
+ before(:each) do
43
+ Doculab.index_layout = 'custom'
44
+ end
45
+
46
+ it "uses the 'custom' layout for the index page" do
47
+ get :index
48
+ controller.send(:_layout).should == 'custom'
49
+ end
50
+
51
+ it "uses the 'docs' layout for a doc page" do
52
+ get :show, :permalink => good_permalink
53
+ controller.send(:_layout).should == 'docs'
54
+ end
55
+ end
56
+
57
+ def reset_layouts!
58
+ Doculab.main_layout = nil
59
+ Doculab.index_layout = nil
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,7 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+ require 'rake'
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag :all %>
6
+ <%= javascript_include_tag :defaults %>
7
+ <%= csrf_meta_tag %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>