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.
- data/.gitignore +6 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +133 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +74 -0
- data/VERSION +1 -0
- data/app/controllers/doculab/docs_controller.rb +50 -0
- data/app/helpers/doculab/docs_helper.rb +15 -0
- data/app/helpers/doculab/table_of_contents_helper.rb +34 -0
- data/app/models/doculab/doc.rb +61 -0
- data/app/models/doculab/table_of_contents.rb +88 -0
- data/app/sweepers/doculab/cache_sweeper.rb +17 -0
- data/config/cucumber.yml +8 -0
- data/config/rails_template.rb +0 -0
- data/config/routes.rb +6 -0
- data/doculab.gemspec +145 -0
- data/features/step_definitions/doc_steps.rb +16 -0
- data/features/step_definitions/web_steps.rb +219 -0
- data/features/support/env.rb +34 -0
- data/features/support/paths.rb +28 -0
- data/features/viewing_docs.feature +10 -0
- data/lib/doculab/engine.rb +43 -0
- data/lib/doculab.rb +53 -0
- data/lib/tasks/doculab.rake +15 -0
- data/spec/controllers/docs_controller_spec.rb +62 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +22 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/doculab.rb +1 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/doculab/docs/overview.textile +1 -0
- data/spec/dummy/doculab/layouts/custom.html.erb +17 -0
- data/spec/dummy/doculab/layouts/docs.html.erb +17 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +175 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/models/doc_spec.rb +47 -0
- data/spec/spec_helper.rb +58 -0
- 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
|
data/spec/dummy/Rakefile
ADDED
@@ -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
|