doculab 0.1.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.
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>