Line ending cleanup. Most of these are svn propsets which should make
the files check out appropriately in the future. The three files in app/models had inconsitent line endings, so they had to be fixed by hand.
This commit is contained in:
parent
4849ca62fb
commit
b29c59e470
14 changed files with 1578 additions and 1578 deletions
372
CHANGELOG
372
CHANGELOG
|
@ -1,186 +1,186 @@
|
||||||
* 0.10.2:
|
* 0.10.2:
|
||||||
Upgraded to Rails 0.13.1
|
Upgraded to Rails 0.13.1
|
||||||
Fixed HTML export
|
Fixed HTML export
|
||||||
Added layout=no option to the export_html action (it exports page contents processed
|
Added layout=no option to the export_html action (it exports page contents processed
|
||||||
by the markup engine, but without the default layout - so that they can be wrapped in
|
by the markup engine, but without the default layout - so that they can be wrapped in
|
||||||
some other layout)
|
some other layout)
|
||||||
<nowiki> tag can span several lines (before it was applied when both opening and closing
|
<nowiki> tag can span several lines (before it was applied when both opening and closing
|
||||||
tags were on the same line only)
|
tags were on the same line only)
|
||||||
Resolved the "endless redirection loop" condition and otherwise improved handling of
|
Resolved the "endless redirection loop" condition and otherwise improved handling of
|
||||||
errors in the rendering engines
|
errors in the rendering engines
|
||||||
Fixed rendering of Markdown hyperlinks such as [Text](http://something.com/foo)
|
Fixed rendering of Markdown hyperlinks such as [Text](http://something.com/foo)
|
||||||
|
|
||||||
* 0.10.1:
|
* 0.10.1:
|
||||||
Upgraded Rails to 0.12.0
|
Upgraded Rails to 0.12.0
|
||||||
Upgraded rubyzip to version 0.5.8
|
Upgraded rubyzip to version 0.5.8
|
||||||
BlueCloth is back (RedCloth didn't do pure Markdown well enough)
|
BlueCloth is back (RedCloth didn't do pure Markdown well enough)
|
||||||
Handling of line breaks in Textile is as in 0.9 (inserts <br/> tag)
|
Handling of line breaks in Textile is as in 0.9 (inserts <br/> tag)
|
||||||
Fixed HTML export (to enclose the output in <html> tags, include the stylesheet etc)
|
Fixed HTML export (to enclose the output in <html> tags, include the stylesheet etc)
|
||||||
Corrected some compatibility issues with storages from earlier Instiki versions
|
Corrected some compatibility issues with storages from earlier Instiki versions
|
||||||
Some other bug fixes
|
Some other bug fixes
|
||||||
|
|
||||||
* 0.10.0:
|
* 0.10.0:
|
||||||
Ported to ActionPack
|
Ported to ActionPack
|
||||||
RedCloth 3.0.3
|
RedCloth 3.0.3
|
||||||
BlueCloth is phased out, Markdown is rendered by RedCloth
|
BlueCloth is phased out, Markdown is rendered by RedCloth
|
||||||
Mix markup option understands both Textile and Markdown on the same page
|
Mix markup option understands both Textile and Markdown on the same page
|
||||||
Instiki can serve static content (such as HTML or plain-text files) from ./public
|
Instiki can serve static content (such as HTML or plain-text files) from ./public
|
||||||
directory
|
directory
|
||||||
Much friendlier admin interface
|
Much friendlier admin interface
|
||||||
Wiki link syntax doesn't conflict with Textile hyperlink syntax. Therefore
|
Wiki link syntax doesn't conflict with Textile hyperlink syntax. Therefore
|
||||||
"textile link":LinkToSomePlace will not look insane.
|
"textile link":LinkToSomePlace will not look insane.
|
||||||
RSS feeds accept query parameters, sush as
|
RSS feeds accept query parameters, sush as
|
||||||
http://localhost:2500/wiki/rss_with_headlines?start=2005-02-18&end=2005-02-19&limit=10
|
http://localhost:2500/wiki/rss_with_headlines?start=2005-02-18&end=2005-02-19&limit=10
|
||||||
RSS feed with page contents for a password-protected web behaves as follows:
|
RSS feed with page contents for a password-protected web behaves as follows:
|
||||||
if the web is published, RSS feed links to the published version of the web
|
if the web is published, RSS feed links to the published version of the web
|
||||||
otherwise, the feed is not available
|
otherwise, the feed is not available
|
||||||
Madeleine will check every hour if there are new commands in the log or 24 hours have
|
Madeleine will check every hour if there are new commands in the log or 24 hours have
|
||||||
passed since last snapshot, and take snapshot if either of these conditions is true
|
passed since last snapshot, and take snapshot if either of these conditions is true
|
||||||
Madeleine will also not log read-only operations, resulting in a better performance
|
Madeleine will also not log read-only operations, resulting in a better performance
|
||||||
Wiki extracts (to HTML and plain text) will leave only the last extract file in ./storage
|
Wiki extracts (to HTML and plain text) will leave only the last extract file in ./storage
|
||||||
Wiki search handles multibyte (UTF-8) characters correctly
|
Wiki search handles multibyte (UTF-8) characters correctly
|
||||||
Local hyperlinks in published pages point to published pages [Michael DeHaan]
|
Local hyperlinks in published pages point to published pages [Michael DeHaan]
|
||||||
Fixed a bug that sometimes caused all past revisions of a page to be "forgotten" on
|
Fixed a bug that sometimes caused all past revisions of a page to be "forgotten" on
|
||||||
restart
|
restart
|
||||||
Fixed parsing of URIs with a port number (http://someplace.org:8080)
|
Fixed parsing of URIs with a port number (http://someplace.org:8080)
|
||||||
Instiki will not fork itself on a *nix, unless explicitly asked to
|
Instiki will not fork itself on a *nix, unless explicitly asked to
|
||||||
Instiki can bind to IPs other than 127.0.0.1 (command-line option)
|
Instiki can bind to IPs other than 127.0.0.1 (command-line option)
|
||||||
Revisions that do not change anything on the page are rejected
|
Revisions that do not change anything on the page are rejected
|
||||||
Automated tests for all controller actions
|
Automated tests for all controller actions
|
||||||
category: lines are presented as links to "All Pages" for relevant categories
|
category: lines are presented as links to "All Pages" for relevant categories
|
||||||
Search looks at page titles, as well as content
|
Search looks at page titles, as well as content
|
||||||
Multiple other usability enhancements and bug fixes
|
Multiple other usability enhancements and bug fixes
|
||||||
|
|
||||||
* 0.9.2:
|
* 0.9.2:
|
||||||
Rollback takes the user to an edit form. The form has to be submitted for the change to
|
Rollback takes the user to an edit form. The form has to be submitted for the change to
|
||||||
take place.
|
take place.
|
||||||
Changed to use inline style on published pages
|
Changed to use inline style on published pages
|
||||||
Fixed "forward in time" on the last revision before current page
|
Fixed "forward in time" on the last revision before current page
|
||||||
Instiki won't log bogus error messages when creating a new Wiki
|
Instiki won't log bogus error messages when creating a new Wiki
|
||||||
Fixed deprecation warning for Object.id (introduced in Ruby 1.8.2)
|
Fixed deprecation warning for Object.id (introduced in Ruby 1.8.2)
|
||||||
Madeleine upgraded to 0.7.1
|
Madeleine upgraded to 0.7.1
|
||||||
Madeleine snapshots are compressed
|
Madeleine snapshots are compressed
|
||||||
Packaged as a gem
|
Packaged as a gem
|
||||||
|
|
||||||
* 0.9.1:
|
* 0.9.1:
|
||||||
Added performance improvements for updating existing pages
|
Added performance improvements for updating existing pages
|
||||||
Fixed IP logging and RSS feeds behind proxies [With help from Guan Yang]
|
Fixed IP logging and RSS feeds behind proxies [With help from Guan Yang]
|
||||||
Fixed default storage directory (borked running on Windows) [Spotted by Curt Hibbs]
|
Fixed default storage directory (borked running on Windows) [Spotted by Curt Hibbs]
|
||||||
|
|
||||||
* 0.9.0:
|
* 0.9.0:
|
||||||
Added aliased links such as [[HomePage|that nice home page]] [Mark Reid]
|
Added aliased links such as [[HomePage|that nice home page]] [Mark Reid]
|
||||||
Added include other page content with [[!include TableOfContents]] [Mark Reid]
|
Added include other page content with [[!include TableOfContents]] [Mark Reid]
|
||||||
Added delete orphan pages from the Edit Web screen [by inspiration from Simon Arnaud]
|
Added delete orphan pages from the Edit Web screen [by inspiration from Simon Arnaud]
|
||||||
Added logging of IP address for authors (who's behind the rollback wars)
|
Added logging of IP address for authors (who's behind the rollback wars)
|
||||||
Added Categories pages through backlinks (use "categories: news, instiki" on start of line) [Mark Reid]
|
Added Categories pages through backlinks (use "categories: news, instiki" on start of line) [Mark Reid]
|
||||||
Added option to use bracket-style wiki links only (and hence ban WikiWords)
|
Added option to use bracket-style wiki links only (and hence ban WikiWords)
|
||||||
Added command-line option to specify different storage path
|
Added command-line option to specify different storage path
|
||||||
Added print view without navigation
|
Added print view without navigation
|
||||||
Added character and page (2275 characters including spaces) counter (important for student papers)
|
Added character and page (2275 characters including spaces) counter (important for student papers)
|
||||||
Off by default, activate it on the Edit Web screen
|
Off by default, activate it on the Edit Web screen
|
||||||
Added LaTeX/PDF integration on Textile installations with pdflatex installed on system (EXPERIMENTAL)
|
Added LaTeX/PDF integration on Textile installations with pdflatex installed on system (EXPERIMENTAL)
|
||||||
Use the home page as a table of contents with a unordered list to control sections
|
Use the home page as a table of contents with a unordered list to control sections
|
||||||
Added limit of 15 to the number of pages included in RSS feed
|
Added limit of 15 to the number of pages included in RSS feed
|
||||||
Moved static parts of stylesheet to separate file [Lau TŒrnskov]
|
Moved static parts of stylesheet to separate file [Lau TŒrnskov]
|
||||||
Fixed better semantics for revision movement [Ryan Singer]
|
Fixed better semantics for revision movement [Ryan Singer]
|
||||||
Fixed color diffs to work much better [Xen/Mertz/Atkins]
|
Fixed color diffs to work much better [Xen/Mertz/Atkins]
|
||||||
Fixed performance problems for All Pages list [Dennis Mertz]
|
Fixed performance problems for All Pages list [Dennis Mertz]
|
||||||
Fixed lots of rendering bugs [Mark Reid]
|
Fixed lots of rendering bugs [Mark Reid]
|
||||||
Upgraded to RedCloth 2.0.11 [integrating the fine work of Dennis Mertz]
|
Upgraded to RedCloth 2.0.11 [integrating the fine work of Dennis Mertz]
|
||||||
|
|
||||||
* 0.8.9:
|
* 0.8.9:
|
||||||
Added color diffs to see changes between revisions [Bill Atkins]
|
Added color diffs to see changes between revisions [Bill Atkins]
|
||||||
They're aren't quite perfect yet as new paragraphs split the <ins> tags (hence 0.8.9, not 0.9.0)
|
They're aren't quite perfect yet as new paragraphs split the <ins> tags (hence 0.8.9, not 0.9.0)
|
||||||
Added redirect to edit if content of page generates an error
|
Added redirect to edit if content of page generates an error
|
||||||
(so the page doesn't become unusable on bugs in the markup engines)
|
(so the page doesn't become unusable on bugs in the markup engines)
|
||||||
Fixed update Web with different address bug [Denis Metz]
|
Fixed update Web with different address bug [Denis Metz]
|
||||||
Fixed a bunch of wiki word rendering issues by doing wiki word detection and replacment at once
|
Fixed a bunch of wiki word rendering issues by doing wiki word detection and replacment at once
|
||||||
Upgraded to BlueCloth 0.0.3b (should fix loads of problems on Markdown wikis)
|
Upgraded to BlueCloth 0.0.3b (should fix loads of problems on Markdown wikis)
|
||||||
|
|
||||||
* 0.8.5:
|
* 0.8.5:
|
||||||
Instiki can now serve as a CMS by running a password-protected web with a published front
|
Instiki can now serve as a CMS by running a password-protected web with a published front
|
||||||
Added version check at startup (Instiki needs Ruby 1.8.1)
|
Added version check at startup (Instiki needs Ruby 1.8.1)
|
||||||
|
|
||||||
* 0.8.1:
|
* 0.8.1:
|
||||||
Actually included RedCloth 2.0.7 in the release
|
Actually included RedCloth 2.0.7 in the release
|
||||||
|
|
||||||
* 0.8.0:
|
* 0.8.0:
|
||||||
NOTE: Single-web wikis created in versions prior to 0.8.0 have "instiki" as their system password
|
NOTE: Single-web wikis created in versions prior to 0.8.0 have "instiki" as their system password
|
||||||
Accepts wiki words in bracket style. Ex: [[wiki word]], [[c]], [[We could'nt have done it!]]
|
Accepts wiki words in bracket style. Ex: [[wiki word]], [[c]], [[We could'nt have done it!]]
|
||||||
Accepts camel-case wiki words in all latin, greek, cyrillian, and armenian unicode characters
|
Accepts camel-case wiki words in all latin, greek, cyrillian, and armenian unicode characters
|
||||||
Many thanks to Guan Yang for building the higher- and lower-case lookup tables
|
Many thanks to Guan Yang for building the higher- and lower-case lookup tables
|
||||||
And thanks to Simon Arnaud for the initial patch that got the work started
|
And thanks to Simon Arnaud for the initial patch that got the work started
|
||||||
Changed charset to UTF-8
|
Changed charset to UTF-8
|
||||||
Cut down on command-line options and replaced them with an per-web config screen
|
Cut down on command-line options and replaced them with an per-web config screen
|
||||||
Added option to extend the stylesheet on a per-web basis to tweak the look in details
|
Added option to extend the stylesheet on a per-web basis to tweak the look in details
|
||||||
Added simple color options for variety
|
Added simple color options for variety
|
||||||
Added option to add/remove password protection on each web
|
Added option to add/remove password protection on each web
|
||||||
Added the wiki name of the author locking a given page (instead of just "someone")
|
Added the wiki name of the author locking a given page (instead of just "someone")
|
||||||
Removed single/multi-web distinction -- all Instikis are now multi-web
|
Removed single/multi-web distinction -- all Instikis are now multi-web
|
||||||
Load libraries from an unshifted load path, so that old installed libraries doesn't clash [Emiel van de Laar]
|
Load libraries from an unshifted load path, so that old installed libraries doesn't clash [Emiel van de Laar]
|
||||||
Keeps the author cookie forever, so you don't have to enter your name again and again
|
Keeps the author cookie forever, so you don't have to enter your name again and again
|
||||||
Fixed XHTML so it validates [Bruce D'Arcus]
|
Fixed XHTML so it validates [Bruce D'Arcus]
|
||||||
Authors are no longer listed under orphan pages
|
Authors are no longer listed under orphan pages
|
||||||
Added export to markup (great for backups, potentially for switching wiki engine)
|
Added export to markup (great for backups, potentially for switching wiki engine)
|
||||||
Don't link wiki words that proceeds from either /, = or ?
|
Don't link wiki words that proceeds from either /, = or ?
|
||||||
(http://c2.com/cgi/wiki?WikiWikiClones, /show/HomePage, cgi.pl?show=WikiWord without escaping)
|
(http://c2.com/cgi/wiki?WikiWikiClones, /show/HomePage, cgi.pl?show=WikiWord without escaping)
|
||||||
Accessing an unexisting page redirects to a different url (/new/PageName)
|
Accessing an unexisting page redirects to a different url (/new/PageName)
|
||||||
Increased snapshot time to just once a day (cuts down on disk storage requirements)
|
Increased snapshot time to just once a day (cuts down on disk storage requirements)
|
||||||
Made RDoc support work better with 1.8.1 [Mauricio Fern‡ndez]
|
Made RDoc support work better with 1.8.1 [Mauricio Fern‡ndez]
|
||||||
Added convinient redirect from /wiki/ to /wiki/show/HomePage
|
Added convinient redirect from /wiki/ to /wiki/show/HomePage
|
||||||
Fixed BlueCloth bug with backticks at start of line
|
Fixed BlueCloth bug with backticks at start of line
|
||||||
Updated to RedCloth 2.0.7 (and linked to the new Textile reference)
|
Updated to RedCloth 2.0.7 (and linked to the new Textile reference)
|
||||||
|
|
||||||
* 0.7.0:
|
* 0.7.0:
|
||||||
Added Markdown (BlueCloth) and RDoc [Mauricio Fern‡ndez] as command-line markup choices
|
Added Markdown (BlueCloth) and RDoc [Mauricio Fern‡ndez] as command-line markup choices
|
||||||
Added wanted and orphan page lists to All pages (only show up if there's actually orphan or wanted pages)
|
Added wanted and orphan page lists to All pages (only show up if there's actually orphan or wanted pages)
|
||||||
Added ISO-8859-1 as XML encoding in RSS feeds (makes FeedReader among others happy for special entities)
|
Added ISO-8859-1 as XML encoding in RSS feeds (makes FeedReader among others happy for special entities)
|
||||||
Added proper links in the RSS feed (but the body links are still relative, which NNW and others doesn't grok)
|
Added proper links in the RSS feed (but the body links are still relative, which NNW and others doesn't grok)
|
||||||
Added access keys: E => Edit, H => HomePage, A => All Pages, U => Recently Revised, X => Export
|
Added access keys: E => Edit, H => HomePage, A => All Pages, U => Recently Revised, X => Export
|
||||||
Added password-login through URL (so you can subscribe to feed on a protected web)
|
Added password-login through URL (so you can subscribe to feed on a protected web)
|
||||||
Added web passwords to the feed links for protected webs, so they work without manual login
|
Added web passwords to the feed links for protected webs, so they work without manual login
|
||||||
Added the web name in small letters above all pages within a web
|
Added the web name in small letters above all pages within a web
|
||||||
Polished authors and recently revised
|
Polished authors and recently revised
|
||||||
Updated to RedCloth 2.0.6
|
Updated to RedCloth 2.0.6
|
||||||
Changed content type for RSS feeds to text/xml (makes Mozilla Aggreg8 happy)
|
Changed content type for RSS feeds to text/xml (makes Mozilla Aggreg8 happy)
|
||||||
Changed searching to be case insensitive
|
Changed searching to be case insensitive
|
||||||
Changed HomePage to display the name of the web instead
|
Changed HomePage to display the name of the web instead
|
||||||
Changed exported HTML pages to be valid XHTML (which can be preprocessed by XSLT)
|
Changed exported HTML pages to be valid XHTML (which can be preprocessed by XSLT)
|
||||||
Fixed broken recently revised
|
Fixed broken recently revised
|
||||||
|
|
||||||
* 0.6.0:
|
* 0.6.0:
|
||||||
Fixed Windows compatibility [Florian]
|
Fixed Windows compatibility [Florian]
|
||||||
Fixed bug that would prevent Madeleine from taking snapshots in Daemon mode
|
Fixed bug that would prevent Madeleine from taking snapshots in Daemon mode
|
||||||
Added export entire web as HTML in a zip file
|
Added export entire web as HTML in a zip file
|
||||||
Added RSS feeds
|
Added RSS feeds
|
||||||
Added proper getops support for the growing number of options [Florian]
|
Added proper getops support for the growing number of options [Florian]
|
||||||
Added safe mode that forbids style options in RedCloth [Florian]
|
Added safe mode that forbids style options in RedCloth [Florian]
|
||||||
Updated RedCloth to 2.0.5
|
Updated RedCloth to 2.0.5
|
||||||
|
|
||||||
* 0.5.0:
|
* 0.5.0:
|
||||||
NOTE: 0.5.0 is NOT compatible with databases from earlier versions
|
NOTE: 0.5.0 is NOT compatible with databases from earlier versions
|
||||||
Added revisions
|
Added revisions
|
||||||
Added multiple webs
|
Added multiple webs
|
||||||
Added password protection for webs on multi-web setups
|
Added password protection for webs on multi-web setups
|
||||||
Added the notion of authors (that are saved in a cookie)
|
Added the notion of authors (that are saved in a cookie)
|
||||||
Added command-line option for not running as a Daemon on Unix
|
Added command-line option for not running as a Daemon on Unix
|
||||||
|
|
||||||
* 0.3.1:
|
* 0.3.1:
|
||||||
Added option to escape wiki words with \
|
Added option to escape wiki words with \
|
||||||
|
|
||||||
* 0.3.0:
|
* 0.3.0:
|
||||||
Brought all files into common style (including Textile help on the edit page)
|
Brought all files into common style (including Textile help on the edit page)
|
||||||
Added page locking (if someone already is editing a page there's a warning)
|
Added page locking (if someone already is editing a page there's a warning)
|
||||||
Added daemon abilities on Unix (keep Instiki running after you close the terminal)
|
Added daemon abilities on Unix (keep Instiki running after you close the terminal)
|
||||||
Made port 2500 the default port, so Instiki can be launched by dobbelt-click
|
Made port 2500 the default port, so Instiki can be launched by dobbelt-click
|
||||||
Added Textile cache to speed-up rendering of large pages
|
Added Textile cache to speed-up rendering of large pages
|
||||||
Made WikiWords look like "Wiki Words"
|
Made WikiWords look like "Wiki Words"
|
||||||
Updated RedCloth to 2.0.4
|
Updated RedCloth to 2.0.4
|
||||||
|
|
||||||
* 0.2.5:
|
* 0.2.5:
|
||||||
Upgraded to RedCloth 2.0.2 and Madeleine 0.6.1, which means the
|
Upgraded to RedCloth 2.0.2 and Madeleine 0.6.1, which means the
|
||||||
Windows problems are gone. Also fixed a problem with wikiwords
|
Windows problems are gone. Also fixed a problem with wikiwords
|
||||||
that used part of other wikiwords.
|
that used part of other wikiwords.
|
||||||
|
|
||||||
* 0.2.0:
|
* 0.2.0:
|
||||||
First public release
|
First public release
|
||||||
|
|
140
README
140
README
|
@ -1,70 +1,70 @@
|
||||||
===What is Instiki?
|
===What is Instiki?
|
||||||
|
|
||||||
Admitted, it's YetAnotherWikiClone[http://c2.com/cgi/wiki?WikiWikiClones], but with a strong focus
|
Admitted, it's YetAnotherWikiClone[http://c2.com/cgi/wiki?WikiWikiClones], but with a strong focus
|
||||||
on simplicity of installation and running:
|
on simplicity of installation and running:
|
||||||
|
|
||||||
Step 1. Download
|
Step 1. Download
|
||||||
|
|
||||||
Step 2. Run "instiki"
|
Step 2. Run "instiki"
|
||||||
|
|
||||||
Step 3. Chuckle... "There's no step three!" (TM)
|
Step 3. Chuckle... "There's no step three!" (TM)
|
||||||
|
|
||||||
You're now running a perfectly suitable wiki on port 2500
|
You're now running a perfectly suitable wiki on port 2500
|
||||||
that'll present you with one-step setup, followed by a textarea for the home page
|
that'll present you with one-step setup, followed by a textarea for the home page
|
||||||
on http://localhost:2500.
|
on http://localhost:2500.
|
||||||
|
|
||||||
Instiki lowers the barriers of interest for when you might consider
|
Instiki lowers the barriers of interest for when you might consider
|
||||||
using a wiki. It's so simple to get running that you'll find yourself
|
using a wiki. It's so simple to get running that you'll find yourself
|
||||||
using it for anything -- taking notes, brainstorming, organizing a
|
using it for anything -- taking notes, brainstorming, organizing a
|
||||||
gathering.
|
gathering.
|
||||||
|
|
||||||
===Features:
|
===Features:
|
||||||
* Regular expression search: Find deep stuff really fast
|
* Regular expression search: Find deep stuff really fast
|
||||||
* Revisions: Follow the changes on every page from birth. Rollback to an earlier rev
|
* Revisions: Follow the changes on every page from birth. Rollback to an earlier rev
|
||||||
* Export to HTML or markup in a zip: Take the entire wiki with you home or for reference
|
* Export to HTML or markup in a zip: Take the entire wiki with you home or for reference
|
||||||
* RSS feeds to track recently revised pages
|
* RSS feeds to track recently revised pages
|
||||||
* Multiple webs: Create separate wikis with their own namespace
|
* Multiple webs: Create separate wikis with their own namespace
|
||||||
* Password-protected webs: Keep it private
|
* Password-protected webs: Keep it private
|
||||||
* Authors: Each revision is associated with an author, so you can see who changed what
|
* Authors: Each revision is associated with an author, so you can see who changed what
|
||||||
* Reference tracker: Which other pages are pointing to the current?
|
* Reference tracker: Which other pages are pointing to the current?
|
||||||
* Speed: Using Madelein[http://madeleine.sourceforge.net] for persistence (all pages are in memory)
|
* Speed: Using Madelein[http://madeleine.sourceforge.net] for persistence (all pages are in memory)
|
||||||
* Three markup choices: Textile[http://www.textism.com/tools/textile]
|
* Three markup choices: Textile[http://www.textism.com/tools/textile]
|
||||||
(default / RedCloth[http://www.whytheluckystiff.net/ruby/redcloth]),
|
(default / RedCloth[http://www.whytheluckystiff.net/ruby/redcloth]),
|
||||||
Markdown (BlueCloth[http://bluecloth.rubyforge.org]), and RDoc[http://rdoc.sourceforge.net/doc]
|
Markdown (BlueCloth[http://bluecloth.rubyforge.org]), and RDoc[http://rdoc.sourceforge.net/doc]
|
||||||
* Embedded webserver: Through WEBrick[http://www.webrick.org]
|
* Embedded webserver: Through WEBrick[http://www.webrick.org]
|
||||||
* Internationalization: Wiki words in any latin, greek, cyrillian, or armenian characters
|
* Internationalization: Wiki words in any latin, greek, cyrillian, or armenian characters
|
||||||
* Color diffs: Track changes through revisions
|
* Color diffs: Track changes through revisions
|
||||||
|
|
||||||
===Missing:
|
===Missing:
|
||||||
* File attachments
|
* File attachments
|
||||||
|
|
||||||
===Install from gem:
|
===Install from gem:
|
||||||
* Install rubygems
|
* Install rubygems
|
||||||
* Run "gem install instiki"
|
* Run "gem install instiki"
|
||||||
* Change to a directory where you want Instiki to keep its data files (for example, ~/instiki/)
|
* Change to a directory where you want Instiki to keep its data files (for example, ~/instiki/)
|
||||||
* Run "instiki" - this will create a "storage" directory (for example, ~/instiki/storage), and start a new Wiki service
|
* Run "instiki" - this will create a "storage" directory (for example, ~/instiki/storage), and start a new Wiki service
|
||||||
|
|
||||||
Make sure that you always launch Instiki from the same working directory, or specify the storage directory in runtime parameters, such as:
|
Make sure that you always launch Instiki from the same working directory, or specify the storage directory in runtime parameters, such as:
|
||||||
instiki --storage ~/instiki/storage
|
instiki --storage ~/instiki/storage
|
||||||
|
|
||||||
===Command-line options:
|
===Command-line options:
|
||||||
* Run "instiki --help"
|
* Run "instiki --help"
|
||||||
|
|
||||||
===History:
|
===History:
|
||||||
* See CHANGELOG
|
* See CHANGELOG
|
||||||
|
|
||||||
===Download latest from:
|
===Download latest from:
|
||||||
* http://rubyforge.org/project/showfiles.php?group_id=186
|
* http://rubyforge.org/project/showfiles.php?group_id=186
|
||||||
|
|
||||||
===Visit the official Instiki wiki:
|
===Visit the official Instiki wiki:
|
||||||
* http://www.instiki.org
|
* http://www.instiki.org
|
||||||
|
|
||||||
===License:
|
===License:
|
||||||
* same as Ruby's
|
* same as Ruby's
|
||||||
|
|
||||||
---
|
---
|
||||||
Author:: David Heinemeier Hansson
|
Author:: David Heinemeier Hansson
|
||||||
Email:: david@loudthinking.com
|
Email:: david@loudthinking.com
|
||||||
Weblog:: http://www.loudthinking.com
|
Weblog:: http://www.loudthinking.com
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,137 +1,137 @@
|
||||||
class Page < ActiveRecord::Base
|
class Page < ActiveRecord::Base
|
||||||
belongs_to :web
|
belongs_to :web
|
||||||
has_many :revisions, :order => 'id'
|
has_many :revisions, :order => 'id'
|
||||||
has_one :current_revision, :class_name => 'Revision', :order => 'id DESC'
|
has_one :current_revision, :class_name => 'Revision', :order => 'id DESC'
|
||||||
|
|
||||||
def revise(content, time, author)
|
def revise(content, time, author)
|
||||||
revisions_size = new_record? ? 0 : revisions.size
|
revisions_size = new_record? ? 0 : revisions.size
|
||||||
if (revisions_size > 0) and content == current_revision.content
|
if (revisions_size > 0) and content == current_revision.content
|
||||||
raise Instiki::ValidationError.new(
|
raise Instiki::ValidationError.new(
|
||||||
"You have tried to save page '#{name}' without changing its content")
|
"You have tried to save page '#{name}' without changing its content")
|
||||||
end
|
end
|
||||||
|
|
||||||
author = Author.new(author.to_s) unless author.is_a?(Author)
|
author = Author.new(author.to_s) unless author.is_a?(Author)
|
||||||
|
|
||||||
# Try to render content to make sure that markup engine can take it,
|
# Try to render content to make sure that markup engine can take it,
|
||||||
Revision.new(:page => self, :content => content, :author => author, :revised_at => time).force_rendering
|
Revision.new(:page => self, :content => content, :author => author, :revised_at => time).force_rendering
|
||||||
|
|
||||||
# A user may change a page, look at it and make some more changes - several times.
|
# A user may change a page, look at it and make some more changes - several times.
|
||||||
# Not to record every such iteration as a new revision, if the previous revision was done
|
# Not to record every such iteration as a new revision, if the previous revision was done
|
||||||
# by the same author, not more than 30 minutes ago, then update the last revision instead of
|
# by the same author, not more than 30 minutes ago, then update the last revision instead of
|
||||||
# creating a new one
|
# creating a new one
|
||||||
if (revisions_size > 0) && continous_revision?(time, author)
|
if (revisions_size > 0) && continous_revision?(time, author)
|
||||||
current_revision.update_attributes(:content => content, :revised_at => time)
|
current_revision.update_attributes(:content => content, :revised_at => time)
|
||||||
else
|
else
|
||||||
Revision.create(:page => self, :content => content, :author => author, :revised_at => time)
|
Revision.create(:page => self, :content => content, :author => author, :revised_at => time)
|
||||||
end
|
end
|
||||||
|
|
||||||
save
|
save
|
||||||
web.refresh_pages_with_references(name) if revisions_size == 0
|
web.refresh_pages_with_references(name) if revisions_size == 0
|
||||||
|
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def rollback(revision_number, time, author_ip = nil)
|
def rollback(revision_number, time, author_ip = nil)
|
||||||
roll_back_revision = self.revisions[revision_number]
|
roll_back_revision = self.revisions[revision_number]
|
||||||
if roll_back_revision.nil?
|
if roll_back_revision.nil?
|
||||||
raise Instiki::ValidationError.new("Revision #{revision_number} not found")
|
raise Instiki::ValidationError.new("Revision #{revision_number} not found")
|
||||||
end
|
end
|
||||||
revise(roll_back_revision.content, time, Author.new(roll_back_revision.author, author_ip))
|
revise(roll_back_revision.content, time, Author.new(roll_back_revision.author, author_ip))
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions?
|
def revisions?
|
||||||
revisions.size > 1
|
revisions.size > 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def previous_revision(revision)
|
def previous_revision(revision)
|
||||||
revision_index = revisions.each_with_index do |rev, index|
|
revision_index = revisions.each_with_index do |rev, index|
|
||||||
if rev.id == revision.id
|
if rev.id == revision.id
|
||||||
break index
|
break index
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if revision_index.nil? or revision_index == 0
|
if revision_index.nil? or revision_index == 0
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
revisions[revision_index - 1]
|
revisions[revision_index - 1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def in_category?(cat)
|
def in_category?(cat)
|
||||||
cat.nil? || cat.empty? || categories.include?(cat)
|
cat.nil? || cat.empty? || categories.include?(cat)
|
||||||
end
|
end
|
||||||
|
|
||||||
def categories
|
def categories
|
||||||
display_content.find_chunks(Category).map { |cat| cat.list }.flatten
|
display_content.find_chunks(Category).map { |cat| cat.list }.flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
def authors
|
def authors
|
||||||
revisions.collect { |rev| rev.author }
|
revisions.collect { |rev| rev.author }
|
||||||
end
|
end
|
||||||
|
|
||||||
def references
|
def references
|
||||||
web.select.pages_that_reference(name)
|
web.select.pages_that_reference(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def linked_from
|
def linked_from
|
||||||
web.select.pages_that_link_to(name)
|
web.select.pages_that_link_to(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def included_from
|
def included_from
|
||||||
web.select.pages_that_include(name)
|
web.select.pages_that_include(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the original wiki-word name as separate words, so "MyPage" becomes "My Page".
|
# Returns the original wiki-word name as separate words, so "MyPage" becomes "My Page".
|
||||||
def plain_name
|
def plain_name
|
||||||
web.brackets_only? ? name : WikiWords.separate(name)
|
web.brackets_only? ? name : WikiWords.separate(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# used to build chunk ids.
|
# used to build chunk ids.
|
||||||
#def id
|
#def id
|
||||||
# @id ||= name.unpack('H*').first
|
# @id ||= name.unpack('H*').first
|
||||||
#end
|
#end
|
||||||
|
|
||||||
def link(options = {})
|
def link(options = {})
|
||||||
web.make_link(name, nil, options)
|
web.make_link(name, nil, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def author_link(options = {})
|
def author_link(options = {})
|
||||||
web.make_link(author, nil, options)
|
web.make_link(author, nil, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
LOCKING_PERIOD = 30.minutes
|
LOCKING_PERIOD = 30.minutes
|
||||||
|
|
||||||
def lock(time, locked_by)
|
def lock(time, locked_by)
|
||||||
update_attributes(:locked_at => time, :locked_by => locked_by)
|
update_attributes(:locked_at => time, :locked_by => locked_by)
|
||||||
end
|
end
|
||||||
|
|
||||||
def lock_duration(time)
|
def lock_duration(time)
|
||||||
((time - locked_at) / 60).to_i unless locked_at.nil?
|
((time - locked_at) / 60).to_i unless locked_at.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def unlock
|
def unlock
|
||||||
update_attribute(:locked_at, nil)
|
update_attribute(:locked_at, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def locked?(comparison_time)
|
def locked?(comparison_time)
|
||||||
locked_at + LOCKING_PERIOD > comparison_time unless locked_at.nil?
|
locked_at + LOCKING_PERIOD > comparison_time unless locked_at.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def continous_revision?(time, author)
|
def continous_revision?(time, author)
|
||||||
(current_revision.author == author) && (revised_at + 30.minutes > time)
|
(current_revision.author == author) && (revised_at + 30.minutes > time)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Forward method calls to the current revision, so the page responds to all revision calls
|
# Forward method calls to the current revision, so the page responds to all revision calls
|
||||||
def method_missing(method_id, *args, &block)
|
def method_missing(method_id, *args, &block)
|
||||||
method_name = method_id.to_s
|
method_name = method_id.to_s
|
||||||
# Perform a hand-off to AR::Base#method_missing
|
# Perform a hand-off to AR::Base#method_missing
|
||||||
if @attributes.include?(method_name) or md = /(=|\?|_before_type_cast)$/.match(method_name)
|
if @attributes.include?(method_name) or md = /(=|\?|_before_type_cast)$/.match(method_name)
|
||||||
super(method_id, *args, &block)
|
super(method_id, *args, &block)
|
||||||
else
|
else
|
||||||
current_revision.send(method_id)
|
current_revision.send(method_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,105 +1,105 @@
|
||||||
require 'diff'
|
require 'diff'
|
||||||
class Revision < ActiveRecord::Base
|
class Revision < ActiveRecord::Base
|
||||||
belongs_to :page
|
belongs_to :page
|
||||||
composed_of :author, :mapping => [ %w(author name), %w(ip ip) ]
|
composed_of :author, :mapping => [ %w(author name), %w(ip ip) ]
|
||||||
|
|
||||||
# Returns an array of all the WikiIncludes present in the content of this revision.
|
# Returns an array of all the WikiIncludes present in the content of this revision.
|
||||||
def wiki_includes
|
def wiki_includes
|
||||||
unless @wiki_includes_cache
|
unless @wiki_includes_cache
|
||||||
chunks = display_content.find_chunks(Include)
|
chunks = display_content.find_chunks(Include)
|
||||||
@wiki_includes_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
|
@wiki_includes_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
|
||||||
end
|
end
|
||||||
@wiki_includes_cache
|
@wiki_includes_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an array of all the WikiReferences present in the content of this revision.
|
# Returns an array of all the WikiReferences present in the content of this revision.
|
||||||
def wiki_references
|
def wiki_references
|
||||||
unless @wiki_references_cache
|
unless @wiki_references_cache
|
||||||
chunks = display_content.find_chunks(WikiChunk::WikiReference)
|
chunks = display_content.find_chunks(WikiChunk::WikiReference)
|
||||||
@wiki_references_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
|
@wiki_references_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
|
||||||
end
|
end
|
||||||
@wiki_references_cache
|
@wiki_references_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an array of all the WikiWords present in the content of this revision.
|
# Returns an array of all the WikiWords present in the content of this revision.
|
||||||
def wiki_words
|
def wiki_words
|
||||||
unless @wiki_words_cache
|
unless @wiki_words_cache
|
||||||
wiki_chunks = display_content.find_chunks(WikiChunk::WikiLink)
|
wiki_chunks = display_content.find_chunks(WikiChunk::WikiLink)
|
||||||
@wiki_words_cache = wiki_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
|
@wiki_words_cache = wiki_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
|
||||||
end
|
end
|
||||||
@wiki_words_cache
|
@wiki_words_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an array of all the WikiWords present in the content of this revision.
|
# Returns an array of all the WikiWords present in the content of this revision.
|
||||||
# that already exists as a page in the web.
|
# that already exists as a page in the web.
|
||||||
def existing_pages
|
def existing_pages
|
||||||
wiki_words.select { |wiki_word| page.web.page(wiki_word) }
|
wiki_words.select { |wiki_word| page.web.page(wiki_word) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an array of all the WikiWords present in the content of this revision
|
# Returns an array of all the WikiWords present in the content of this revision
|
||||||
# that *doesn't* already exists as a page in the web.
|
# that *doesn't* already exists as a page in the web.
|
||||||
def unexisting_pages
|
def unexisting_pages
|
||||||
wiki_words - existing_pages
|
wiki_words - existing_pages
|
||||||
end
|
end
|
||||||
|
|
||||||
# Explicit check for new type of display cache with chunks_by_type method.
|
# Explicit check for new type of display cache with chunks_by_type method.
|
||||||
# Ensures new version works with older snapshots.
|
# Ensures new version works with older snapshots.
|
||||||
def display_content
|
def display_content
|
||||||
unless @display_cache && @display_cache.respond_to?(:chunks_by_type)
|
unless @display_cache && @display_cache.respond_to?(:chunks_by_type)
|
||||||
@display_cache = WikiContent.new(self)
|
@display_cache = WikiContent.new(self)
|
||||||
@display_cache.render!
|
@display_cache.render!
|
||||||
end
|
end
|
||||||
@display_cache
|
@display_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO this probably doesn't belong in revision (because it has to call back the page)
|
# TODO this probably doesn't belong in revision (because it has to call back the page)
|
||||||
def display_diff
|
def display_diff
|
||||||
previous_revision = page.previous_revision(self)
|
previous_revision = page.previous_revision(self)
|
||||||
if previous_revision
|
if previous_revision
|
||||||
HTMLDiff.diff(previous_revision.display_content, display_content)
|
HTMLDiff.diff(previous_revision.display_content, display_content)
|
||||||
else
|
else
|
||||||
display_content
|
display_content
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def clear_display_cache
|
def clear_display_cache
|
||||||
@wiki_words_cache = @published_cache = @display_cache = @wiki_includes_cache =
|
@wiki_words_cache = @published_cache = @display_cache = @wiki_includes_cache =
|
||||||
@wiki_references_cache = nil
|
@wiki_references_cache = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def display_published
|
def display_published
|
||||||
unless @published_cache && @published_cache.respond_to?(:chunks_by_type)
|
unless @published_cache && @published_cache.respond_to?(:chunks_by_type)
|
||||||
@published_cache = WikiContent.new(self, {:mode => :publish})
|
@published_cache = WikiContent.new(self, {:mode => :publish})
|
||||||
@published_cache.render!
|
@published_cache.render!
|
||||||
end
|
end
|
||||||
@published_cache
|
@published_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
def display_content_for_export
|
def display_content_for_export
|
||||||
WikiContent.new(self, {:mode => :export} ).render!
|
WikiContent.new(self, {:mode => :export} ).render!
|
||||||
end
|
end
|
||||||
|
|
||||||
def force_rendering
|
def force_rendering
|
||||||
begin
|
begin
|
||||||
display_content.render!
|
display_content.render!
|
||||||
rescue => e
|
rescue => e
|
||||||
logger.error "Failed rendering page #{@name}"
|
logger.error "Failed rendering page #{@name}"
|
||||||
logger.error e
|
logger.error e
|
||||||
message = e.message
|
message = e.message
|
||||||
# substitute content with an error message
|
# substitute content with an error message
|
||||||
self.content = <<-EOL
|
self.content = <<-EOL
|
||||||
<p>Markup engine has failed to render this page, raising the following error:</p>
|
<p>Markup engine has failed to render this page, raising the following error:</p>
|
||||||
<p>#{message}</p>
|
<p>#{message}</p>
|
||||||
<pre>#{self.content}</pre>
|
<pre>#{self.content}</pre>
|
||||||
EOL
|
EOL
|
||||||
clear_display_cache
|
clear_display_cache
|
||||||
raise e
|
raise e
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
after_create :force_rendering
|
after_create :force_rendering
|
||||||
after_save :clear_display_cache
|
after_save :clear_display_cache
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,173 +1,173 @@
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
|
|
||||||
class Web < ActiveRecord::Base
|
class Web < ActiveRecord::Base
|
||||||
has_many :pages#, :include => [:current_revision, :web]
|
has_many :pages#, :include => [:current_revision, :web]
|
||||||
|
|
||||||
def wiki
|
def wiki
|
||||||
Wiki.new
|
Wiki.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def file_yard
|
def file_yard
|
||||||
@file_yard ||= FileYard.new("#{Wiki.storage_path}/#{address}", max_upload_size)
|
@file_yard ||= FileYard.new("#{Wiki.storage_path}/#{address}", max_upload_size)
|
||||||
end
|
end
|
||||||
|
|
||||||
def settings_changed?(markup, safe_mode, brackets_only)
|
def settings_changed?(markup, safe_mode, brackets_only)
|
||||||
self.markup != markup ||
|
self.markup != markup ||
|
||||||
self.safe_mode != safe_mode ||
|
self.safe_mode != safe_mode ||
|
||||||
self.brackets_only != brackets_only
|
self.brackets_only != brackets_only
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_page(name, content, time, author)
|
def add_page(name, content, time, author)
|
||||||
page = page(name) || Page.new(:web => self, :name => name)
|
page = page(name) || Page.new(:web => self, :name => name)
|
||||||
page.revise(content, time, author)
|
page.revise(content, time, author)
|
||||||
end
|
end
|
||||||
|
|
||||||
def authors
|
def authors
|
||||||
select.authors
|
select.authors
|
||||||
end
|
end
|
||||||
|
|
||||||
def categories
|
def categories
|
||||||
select.map { |page| page.categories }.flatten.uniq.sort
|
select.map { |page| page.categories }.flatten.uniq.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
def page(name)
|
def page(name)
|
||||||
pages.find(:first, :conditions => ['name = ?', name])
|
pages.find(:first, :conditions => ['name = ?', name])
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_page?(name)
|
def has_page?(name)
|
||||||
Page.count(['web_id = ? AND name = ?', id, name]) > 0
|
Page.count(['web_id = ? AND name = ?', id, name]) > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_file?(name)
|
def has_file?(name)
|
||||||
wiki.file_yard(self).has_file?(name)
|
wiki.file_yard(self).has_file?(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def markup
|
def markup
|
||||||
read_attribute('markup').to_sym
|
read_attribute('markup').to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_file_link(mode, name, text, base_url)
|
def make_file_link(mode, name, text, base_url)
|
||||||
link = CGI.escape(name)
|
link = CGI.escape(name)
|
||||||
case mode
|
case mode
|
||||||
when :export
|
when :export
|
||||||
if has_file?(name) then "<a class=\"existingWikiWord\" href=\"#{link}.html\">#{text}</a>"
|
if has_file?(name) then "<a class=\"existingWikiWord\" href=\"#{link}.html\">#{text}</a>"
|
||||||
else "<span class=\"newWikiWord\">#{text}</span>" end
|
else "<span class=\"newWikiWord\">#{text}</span>" end
|
||||||
when :publish
|
when :publish
|
||||||
if has_file?(name) then "<a class=\"existingWikiWord\" href=\"#{base_url}/published/#{link}\">#{text}</a>"
|
if has_file?(name) then "<a class=\"existingWikiWord\" href=\"#{base_url}/published/#{link}\">#{text}</a>"
|
||||||
else "<span class=\"newWikiWord\">#{text}</span>" end
|
else "<span class=\"newWikiWord\">#{text}</span>" end
|
||||||
else
|
else
|
||||||
if has_file?(name)
|
if has_file?(name)
|
||||||
"<a class=\"existingWikiWord\" href=\"#{base_url}/file/#{link}\">#{text}</a>"
|
"<a class=\"existingWikiWord\" href=\"#{base_url}/file/#{link}\">#{text}</a>"
|
||||||
else
|
else
|
||||||
"<span class=\"newWikiWord\">#{text}<a href=\"#{base_url}/file/#{link}\">?</a></span>"
|
"<span class=\"newWikiWord\">#{text}<a href=\"#{base_url}/file/#{link}\">?</a></span>"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a link for the given page name and link text based
|
# Create a link for the given page name and link text based
|
||||||
# on the render mode in options and whether the page exists
|
# on the render mode in options and whether the page exists
|
||||||
# in the this web.
|
# in the this web.
|
||||||
# The links a relative, and will work only if displayed on another WikiPage.
|
# The links a relative, and will work only if displayed on another WikiPage.
|
||||||
# It should not be used in menus, templates and such - instead, use link_to_page helper
|
# It should not be used in menus, templates and such - instead, use link_to_page helper
|
||||||
def make_link(name, text = nil, options = {})
|
def make_link(name, text = nil, options = {})
|
||||||
text = CGI.escapeHTML(text || WikiWords.separate(name))
|
text = CGI.escapeHTML(text || WikiWords.separate(name))
|
||||||
mode = options[:mode] || :show
|
mode = options[:mode] || :show
|
||||||
base_url = options[:base_url] || '..'
|
base_url = options[:base_url] || '..'
|
||||||
link_type = options[:link_type] || :show
|
link_type = options[:link_type] || :show
|
||||||
case link_type.to_sym
|
case link_type.to_sym
|
||||||
when :show
|
when :show
|
||||||
make_page_link(mode, name, text, base_url)
|
make_page_link(mode, name, text, base_url)
|
||||||
when :file
|
when :file
|
||||||
make_file_link(mode, name, text, base_url)
|
make_file_link(mode, name, text, base_url)
|
||||||
when :pic
|
when :pic
|
||||||
make_pic_link(mode, name, text, base_url)
|
make_pic_link(mode, name, text, base_url)
|
||||||
else
|
else
|
||||||
raise "Unknown link type: #{link_type}"
|
raise "Unknown link type: #{link_type}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_page_link(mode, name, text, base_url)
|
def make_page_link(mode, name, text, base_url)
|
||||||
link = CGI.escape(name)
|
link = CGI.escape(name)
|
||||||
case mode.to_sym
|
case mode.to_sym
|
||||||
when :export
|
when :export
|
||||||
if has_page?(name) then %{<a class="existingWikiWord" href="#{link}.html">#{text}</a>}
|
if has_page?(name) then %{<a class="existingWikiWord" href="#{link}.html">#{text}</a>}
|
||||||
else %{<span class="newWikiWord">#{text}</span>} end
|
else %{<span class="newWikiWord">#{text}</span>} end
|
||||||
when :publish
|
when :publish
|
||||||
if has_page?(name) then %{<a class="existingWikiWord" href="#{base_url}/published/#{link}">#{text}</a>}
|
if has_page?(name) then %{<a class="existingWikiWord" href="#{base_url}/published/#{link}">#{text}</a>}
|
||||||
else %{<span class="newWikiWord">#{text}</span>} end
|
else %{<span class="newWikiWord">#{text}</span>} end
|
||||||
else
|
else
|
||||||
if has_page?(name)
|
if has_page?(name)
|
||||||
%{<a class="existingWikiWord" href="#{base_url}/show/#{link}">#{text}</a>}
|
%{<a class="existingWikiWord" href="#{base_url}/show/#{link}">#{text}</a>}
|
||||||
else
|
else
|
||||||
%{<span class="newWikiWord">#{text}<a href="#{base_url}/show/#{link}">?</a></span>}
|
%{<span class="newWikiWord">#{text}<a href="#{base_url}/show/#{link}">?</a></span>}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_pic_link(mode, name, text, base_url)
|
def make_pic_link(mode, name, text, base_url)
|
||||||
link = CGI.escape(name)
|
link = CGI.escape(name)
|
||||||
case mode.to_sym
|
case mode.to_sym
|
||||||
when :export
|
when :export
|
||||||
if has_file?(name) then %{<img alt="#{text}" src="#{link}" />}
|
if has_file?(name) then %{<img alt="#{text}" src="#{link}" />}
|
||||||
else %{<img alt="#{text}" src="no image" />} end
|
else %{<img alt="#{text}" src="no image" />} end
|
||||||
when :publish
|
when :publish
|
||||||
if has_file?(name) then %{<img alt="#{text}" src="#{link}" />}
|
if has_file?(name) then %{<img alt="#{text}" src="#{link}" />}
|
||||||
else %{<span class="newWikiWord">#{text}</span>} end
|
else %{<span class="newWikiWord">#{text}</span>} end
|
||||||
else
|
else
|
||||||
if has_file?(name) then %{<img alt="#{text}" src="#{base_url}/pic/#{link}" />}
|
if has_file?(name) then %{<img alt="#{text}" src="#{base_url}/pic/#{link}" />}
|
||||||
else %{<span class="newWikiWord">#{text}<a href="#{base_url}/pic/#{link}">?</a></span>} end
|
else %{<span class="newWikiWord">#{text}<a href="#{base_url}/pic/#{link}">?</a></span>} end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Clears the display cache for all the pages with references to
|
# Clears the display cache for all the pages with references to
|
||||||
def refresh_pages_with_references(page_name)
|
def refresh_pages_with_references(page_name)
|
||||||
#select.pages_that_reference(page_name).each { |page|
|
#select.pages_that_reference(page_name).each { |page|
|
||||||
# page.revisions.each { |revision| revision.clear_display_cache }
|
# page.revisions.each { |revision| revision.clear_display_cache }
|
||||||
#}
|
#}
|
||||||
end
|
end
|
||||||
|
|
||||||
def refresh_revisions
|
def refresh_revisions
|
||||||
select.each { |page| page.revisions.each { |revision| revision.clear_display_cache } }
|
select.each { |page| page.revisions.each { |revision| revision.clear_display_cache } }
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_pages(pages_to_be_removed)
|
def remove_pages(pages_to_be_removed)
|
||||||
pages_to_be_removed.each { |p| p.destroy }
|
pages_to_be_removed.each { |p| p.destroy }
|
||||||
end
|
end
|
||||||
|
|
||||||
def revised_at
|
def revised_at
|
||||||
select.most_recent_revision
|
select.most_recent_revision
|
||||||
end
|
end
|
||||||
|
|
||||||
def select(&condition)
|
def select(&condition)
|
||||||
PageSet.new(self, pages, condition)
|
PageSet.new(self, pages, condition)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Returns an array of all the wiki words in any current revision
|
# Returns an array of all the wiki words in any current revision
|
||||||
def wiki_words
|
def wiki_words
|
||||||
pages.inject([]) { |wiki_words, page| wiki_words << page.wiki_words }.flatten.uniq
|
pages.inject([]) { |wiki_words, page| wiki_words << page.wiki_words }.flatten.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an array of all the page names on this web
|
# Returns an array of all the page names on this web
|
||||||
def page_names
|
def page_names
|
||||||
pages.map { |p| p.name }
|
pages.map { |p| p.name }
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
before_save :sanitize_markup
|
before_save :sanitize_markup
|
||||||
before_validation :validate_address
|
before_validation :validate_address
|
||||||
validates_uniqueness_of :address
|
validates_uniqueness_of :address
|
||||||
validates_length_of :color, :in => 3..6
|
validates_length_of :color, :in => 3..6
|
||||||
|
|
||||||
def sanitize_markup
|
def sanitize_markup
|
||||||
self.markup = markup.to_s
|
self.markup = markup.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_address
|
def validate_address
|
||||||
unless address == CGI.escape(address)
|
unless address == CGI.escape(address)
|
||||||
self.errors.add(:address, 'should contain only valid URI characters')
|
self.errors.add(:address, 'should contain only valid URI characters')
|
||||||
raise Instiki::ValidationError.new("#{self.class.human_attribute_name('address')} #{errors.on(:address)}")
|
raise Instiki::ValidationError.new("#{self.class.human_attribute_name('address')} #{errors.on(:address)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
$__instiki_source_patterns = [
|
$__instiki_source_patterns = [
|
||||||
'[A-Z]*', 'instiki', 'instiki.rb', 'app/**/*', 'lib/**/*', 'vendor/**/*',
|
'[A-Z]*', 'instiki', 'instiki.rb', 'app/**/*', 'lib/**/*', 'vendor/**/*',
|
||||||
'public/**/*', 'natives/**/*', 'config/**/*', 'script/**/*'
|
'public/**/*', 'natives/**/*', 'config/**/*', 'script/**/*'
|
||||||
]
|
]
|
||||||
|
|
||||||
spec = Gem::Specification.new do |s|
|
spec = Gem::Specification.new do |s|
|
||||||
s.platform = Gem::Platform::RUBY
|
s.platform = Gem::Platform::RUBY
|
||||||
s.name = 'instiki'
|
s.name = 'instiki'
|
||||||
s.version = "0.10.2"
|
s.version = "0.10.2"
|
||||||
s.summary = 'Easy to install WikiClone running on WEBrick and SQLite'
|
s.summary = 'Easy to install WikiClone running on WEBrick and SQLite'
|
||||||
s.description = <<-EOF
|
s.description = <<-EOF
|
||||||
Instiki is a Wiki Clone written in Ruby that ships with an embedded
|
Instiki is a Wiki Clone written in Ruby that ships with an embedded
|
||||||
webserver. You can setup up an Instiki in just a few steps.
|
webserver. You can setup up an Instiki in just a few steps.
|
||||||
Possibly the simplest wiki setup ever.
|
Possibly the simplest wiki setup ever.
|
||||||
EOF
|
EOF
|
||||||
s.author = 'David Heinemeier Hansson'
|
s.author = 'David Heinemeier Hansson'
|
||||||
s.email = 'david@loudthinking.com'
|
s.email = 'david@loudthinking.com'
|
||||||
s.rubyforge_project = 'instiki'
|
s.rubyforge_project = 'instiki'
|
||||||
s.homepage = 'http://www.instiki.org'
|
s.homepage = 'http://www.instiki.org'
|
||||||
|
|
||||||
s.bindir = '.'
|
s.bindir = '.'
|
||||||
s.executables = ['instiki']
|
s.executables = ['instiki']
|
||||||
s.default_executable = 'instiki'
|
s.default_executable = 'instiki'
|
||||||
|
|
||||||
s.has_rdoc = false
|
s.has_rdoc = false
|
||||||
|
|
||||||
s.add_dependency('RedCloth', '= 3.0.3')
|
s.add_dependency('RedCloth', '= 3.0.3')
|
||||||
s.add_dependency('rubyzip', '= 0.5.8')
|
s.add_dependency('rubyzip', '= 0.5.8')
|
||||||
s.add_dependency('rails', '= 0.13.1')
|
s.add_dependency('rails', '= 0.13.1')
|
||||||
s.add_dependency('sqlite3-ruby', '= 1.1.0')
|
s.add_dependency('sqlite3-ruby', '= 1.1.0')
|
||||||
s.requirements << 'none'
|
s.requirements << 'none'
|
||||||
s.require_path = 'lib'
|
s.require_path = 'lib'
|
||||||
|
|
||||||
s.files = $__instiki_source_patterns.inject([]) { |list, glob|
|
s.files = $__instiki_source_patterns.inject([]) { |list, glob|
|
||||||
list << Dir[glob].delete_if { |path|
|
list << Dir[glob].delete_if { |path|
|
||||||
File.directory?(path) or
|
File.directory?(path) or
|
||||||
path.include?('.svn/') or
|
path.include?('.svn/') or
|
||||||
path.include?('vendor/') or
|
path.include?('vendor/') or
|
||||||
path.include?('test/') or
|
path.include?('test/') or
|
||||||
path.include?('_test.rb')
|
path.include?('_test.rb')
|
||||||
}
|
}
|
||||||
}.flatten
|
}.flatten
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
require 'erb'
|
require 'erb'
|
||||||
|
|
||||||
def create_options
|
def create_options
|
||||||
if @db == 'mysql'
|
if @db == 'mysql'
|
||||||
'ENGINE = ' + (mysql_engine rescue @mysql_engine)
|
'ENGINE = ' + (mysql_engine rescue @mysql_engine)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def db_quote(column)
|
def db_quote(column)
|
||||||
case @db
|
case @db
|
||||||
when 'postgresql'
|
when 'postgresql'
|
||||||
return "\"#{column}\""
|
return "\"#{column}\""
|
||||||
when 'sqlite', 'sqlite3'
|
when 'sqlite', 'sqlite3'
|
||||||
return "'#{column}'"
|
return "'#{column}'"
|
||||||
when 'mysql'
|
when 'mysql'
|
||||||
return "`#{column}`"
|
return "`#{column}`"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def db_structure(db)
|
def db_structure(db)
|
||||||
db.downcase!
|
db.downcase!
|
||||||
@db = db
|
@db = db
|
||||||
case db
|
case db
|
||||||
when 'postgresql'
|
when 'postgresql'
|
||||||
@pk = 'SERIAL PRIMARY KEY'
|
@pk = 'SERIAL PRIMARY KEY'
|
||||||
@datetime = 'TIMESTAMP'
|
@datetime = 'TIMESTAMP'
|
||||||
@boolean = "BOOLEAN"
|
@boolean = "BOOLEAN"
|
||||||
when 'sqlite', 'sqlite3'
|
when 'sqlite', 'sqlite3'
|
||||||
@pk = 'INTEGER PRIMARY KEY'
|
@pk = 'INTEGER PRIMARY KEY'
|
||||||
@datetime = 'DATETIME'
|
@datetime = 'DATETIME'
|
||||||
@boolean = "INTEGER"
|
@boolean = "INTEGER"
|
||||||
when 'mysql'
|
when 'mysql'
|
||||||
@pk = 'INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY'
|
@pk = 'INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY'
|
||||||
@datetime = 'DATETIME'
|
@datetime = 'DATETIME'
|
||||||
@boolean = "TINYINT"
|
@boolean = "TINYINT"
|
||||||
@mysql_engine = 'InnoDB'
|
@mysql_engine = 'InnoDB'
|
||||||
else
|
else
|
||||||
raise "Unknown db type #{db}"
|
raise "Unknown db type #{db}"
|
||||||
end
|
end
|
||||||
|
|
||||||
s = ''
|
s = ''
|
||||||
Dir[RAILS_ROOT + '/db/*.erbsql'].each do |filename|
|
Dir[RAILS_ROOT + '/db/*.erbsql'].each do |filename|
|
||||||
s += ERB.new(File.read(filename)).result
|
s += ERB.new(File.read(filename)).result
|
||||||
end
|
end
|
||||||
s
|
s
|
||||||
end
|
end
|
||||||
|
|
108
test/fixtures/pages.yml
vendored
108
test/fixtures/pages.yml
vendored
|
@ -1,55 +1,55 @@
|
||||||
home_page:
|
home_page:
|
||||||
id: 1
|
id: 1
|
||||||
created_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
created_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
||||||
updated_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
updated_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
||||||
web_id: 1
|
web_id: 1
|
||||||
name: HomePage
|
name: HomePage
|
||||||
|
|
||||||
my_way:
|
my_way:
|
||||||
id: 2
|
id: 2
|
||||||
created_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
||||||
web_id: 1
|
web_id: 1
|
||||||
name: MyWay
|
name: MyWay
|
||||||
|
|
||||||
smart_engine:
|
smart_engine:
|
||||||
id: 3
|
id: 3
|
||||||
created_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
||||||
web_id: 1
|
web_id: 1
|
||||||
name: SmartEngine
|
name: SmartEngine
|
||||||
|
|
||||||
that_way:
|
that_way:
|
||||||
id: 4
|
id: 4
|
||||||
created_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
||||||
web_id: 1
|
web_id: 1
|
||||||
name: ThatWay
|
name: ThatWay
|
||||||
|
|
||||||
no_wiki_word:
|
no_wiki_word:
|
||||||
id: 5
|
id: 5
|
||||||
created_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
||||||
web_id: 1
|
web_id: 1
|
||||||
name: NoWikiWord
|
name: NoWikiWord
|
||||||
|
|
||||||
first_page:
|
first_page:
|
||||||
id: 6
|
id: 6
|
||||||
created_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
created_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
||||||
updated_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
updated_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
||||||
web_id: 1
|
web_id: 1
|
||||||
name: FirstPage
|
name: FirstPage
|
||||||
|
|
||||||
oak:
|
oak:
|
||||||
id: 7
|
id: 7
|
||||||
created_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
||||||
web_id: 1
|
web_id: 1
|
||||||
name: Oak
|
name: Oak
|
||||||
|
|
||||||
elephant:
|
elephant:
|
||||||
id: 8
|
id: 8
|
||||||
created_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
created_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
updated_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
||||||
web_id: 1
|
web_id: 1
|
||||||
name: Elephant
|
name: Elephant
|
166
test/fixtures/revisions.yml
vendored
166
test/fixtures/revisions.yml
vendored
|
@ -1,83 +1,83 @@
|
||||||
home_page_first_revision:
|
home_page_first_revision:
|
||||||
id: 1
|
id: 1
|
||||||
created_at: <%= Time.local(2004, 4, 4, 15, 50).to_formatted_s(:db) %>
|
created_at: <%= Time.local(2004, 4, 4, 15, 50).to_formatted_s(:db) %>
|
||||||
updated_at: <%= Time.local(2004, 4, 4, 15, 50).to_formatted_s(:db) %>
|
updated_at: <%= Time.local(2004, 4, 4, 15, 50).to_formatted_s(:db) %>
|
||||||
revised_at: <%= Time.local(2004, 4, 4, 15, 50).to_formatted_s(:db) %>
|
revised_at: <%= Time.local(2004, 4, 4, 15, 50).to_formatted_s(:db) %>
|
||||||
page_id: 1
|
page_id: 1
|
||||||
content: First revision of the HomePage end
|
content: First revision of the HomePage end
|
||||||
author: AnAuthor
|
author: AnAuthor
|
||||||
ip: 127.0.0.1
|
ip: 127.0.0.1
|
||||||
|
|
||||||
my_way_first_revision:
|
my_way_first_revision:
|
||||||
id: 2
|
id: 2
|
||||||
created_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
||||||
revised_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
revised_at: <%= 9.days.ago.to_formatted_s(:db) %>
|
||||||
page_id: 2
|
page_id: 2
|
||||||
content: MyWay
|
content: MyWay
|
||||||
author: Me
|
author: Me
|
||||||
|
|
||||||
smart_engine_first_revision:
|
smart_engine_first_revision:
|
||||||
id: 3
|
id: 3
|
||||||
created_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
||||||
revised_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
revised_at: <%= 8.days.ago.to_formatted_s(:db) %>
|
||||||
page_id: 3
|
page_id: 3
|
||||||
content: SmartEngine
|
content: SmartEngine
|
||||||
author: Me
|
author: Me
|
||||||
|
|
||||||
that_way_first_revision:
|
that_way_first_revision:
|
||||||
id: 4
|
id: 4
|
||||||
created_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
||||||
revised_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
revised_at: <%= 7.days.ago.to_formatted_s(:db) %>
|
||||||
page_id: 4
|
page_id: 4
|
||||||
content: ThatWay
|
content: ThatWay
|
||||||
author: Me
|
author: Me
|
||||||
|
|
||||||
no_wiki_word_first_revision:
|
no_wiki_word_first_revision:
|
||||||
id: 5
|
id: 5
|
||||||
created_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
||||||
revised_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
revised_at: <%= 6.days.ago.to_formatted_s(:db) %>
|
||||||
page_id: 5
|
page_id: 5
|
||||||
content: hey you
|
content: hey you
|
||||||
author: Me
|
author: Me
|
||||||
|
|
||||||
home_page_second_revision:
|
home_page_second_revision:
|
||||||
id: 6
|
id: 6
|
||||||
created_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
created_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
||||||
updated_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
updated_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
||||||
revised_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
revised_at: <%= Time.local(2004, 4, 4, 16, 50).to_formatted_s(:db) %>
|
||||||
page_id: 1
|
page_id: 1
|
||||||
content: HisWay would be MyWay in kinda ThatWay in HisWay though MyWay \OverThere -- see SmartEngine in that SmartEngineGUI
|
content: HisWay would be MyWay in kinda ThatWay in HisWay though MyWay \OverThere -- see SmartEngine in that SmartEngineGUI
|
||||||
author: DavidHeinemeierHansson
|
author: DavidHeinemeierHansson
|
||||||
|
|
||||||
first_page_first_revision:
|
first_page_first_revision:
|
||||||
id: 7
|
id: 7
|
||||||
created_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
created_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
||||||
updated_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
updated_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
||||||
revised_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
revised_at: <%= Time.local(2004, 4, 4, 16, 55).to_formatted_s(:db) %>
|
||||||
page_id: 6
|
page_id: 6
|
||||||
content: HisWay would be MyWay in kinda ThatWay in HisWay though MyWay \\OverThere -- see SmartEngine in that SmartEngineGUI
|
content: HisWay would be MyWay in kinda ThatWay in HisWay though MyWay \\OverThere -- see SmartEngine in that SmartEngineGUI
|
||||||
author: DavidHeinemeierHansson
|
author: DavidHeinemeierHansson
|
||||||
|
|
||||||
oak_first_revision:
|
oak_first_revision:
|
||||||
id: 8
|
id: 8
|
||||||
created_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
created_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
updated_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
||||||
revised_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
revised_at: <%= 5.days.ago.to_formatted_s(:db) %>
|
||||||
page_id: 7
|
page_id: 7
|
||||||
content: "All about oak.\ncategory: trees"
|
content: "All about oak.\ncategory: trees"
|
||||||
author: TreeHugger
|
author: TreeHugger
|
||||||
ip: 127.0.0.2
|
ip: 127.0.0.2
|
||||||
|
|
||||||
elephant_first_revision:
|
elephant_first_revision:
|
||||||
id: 9
|
id: 9
|
||||||
created_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
created_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
||||||
updated_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
updated_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
||||||
revised_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
revised_at: <%= 10.minutes.ago.to_formatted_s(:db) %>
|
||||||
page_id: 8
|
page_id: 8
|
||||||
content: "All about elephants.\ncategory: animals"
|
content: "All about elephants.\ncategory: animals"
|
||||||
author: Guest
|
author: Guest
|
||||||
ip: 127.0.0.2
|
ip: 127.0.0.2
|
||||||
|
|
28
test/fixtures/webs.yml
vendored
28
test/fixtures/webs.yml
vendored
|
@ -1,15 +1,15 @@
|
||||||
test_wiki:
|
test_wiki:
|
||||||
id: 1
|
id: 1
|
||||||
created_at: 2004-08-01
|
created_at: 2004-08-01
|
||||||
updated_at: 2005-08-01
|
updated_at: 2005-08-01
|
||||||
name: wiki1
|
name: wiki1
|
||||||
address: wiki1
|
address: wiki1
|
||||||
markup: textile
|
markup: textile
|
||||||
|
|
||||||
instiki:
|
instiki:
|
||||||
id: 2
|
id: 2
|
||||||
created_at: 2004-08-01
|
created_at: 2004-08-01
|
||||||
updated_at: 2005-08-01
|
updated_at: 2005-08-01
|
||||||
name: Instiki
|
name: Instiki
|
||||||
address: instiki
|
address: instiki
|
||||||
markup: textile
|
markup: textile
|
|
@ -1,106 +1,106 @@
|
||||||
ENV["RAILS_ENV"] = "test"
|
ENV["RAILS_ENV"] = "test"
|
||||||
|
|
||||||
# Expand the path to environment so that Ruby does not load it multiple times
|
# Expand the path to environment so that Ruby does not load it multiple times
|
||||||
# File.expand_path can be removed if Ruby 1.9 is in use.
|
# File.expand_path can be removed if Ruby 1.9 is in use.
|
||||||
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
||||||
require 'application'
|
require 'application'
|
||||||
|
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
require 'active_record/fixtures'
|
require 'active_record/fixtures'
|
||||||
require 'action_controller/test_process'
|
require 'action_controller/test_process'
|
||||||
require 'action_web_service/test_invoke'
|
require 'action_web_service/test_invoke'
|
||||||
require 'breakpoint'
|
require 'breakpoint'
|
||||||
require 'wiki_content'
|
require 'wiki_content'
|
||||||
|
|
||||||
# Uncomment these and hang on, because the tests will be FAST
|
# Uncomment these and hang on, because the tests will be FAST
|
||||||
#Test::Unit::TestCase.pre_loaded_fixtures = false
|
#Test::Unit::TestCase.pre_loaded_fixtures = false
|
||||||
#Test::Unit::TestCase.use_transactional_fixtures = true
|
#Test::Unit::TestCase.use_transactional_fixtures = true
|
||||||
|
|
||||||
Test::Unit::TestCase.use_instantiated_fixtures = false
|
Test::Unit::TestCase.use_instantiated_fixtures = false
|
||||||
Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
|
Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
|
||||||
|
|
||||||
class Test::Unit::TestCase
|
class Test::Unit::TestCase
|
||||||
def create_fixtures(*table_names)
|
def create_fixtures(*table_names)
|
||||||
Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures", table_names)
|
Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures", table_names)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add more helper methods to be used by all tests here...
|
# Add more helper methods to be used by all tests here...
|
||||||
def set_web_property(property, value)
|
def set_web_property(property, value)
|
||||||
@web.update_attribute(property, value)
|
@web.update_attribute(property, value)
|
||||||
@page = Page.find(@page.id)
|
@page = Page.find(@page.id)
|
||||||
@wiki.webs[@web.name] = @web
|
@wiki.webs[@web.name] = @web
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_wiki_with_30_pages
|
def setup_wiki_with_30_pages
|
||||||
ActiveRecord::Base.silence do
|
ActiveRecord::Base.silence do
|
||||||
(1..30).each do |i|
|
(1..30).each do |i|
|
||||||
@wiki.write_page('wiki1', "page#{i}", "Test page #{i}\ncategory: test",
|
@wiki.write_page('wiki1', "page#{i}", "Test page #{i}\ncategory: test",
|
||||||
Time.local(1976, 10, i, 12, 00, 00), Author.new('Dema', '127.0.0.2'))
|
Time.local(1976, 10, i, 12, 00, 00), Author.new('Dema', '127.0.0.2'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@web = Web.find(@web.id)
|
@web = Web.find(@web.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def use_blank_wiki
|
def use_blank_wiki
|
||||||
Revision.destroy_all
|
Revision.destroy_all
|
||||||
Page.destroy_all
|
Page.destroy_all
|
||||||
Web.destroy_all
|
Web.destroy_all
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# This module is to be included in unit tests that involve matching chunks.
|
# This module is to be included in unit tests that involve matching chunks.
|
||||||
# It provides a easy way to test whether a chunk matches a particular string
|
# It provides a easy way to test whether a chunk matches a particular string
|
||||||
# and any the values of any fields that should be set after a match.
|
# and any the values of any fields that should be set after a match.
|
||||||
class ContentStub < String
|
class ContentStub < String
|
||||||
include ChunkManager
|
include ChunkManager
|
||||||
def initialize(str)
|
def initialize(str)
|
||||||
super
|
super
|
||||||
init_chunk_manager
|
init_chunk_manager
|
||||||
end
|
end
|
||||||
def page_link(*); end
|
def page_link(*); end
|
||||||
end
|
end
|
||||||
|
|
||||||
module ChunkMatch
|
module ChunkMatch
|
||||||
|
|
||||||
# Asserts a number of tests for the given type and text.
|
# Asserts a number of tests for the given type and text.
|
||||||
def match(chunk_type, test_text, expected_chunk_state)
|
def match(chunk_type, test_text, expected_chunk_state)
|
||||||
if chunk_type.respond_to? :pattern
|
if chunk_type.respond_to? :pattern
|
||||||
assert_match(chunk_type.pattern, test_text)
|
assert_match(chunk_type.pattern, test_text)
|
||||||
end
|
end
|
||||||
|
|
||||||
content = ContentStub.new(test_text)
|
content = ContentStub.new(test_text)
|
||||||
chunk_type.apply_to(content)
|
chunk_type.apply_to(content)
|
||||||
|
|
||||||
# Test if requested parts are correct.
|
# Test if requested parts are correct.
|
||||||
expected_chunk_state.each_pair do |a_method, expected_value|
|
expected_chunk_state.each_pair do |a_method, expected_value|
|
||||||
assert content.chunks.last.kind_of?(chunk_type)
|
assert content.chunks.last.kind_of?(chunk_type)
|
||||||
assert_respond_to(content.chunks.last, a_method)
|
assert_respond_to(content.chunks.last, a_method)
|
||||||
assert_equal(expected_value, content.chunks.last.send(a_method.to_sym),
|
assert_equal(expected_value, content.chunks.last.send(a_method.to_sym),
|
||||||
"Wrong #{a_method} value")
|
"Wrong #{a_method} value")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Asserts that test_text doesn't match the chunk_type
|
# Asserts that test_text doesn't match the chunk_type
|
||||||
def no_match(chunk_type, test_text)
|
def no_match(chunk_type, test_text)
|
||||||
if chunk_type.respond_to? :pattern
|
if chunk_type.respond_to? :pattern
|
||||||
assert_no_match(chunk_type.pattern, test_text)
|
assert_no_match(chunk_type.pattern, test_text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if defined? $validate_xml_in_assert_success and $validate_xml_in_assert_success == true
|
if defined? $validate_xml_in_assert_success and $validate_xml_in_assert_success == true
|
||||||
module Test
|
module Test
|
||||||
module Unit
|
module Unit
|
||||||
module Assertions
|
module Assertions
|
||||||
unless method_defined? :__assert_success_before_override_by_instiki
|
unless method_defined? :__assert_success_before_override_by_instiki
|
||||||
alias :__assert_success_before_override_by_instiki :assert_success
|
alias :__assert_success_before_override_by_instiki :assert_success
|
||||||
end
|
end
|
||||||
def assert_success
|
def assert_success
|
||||||
__assert_success_before_override_by_instiki
|
__assert_success_before_override_by_instiki
|
||||||
if @response.body.kind_of?(Proc) then # it's a file download, not an HTML content
|
if @response.body.kind_of?(Proc) then # it's a file download, not an HTML content
|
||||||
else assert_nothing_raised(@response.body) { REXML::Document.new(@response.body) } end
|
else assert_nothing_raised(@response.body) { REXML::Document.new(@response.body) } end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,88 +1,88 @@
|
||||||
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
||||||
|
|
||||||
class PageTest < Test::Unit::TestCase
|
class PageTest < Test::Unit::TestCase
|
||||||
fixtures :webs, :pages, :revisions, :system
|
fixtures :webs, :pages, :revisions, :system
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@page = pages(:first_page)
|
@page = pages(:first_page)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_lock
|
def test_lock
|
||||||
assert !@page.locked?(Time.local(2004, 4, 4, 16, 50))
|
assert !@page.locked?(Time.local(2004, 4, 4, 16, 50))
|
||||||
|
|
||||||
@page.lock(Time.local(2004, 4, 4, 16, 30), "DavidHeinemeierHansson")
|
@page.lock(Time.local(2004, 4, 4, 16, 30), "DavidHeinemeierHansson")
|
||||||
|
|
||||||
assert @page.locked?(Time.local(2004, 4, 4, 16, 50))
|
assert @page.locked?(Time.local(2004, 4, 4, 16, 50))
|
||||||
assert !@page.locked?(Time.local(2004, 4, 4, 17, 1))
|
assert !@page.locked?(Time.local(2004, 4, 4, 17, 1))
|
||||||
|
|
||||||
@page.unlock
|
@page.unlock
|
||||||
|
|
||||||
assert !@page.locked?(Time.local(2004, 4, 4, 16, 50))
|
assert !@page.locked?(Time.local(2004, 4, 4, 16, 50))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_lock_duration
|
def test_lock_duration
|
||||||
@page.lock(Time.local(2004, 4, 4, 16, 30), "DavidHeinemeierHansson")
|
@page.lock(Time.local(2004, 4, 4, 16, 30), "DavidHeinemeierHansson")
|
||||||
|
|
||||||
assert_equal 15, @page.lock_duration(Time.local(2004, 4, 4, 16, 45))
|
assert_equal 15, @page.lock_duration(Time.local(2004, 4, 4, 16, 45))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_plain_name
|
def test_plain_name
|
||||||
assert_equal "First Page", @page.plain_name
|
assert_equal "First Page", @page.plain_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_revise
|
def test_revise
|
||||||
@page.revise('HisWay would be MyWay in kinda lame', Time.local(2004, 4, 4, 16, 55), 'MarianneSyhler')
|
@page.revise('HisWay would be MyWay in kinda lame', Time.local(2004, 4, 4, 16, 55), 'MarianneSyhler')
|
||||||
@page.reload
|
@page.reload
|
||||||
|
|
||||||
assert_equal 2, @page.revisions.length, 'Should have two revisions'
|
assert_equal 2, @page.revisions.length, 'Should have two revisions'
|
||||||
assert_equal 'MarianneSyhler', @page.current_revision.author.to_s, 'Mary should be the author now'
|
assert_equal 'MarianneSyhler', @page.current_revision.author.to_s, 'Mary should be the author now'
|
||||||
assert_equal 'DavidHeinemeierHansson', @page.revisions.first.author.to_s, 'David was the first author'
|
assert_equal 'DavidHeinemeierHansson', @page.revisions.first.author.to_s, 'David was the first author'
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_revise_continous_revision
|
def test_revise_continous_revision
|
||||||
@page.revise('HisWay would be MyWay in kinda lame', Time.local(2004, 4, 4, 16, 55), 'MarianneSyhler')
|
@page.revise('HisWay would be MyWay in kinda lame', Time.local(2004, 4, 4, 16, 55), 'MarianneSyhler')
|
||||||
@page.reload
|
@page.reload
|
||||||
assert_equal 2, @page.revisions.length
|
assert_equal 2, @page.revisions.length
|
||||||
assert_equal 'HisWay would be MyWay in kinda lame', @page.content
|
assert_equal 'HisWay would be MyWay in kinda lame', @page.content
|
||||||
|
|
||||||
# consecutive revision by the same author within 30 minutes doesn't create a new revision
|
# consecutive revision by the same author within 30 minutes doesn't create a new revision
|
||||||
@page.revise('HisWay would be MyWay in kinda update', Time.local(2004, 4, 4, 16, 57), 'MarianneSyhler')
|
@page.revise('HisWay would be MyWay in kinda update', Time.local(2004, 4, 4, 16, 57), 'MarianneSyhler')
|
||||||
@page.reload
|
@page.reload
|
||||||
assert_equal 2, @page.revisions.length
|
assert_equal 2, @page.revisions.length
|
||||||
assert_equal 'HisWay would be MyWay in kinda update', @page.content
|
assert_equal 'HisWay would be MyWay in kinda update', @page.content
|
||||||
assert_equal Time.local(2004, 4, 4, 16, 57), @page.revised_at
|
assert_equal Time.local(2004, 4, 4, 16, 57), @page.revised_at
|
||||||
|
|
||||||
# but consecutive revision by another author results in a new revision
|
# but consecutive revision by another author results in a new revision
|
||||||
@page.revise('HisWay would be MyWay in the house', Time.local(2004, 4, 4, 16, 58), 'DavidHeinemeierHansson')
|
@page.revise('HisWay would be MyWay in the house', Time.local(2004, 4, 4, 16, 58), 'DavidHeinemeierHansson')
|
||||||
@page.reload
|
@page.reload
|
||||||
assert_equal 3, @page.revisions.length
|
assert_equal 3, @page.revisions.length
|
||||||
assert_equal 'HisWay would be MyWay in the house', @page.content
|
assert_equal 'HisWay would be MyWay in the house', @page.content
|
||||||
|
|
||||||
# consecutive update after 30 minutes since the last one also creates a new revision,
|
# consecutive update after 30 minutes since the last one also creates a new revision,
|
||||||
# even when it is by the same author
|
# even when it is by the same author
|
||||||
@page.revise('HisWay would be MyWay in my way', Time.local(2004, 4, 4, 17, 30), 'DavidHeinemeierHansson')
|
@page.revise('HisWay would be MyWay in my way', Time.local(2004, 4, 4, 17, 30), 'DavidHeinemeierHansson')
|
||||||
@page.reload
|
@page.reload
|
||||||
assert_equal 4, @page.revisions.length
|
assert_equal 4, @page.revisions.length
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_revise_content_unchanged
|
def test_revise_content_unchanged
|
||||||
last_revision_before = @page.current_revision
|
last_revision_before = @page.current_revision
|
||||||
revisions_number_before = @page.revisions.size
|
revisions_number_before = @page.revisions.size
|
||||||
|
|
||||||
assert_raises(Instiki::ValidationError) {
|
assert_raises(Instiki::ValidationError) {
|
||||||
@page.revise(@page.current_revision.content, Time.now, 'AlexeyVerkhovsky')
|
@page.revise(@page.current_revision.content, Time.now, 'AlexeyVerkhovsky')
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_equal last_revision_before, @page.current_revision(true)
|
assert_equal last_revision_before, @page.current_revision(true)
|
||||||
assert_equal revisions_number_before, @page.revisions.size
|
assert_equal revisions_number_before, @page.revisions.size
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_rollback
|
def test_rollback
|
||||||
@page.revise("spot two", Time.now, "David")
|
@page.revise("spot two", Time.now, "David")
|
||||||
@page.revise("spot three", Time.now + 2000, "David")
|
@page.revise("spot three", Time.now + 2000, "David")
|
||||||
assert_equal 3, @page.revisions(true).length, "Should have three revisions"
|
assert_equal 3, @page.revisions(true).length, "Should have three revisions"
|
||||||
@page.current_revision(true)
|
@page.current_revision(true)
|
||||||
@page.rollback(0, Time.now)
|
@page.rollback(0, Time.now)
|
||||||
assert_equal "HisWay would be MyWay in kinda ThatWay in HisWay though MyWay \\\\OverThere -- see SmartEngine in that SmartEngineGUI", @page.current_revision(true).content
|
assert_equal "HisWay would be MyWay in kinda ThatWay in HisWay though MyWay \\\\OverThere -- see SmartEngine in that SmartEngineGUI", @page.current_revision(true).content
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,317 +1,317 @@
|
||||||
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
||||||
|
|
||||||
class RevisionTest < Test::Unit::TestCase
|
class RevisionTest < Test::Unit::TestCase
|
||||||
fixtures :webs, :pages, :revisions, :system
|
fixtures :webs, :pages, :revisions, :system
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@wiki = Wiki.new
|
@wiki = Wiki.new
|
||||||
@web = webs(:test_wiki)
|
@web = webs(:test_wiki)
|
||||||
@page = pages(:home_page)
|
@page = pages(:home_page)
|
||||||
@revision = revisions(:home_page_second_revision)
|
@revision = revisions(:home_page_second_revision)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_wiki_words
|
def test_wiki_words
|
||||||
assert_equal %w( HisWay MyWay SmartEngine SmartEngineGUI ThatWay ), @revision.wiki_words.sort
|
assert_equal %w( HisWay MyWay SmartEngine SmartEngineGUI ThatWay ), @revision.wiki_words.sort
|
||||||
|
|
||||||
@wiki.write_page('wiki1', 'NoWikiWord', 'hey you!', Time.now, 'Me')
|
@wiki.write_page('wiki1', 'NoWikiWord', 'hey you!', Time.now, 'Me')
|
||||||
assert_equal [], @wiki.read_page('wiki1', 'NoWikiWord').wiki_words
|
assert_equal [], @wiki.read_page('wiki1', 'NoWikiWord').wiki_words
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_existing_pages
|
def test_existing_pages
|
||||||
assert_equal %w( MyWay SmartEngine ThatWay ), @revision.existing_pages.sort
|
assert_equal %w( MyWay SmartEngine ThatWay ), @revision.existing_pages.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_unexisting_pages
|
def test_unexisting_pages
|
||||||
assert_equal %w( HisWay SmartEngineGUI ), @revision.unexisting_pages.sort
|
assert_equal %w( HisWay SmartEngineGUI ), @revision.unexisting_pages.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_wiki_links
|
def test_content_with_wiki_links
|
||||||
assert_equal '<p><span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' +
|
assert_equal '<p><span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' +
|
||||||
'would be <a class="existingWikiWord" href="../show/MyWay">My Way</a> in kinda ' +
|
'would be <a class="existingWikiWord" href="../show/MyWay">My Way</a> in kinda ' +
|
||||||
'<a class="existingWikiWord" href="../show/ThatWay">That Way</a> in ' +
|
'<a class="existingWikiWord" href="../show/ThatWay">That Way</a> in ' +
|
||||||
'<span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' +
|
'<span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' +
|
||||||
'though <a class="existingWikiWord" href="../show/MyWay">My Way</a> OverThere—see ' +
|
'though <a class="existingWikiWord" href="../show/MyWay">My Way</a> OverThere—see ' +
|
||||||
'<a class="existingWikiWord" href="../show/SmartEngine">Smart Engine</a> in that ' +
|
'<a class="existingWikiWord" href="../show/SmartEngine">Smart Engine</a> in that ' +
|
||||||
'<span class="newWikiWord">Smart Engine GUI' +
|
'<span class="newWikiWord">Smart Engine GUI' +
|
||||||
'<a href="../show/SmartEngineGUI">?</a></span></p>',
|
'<a href="../show/SmartEngineGUI">?</a></span></p>',
|
||||||
@revision.display_content
|
@revision.display_content
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_markdown
|
def test_markdown
|
||||||
set_web_property :markup, :markdown
|
set_web_property :markup, :markdown
|
||||||
|
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
%{<h1>My Headline</h1>\n\n<p>that <span class="newWikiWord">} +
|
%{<h1>My Headline</h1>\n\n<p>that <span class="newWikiWord">} +
|
||||||
%{Smart Engine GUI<a href="../show/SmartEngineGUI">?</a></span></p>},
|
%{Smart Engine GUI<a href="../show/SmartEngineGUI">?</a></span></p>},
|
||||||
"My Headline\n===========\n\nthat SmartEngineGUI")
|
"My Headline\n===========\n\nthat SmartEngineGUI")
|
||||||
|
|
||||||
code_block = [
|
code_block = [
|
||||||
'This is a code block:',
|
'This is a code block:',
|
||||||
'',
|
'',
|
||||||
' def a_method(arg)',
|
' def a_method(arg)',
|
||||||
' return ThatWay',
|
' return ThatWay',
|
||||||
'',
|
'',
|
||||||
'Nice!'
|
'Nice!'
|
||||||
].join("\n")
|
].join("\n")
|
||||||
|
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
%{<p>This is a code block:</p>\n\n<pre><code>def a_method(arg)\n} +
|
%{<p>This is a code block:</p>\n\n<pre><code>def a_method(arg)\n} +
|
||||||
%{return ThatWay\n</code></pre>\n\n<p>Nice!</p>},
|
%{return ThatWay\n</code></pre>\n\n<p>Nice!</p>},
|
||||||
code_block)
|
code_block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_markdown_hyperlink_with_slash
|
def test_markdown_hyperlink_with_slash
|
||||||
# in response to a bug, see http://dev.instiki.org/attachment/ticket/177
|
# in response to a bug, see http://dev.instiki.org/attachment/ticket/177
|
||||||
set_web_property :markup, :markdown
|
set_web_property :markup, :markdown
|
||||||
|
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><a href="http://example/with/slash">text</a></p>',
|
'<p><a href="http://example/with/slash">text</a></p>',
|
||||||
'[text](http://example/with/slash)')
|
'[text](http://example/with/slash)')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_mixed_formatting
|
def test_mixed_formatting
|
||||||
textile_and_markdown = [
|
textile_and_markdown = [
|
||||||
'Markdown heading',
|
'Markdown heading',
|
||||||
'================',
|
'================',
|
||||||
'',
|
'',
|
||||||
'h2. Textile heading',
|
'h2. Textile heading',
|
||||||
'',
|
'',
|
||||||
'*some* **text** _with_ -styles-',
|
'*some* **text** _with_ -styles-',
|
||||||
'',
|
'',
|
||||||
'* list 1',
|
'* list 1',
|
||||||
'* list 2'
|
'* list 2'
|
||||||
].join("\n")
|
].join("\n")
|
||||||
|
|
||||||
set_web_property :markup, :markdown
|
set_web_property :markup, :markdown
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
"<h1>Markdown heading</h1>\n\n" +
|
"<h1>Markdown heading</h1>\n\n" +
|
||||||
"<p>h2. Textile heading</p>\n\n" +
|
"<p>h2. Textile heading</p>\n\n" +
|
||||||
"<p><em>some</em> <strong>text</strong> <em>with</em> -styles-</p>\n\n" +
|
"<p><em>some</em> <strong>text</strong> <em>with</em> -styles-</p>\n\n" +
|
||||||
"<ul>\n<li>list 1</li>\n<li>list 2</li>\n</ul>",
|
"<ul>\n<li>list 1</li>\n<li>list 2</li>\n</ul>",
|
||||||
textile_and_markdown)
|
textile_and_markdown)
|
||||||
|
|
||||||
set_web_property :markup, :textile
|
set_web_property :markup, :textile
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
"<p>Markdown heading<br />================</p>\n\n\n\t<h2>Textile heading</h2>" +
|
"<p>Markdown heading<br />================</p>\n\n\n\t<h2>Textile heading</h2>" +
|
||||||
"\n\n\n\t<p><strong>some</strong> <b>text</b> <em>with</em> <del>styles</del></p>" +
|
"\n\n\n\t<p><strong>some</strong> <b>text</b> <em>with</em> <del>styles</del></p>" +
|
||||||
"\n\n\n\t<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
|
"\n\n\n\t<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
|
||||||
textile_and_markdown)
|
textile_and_markdown)
|
||||||
|
|
||||||
set_web_property :markup, :mixed
|
set_web_property :markup, :mixed
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
"<h1>Markdown heading</h1>\n\n\n\t<h2>Textile heading</h2>\n\n\n\t" +
|
"<h1>Markdown heading</h1>\n\n\n\t<h2>Textile heading</h2>\n\n\n\t" +
|
||||||
"<p><strong>some</strong> <b>text</b> <em>with</em> <del>styles</del></p>\n\n\n\t" +
|
"<p><strong>some</strong> <b>text</b> <em>with</em> <del>styles</del></p>\n\n\n\t" +
|
||||||
"<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
|
"<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
|
||||||
textile_and_markdown)
|
textile_and_markdown)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_rdoc
|
def test_rdoc
|
||||||
set_web_property :markup, :rdoc
|
set_web_property :markup, :rdoc
|
||||||
|
|
||||||
@revision = Revision.new(:page => @page, :content => '+hello+ that SmartEngineGUI',
|
@revision = Revision.new(:page => @page, :content => '+hello+ that SmartEngineGUI',
|
||||||
:author => Author.new('DavidHeinemeierHansson'))
|
:author => Author.new('DavidHeinemeierHansson'))
|
||||||
|
|
||||||
assert_equal "<tt>hello</tt> that <span class=\"newWikiWord\">Smart Engine GUI" +
|
assert_equal "<tt>hello</tt> that <span class=\"newWikiWord\">Smart Engine GUI" +
|
||||||
"<a href=\"../show/SmartEngineGUI\">?</a></span>\n\n", @revision.display_content
|
"<a href=\"../show/SmartEngineGUI\">?</a></span>\n\n", @revision.display_content
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_auto_links
|
def test_content_with_auto_links
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><a href="http://www.loudthinking.com/">http://www.loudthinking.com/</a> ' +
|
'<p><a href="http://www.loudthinking.com/">http://www.loudthinking.com/</a> ' +
|
||||||
'points to <a class="existingWikiWord" href="../show/ThatWay">That Way</a> from ' +
|
'points to <a class="existingWikiWord" href="../show/ThatWay">That Way</a> from ' +
|
||||||
'<a href="mailto:david@loudthinking.com">david@loudthinking.com</a></p>',
|
'<a href="mailto:david@loudthinking.com">david@loudthinking.com</a></p>',
|
||||||
'http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com')
|
'http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_aliased_links
|
def test_content_with_aliased_links
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>Would a <a class="existingWikiWord" href="../show/SmartEngine">clever motor' +
|
'<p>Would a <a class="existingWikiWord" href="../show/SmartEngine">clever motor' +
|
||||||
'</a> go by any other name?</p>',
|
'</a> go by any other name?</p>',
|
||||||
'Would a [[SmartEngine|clever motor]] go by any other name?')
|
'Would a [[SmartEngine|clever motor]] go by any other name?')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_wikiword_in_em
|
def test_content_with_wikiword_in_em
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><em>should we go <a class="existingWikiWord" href="../show/ThatWay">' +
|
'<p><em>should we go <a class="existingWikiWord" href="../show/ThatWay">' +
|
||||||
'That Way</a> or <span class="newWikiWord">This Way<a href="../show/ThisWay">?</a>' +
|
'That Way</a> or <span class="newWikiWord">This Way<a href="../show/ThisWay">?</a>' +
|
||||||
'</span> </em></p>',
|
'</span> </em></p>',
|
||||||
'_should we go ThatWay or ThisWay _')
|
'_should we go ThatWay or ThisWay _')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_wikiword_in_tag
|
def test_content_with_wikiword_in_tag
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>That is some <em style="WikiWord">Stylish Emphasis</em></p>',
|
'<p>That is some <em style="WikiWord">Stylish Emphasis</em></p>',
|
||||||
'That is some <em style="WikiWord">Stylish Emphasis</em>')
|
'That is some <em style="WikiWord">Stylish Emphasis</em>')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_escaped_wikiword
|
def test_content_with_escaped_wikiword
|
||||||
# there should be no wiki link
|
# there should be no wiki link
|
||||||
assert_markup_parsed_as('<p>WikiWord</p>', '\WikiWord')
|
assert_markup_parsed_as('<p>WikiWord</p>', '\WikiWord')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_pre_blocks
|
def test_content_with_pre_blocks
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre></p>',
|
'<p>A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre></p>',
|
||||||
'A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre>')
|
'A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre>')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_autolink_in_parentheses
|
def test_content_with_autolink_in_parentheses
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>The <span class="caps">W3C</span> body (<a href="http://www.w3c.org">' +
|
'<p>The <span class="caps">W3C</span> body (<a href="http://www.w3c.org">' +
|
||||||
'http://www.w3c.org</a>) sets web standards</p>',
|
'http://www.w3c.org</a>) sets web standards</p>',
|
||||||
'The W3C body (http://www.w3c.org) sets web standards')
|
'The W3C body (http://www.w3c.org) sets web standards')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_link_in_parentheses
|
def test_content_with_link_in_parentheses
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>(<a href="http://wiki.org/wiki.cgi?WhatIsWiki">What is a wiki?</a>)</p>',
|
'<p>(<a href="http://wiki.org/wiki.cgi?WhatIsWiki">What is a wiki?</a>)</p>',
|
||||||
'("What is a wiki?":http://wiki.org/wiki.cgi?WhatIsWiki)')
|
'("What is a wiki?":http://wiki.org/wiki.cgi?WhatIsWiki)')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_image_link
|
def test_content_with_image_link
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is a Textile image link.</p>',
|
'<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is a Textile image link.</p>',
|
||||||
'This !http://hobix.com/sample.jpg! is a Textile image link.')
|
'This !http://hobix.com/sample.jpg! is a Textile image link.')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_inlined_img_tag
|
def test_content_with_inlined_img_tag
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is an inline image link.</p>',
|
'<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is an inline image link.</p>',
|
||||||
'This <img src="http://hobix.com/sample.jpg" alt="" /> is an inline image link.')
|
'This <img src="http://hobix.com/sample.jpg" alt="" /> is an inline image link.')
|
||||||
|
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>This <IMG SRC="http://hobix.com/sample.jpg" alt=""> is an inline image link.</p>',
|
'<p>This <IMG SRC="http://hobix.com/sample.jpg" alt=""> is an inline image link.</p>',
|
||||||
'This <IMG SRC="http://hobix.com/sample.jpg" alt=""> is an inline image link.')
|
'This <IMG SRC="http://hobix.com/sample.jpg" alt=""> is an inline image link.')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_nowiki_tag
|
def test_nowiki_tag
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>Do not mark up [[this text]] or http://www.thislink.com.</p>',
|
'<p>Do not mark up [[this text]] or http://www.thislink.com.</p>',
|
||||||
'Do not mark up <nowiki>[[this text]]</nowiki> ' +
|
'Do not mark up <nowiki>[[this text]]</nowiki> ' +
|
||||||
'or <nowiki>http://www.thislink.com</nowiki>.')
|
'or <nowiki>http://www.thislink.com</nowiki>.')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_multiline_nowiki_tag
|
def test_multiline_nowiki_tag
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
"<p>Do not mark \n up [[this text]] \nand http://this.url.com but markup " +
|
"<p>Do not mark \n up [[this text]] \nand http://this.url.com but markup " +
|
||||||
'<span class="newWikiWord">this<a href="../show/this">?</a></span></p>',
|
'<span class="newWikiWord">this<a href="../show/this">?</a></span></p>',
|
||||||
"Do not <nowiki>mark \n up [[this text]] \n" +
|
"Do not <nowiki>mark \n up [[this text]] \n" +
|
||||||
"and http://this.url.com </nowiki> but markup [[this]]")
|
"and http://this.url.com </nowiki> but markup [[this]]")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_with_bracketted_wiki_word
|
def test_content_with_bracketted_wiki_word
|
||||||
set_web_property :brackets_only, true
|
set_web_property :brackets_only, true
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p>This is a WikiWord and a tricky name <span class="newWikiWord">' +
|
'<p>This is a WikiWord and a tricky name <span class="newWikiWord">' +
|
||||||
'Sperberg-McQueen<a href="../show/Sperberg-McQueen">?</a></span>.</p>',
|
'Sperberg-McQueen<a href="../show/Sperberg-McQueen">?</a></span>.</p>',
|
||||||
'This is a WikiWord and a tricky name [[Sperberg-McQueen]].')
|
'This is a WikiWord and a tricky name [[Sperberg-McQueen]].')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_content_for_export
|
def test_content_for_export
|
||||||
assert_equal '<p><span class="newWikiWord">His Way</span> would be ' +
|
assert_equal '<p><span class="newWikiWord">His Way</span> would be ' +
|
||||||
'<a class="existingWikiWord" href="MyWay.html">My Way</a> in kinda ' +
|
'<a class="existingWikiWord" href="MyWay.html">My Way</a> in kinda ' +
|
||||||
'<a class="existingWikiWord" href="ThatWay.html">That Way</a> in ' +
|
'<a class="existingWikiWord" href="ThatWay.html">That Way</a> in ' +
|
||||||
'<span class="newWikiWord">His Way</span> though ' +
|
'<span class="newWikiWord">His Way</span> though ' +
|
||||||
'<a class="existingWikiWord" href="MyWay.html">My Way</a> OverThere—see ' +
|
'<a class="existingWikiWord" href="MyWay.html">My Way</a> OverThere—see ' +
|
||||||
'<a class="existingWikiWord" href="SmartEngine.html">Smart Engine</a> in that ' +
|
'<a class="existingWikiWord" href="SmartEngine.html">Smart Engine</a> in that ' +
|
||||||
'<span class="newWikiWord">Smart Engine GUI</span></p>',
|
'<span class="newWikiWord">Smart Engine GUI</span></p>',
|
||||||
@revision.display_content_for_export
|
@revision.display_content_for_export
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_double_replacing
|
def test_double_replacing
|
||||||
@revision.content = "VersionHistory\r\n\r\ncry VersionHistory"
|
@revision.content = "VersionHistory\r\n\r\ncry VersionHistory"
|
||||||
assert_equal '<p><span class="newWikiWord">Version History' +
|
assert_equal '<p><span class="newWikiWord">Version History' +
|
||||||
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
|
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
|
||||||
'<span class="newWikiWord">Version History<a href="../show/VersionHistory">?</a>' +
|
'<span class="newWikiWord">Version History<a href="../show/VersionHistory">?</a>' +
|
||||||
'</span></p>',
|
'</span></p>',
|
||||||
@revision.display_content
|
@revision.display_content
|
||||||
|
|
||||||
@revision.clear_display_cache
|
@revision.clear_display_cache
|
||||||
|
|
||||||
@revision.content = "f\r\nVersionHistory\r\n\r\ncry VersionHistory"
|
@revision.content = "f\r\nVersionHistory\r\n\r\ncry VersionHistory"
|
||||||
assert_equal "<p>f<br /><span class=\"newWikiWord\">Version History" +
|
assert_equal "<p>f<br /><span class=\"newWikiWord\">Version History" +
|
||||||
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
|
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
|
||||||
"<span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a>" +
|
"<span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a>" +
|
||||||
"</span></p>",
|
"</span></p>",
|
||||||
@revision.display_content
|
@revision.display_content
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_difficult_wiki_words
|
def test_difficult_wiki_words
|
||||||
@revision.content = "[[It's just awesome GUI!]]"
|
@revision.content = "[[It's just awesome GUI!]]"
|
||||||
assert_equal "<p><span class=\"newWikiWord\">It's just awesome GUI!" +
|
assert_equal "<p><span class=\"newWikiWord\">It's just awesome GUI!" +
|
||||||
"<a href=\"../show/It%27s+just+awesome+GUI%21\">?</a></span></p>",
|
"<a href=\"../show/It%27s+just+awesome+GUI%21\">?</a></span></p>",
|
||||||
@revision.display_content
|
@revision.display_content
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_revisions_diff
|
def test_revisions_diff
|
||||||
Revision.create(:page => @page, :content => 'What a blue and lovely morning',
|
Revision.create(:page => @page, :content => 'What a blue and lovely morning',
|
||||||
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
|
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
|
||||||
Revision.create(:page => @page, :content => 'What a red and lovely morning today',
|
Revision.create(:page => @page, :content => 'What a red and lovely morning today',
|
||||||
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
|
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
|
||||||
|
|
||||||
assert_equal "<p>What a <del class=\"diffmod\">blue </del><ins class=\"diffmod\">red " +
|
assert_equal "<p>What a <del class=\"diffmod\">blue </del><ins class=\"diffmod\">red " +
|
||||||
"</ins>and lovely <del class=\"diffmod\">morning</del><ins class=\"diffmod\">morning " +
|
"</ins>and lovely <del class=\"diffmod\">morning</del><ins class=\"diffmod\">morning " +
|
||||||
"today</ins></p>", @page.revisions.last.display_diff
|
"today</ins></p>", @page.revisions.last.display_diff
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_link_to_file
|
def test_link_to_file
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><span class="newWikiWord">doc.pdf<a href="../file/doc.pdf">?</a></span></p>',
|
'<p><span class="newWikiWord">doc.pdf<a href="../file/doc.pdf">?</a></span></p>',
|
||||||
'[[doc.pdf:file]]')
|
'[[doc.pdf:file]]')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_link_to_pic
|
def test_link_to_pic
|
||||||
FileUtils.mkdir_p "#{RAILS_ROOT}/storage/test/wiki1"
|
FileUtils.mkdir_p "#{RAILS_ROOT}/storage/test/wiki1"
|
||||||
FileUtils.rm(Dir["#{RAILS_ROOT}/storage/test/wiki1/*"])
|
FileUtils.rm(Dir["#{RAILS_ROOT}/storage/test/wiki1/*"])
|
||||||
@wiki.file_yard(@web).upload_file('square.jpg', StringIO.new(''))
|
@wiki.file_yard(@web).upload_file('square.jpg', StringIO.new(''))
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><img alt="Square" src="../pic/square.jpg" /></p>',
|
'<p><img alt="Square" src="../pic/square.jpg" /></p>',
|
||||||
'[[square.jpg|Square:pic]]')
|
'[[square.jpg|Square:pic]]')
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><img alt="square.jpg" src="../pic/square.jpg" /></p>',
|
'<p><img alt="square.jpg" src="../pic/square.jpg" /></p>',
|
||||||
'[[square.jpg:pic]]')
|
'[[square.jpg:pic]]')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_link_to_non_existant_pic
|
def test_link_to_non_existant_pic
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><span class="newWikiWord">NonExistant<a href="../pic/NonExistant.jpg">?</a>' +
|
'<p><span class="newWikiWord">NonExistant<a href="../pic/NonExistant.jpg">?</a>' +
|
||||||
'</span></p>',
|
'</span></p>',
|
||||||
'[[NonExistant.jpg|NonExistant:pic]]')
|
'[[NonExistant.jpg|NonExistant:pic]]')
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><span class="newWikiWord">NonExistant.jpg<a href="../pic/NonExistant.jpg">?</a>' +
|
'<p><span class="newWikiWord">NonExistant.jpg<a href="../pic/NonExistant.jpg">?</a>' +
|
||||||
'</span></p>',
|
'</span></p>',
|
||||||
'[[NonExistant.jpg:pic]]')
|
'[[NonExistant.jpg:pic]]')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_wiki_link_with_colon
|
def test_wiki_link_with_colon
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
'<p><span class="newWikiWord">With:Colon<a href="../show/With%3AColon">?</a></span></p>',
|
'<p><span class="newWikiWord">With:Colon<a href="../show/With%3AColon">?</a></span></p>',
|
||||||
'[[With:Colon]]')
|
'[[With:Colon]]')
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO Remove the leading underscores from this test when upgrading to RedCloth 3.0.1;
|
# TODO Remove the leading underscores from this test when upgrading to RedCloth 3.0.1;
|
||||||
# also add a test for the "Unhappy Face" problem (another interesting RedCloth bug)
|
# also add a test for the "Unhappy Face" problem (another interesting RedCloth bug)
|
||||||
def test_list_with_tildas
|
def test_list_with_tildas
|
||||||
list_with_tildas = <<-EOL
|
list_with_tildas = <<-EOL
|
||||||
* "a":~b
|
* "a":~b
|
||||||
* c~ d
|
* c~ d
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
"<ul>\n\t<li><a href=\"~b\">a</a></li>\n\t\t<li>c~ d</li>\n\t</ul>",
|
"<ul>\n\t<li><a href=\"~b\">a</a></li>\n\t\t<li>c~ d</li>\n\t</ul>",
|
||||||
list_with_tildas)
|
list_with_tildas)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_textile_image_in_mixed_wiki
|
def test_textile_image_in_mixed_wiki
|
||||||
set_web_property :markup, :mixed
|
set_web_property :markup, :mixed
|
||||||
assert_markup_parsed_as(
|
assert_markup_parsed_as(
|
||||||
"<p><img src=\"http://google.com\" alt=\"\" />\nss</p>",
|
"<p><img src=\"http://google.com\" alt=\"\" />\nss</p>",
|
||||||
"!http://google.com!\r\nss")
|
"!http://google.com!\r\nss")
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_markup_parsed_as(expected_output, input)
|
def assert_markup_parsed_as(expected_output, input)
|
||||||
revision = Revision.new(:page => @page, :content => input, :author => Author.new('AnAuthor'))
|
revision = Revision.new(:page => @page, :content => input, :author => Author.new('AnAuthor'))
|
||||||
assert_equal expected_output, revision.display_content, 'Textile output not as expected'
|
assert_equal expected_output, revision.display_content, 'Textile output not as expected'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,158 +1,158 @@
|
||||||
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
||||||
|
|
||||||
class WebTest < Test::Unit::TestCase
|
class WebTest < Test::Unit::TestCase
|
||||||
fixtures :webs, :pages, :revisions, :system
|
fixtures :webs, :pages, :revisions, :system
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@web = webs(:instiki)
|
@web = webs(:instiki)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_wiki_word_linking
|
def test_wiki_word_linking
|
||||||
@web.add_page('SecondPage', 'Yo, yo. Have you EverBeenHated',
|
@web.add_page('SecondPage', 'Yo, yo. Have you EverBeenHated',
|
||||||
Time.now, 'DavidHeinemeierHansson')
|
Time.now, 'DavidHeinemeierHansson')
|
||||||
|
|
||||||
assert_equal('<p>Yo, yo. Have you <span class="newWikiWord">Ever Been Hated' +
|
assert_equal('<p>Yo, yo. Have you <span class="newWikiWord">Ever Been Hated' +
|
||||||
'<a href="../show/EverBeenHated">?</a></span></p>',
|
'<a href="../show/EverBeenHated">?</a></span></p>',
|
||||||
@web.page("SecondPage").display_content)
|
@web.page("SecondPage").display_content)
|
||||||
|
|
||||||
@web.add_page('EverBeenHated', 'Yo, yo. Have you EverBeenHated', Time.now,
|
@web.add_page('EverBeenHated', 'Yo, yo. Have you EverBeenHated', Time.now,
|
||||||
'DavidHeinemeierHansson')
|
'DavidHeinemeierHansson')
|
||||||
assert_equal('<p>Yo, yo. Have you <a class="existingWikiWord" ' +
|
assert_equal('<p>Yo, yo. Have you <a class="existingWikiWord" ' +
|
||||||
'href="../show/EverBeenHated">Ever Been Hated</a></p>',
|
'href="../show/EverBeenHated">Ever Been Hated</a></p>',
|
||||||
@web.page("SecondPage").display_content)
|
@web.page("SecondPage").display_content)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pages_by_revision
|
def test_pages_by_revision
|
||||||
add_sample_pages
|
add_sample_pages
|
||||||
assert_equal 'EverBeenHated', @web.select.by_revision.first.name
|
assert_equal 'EverBeenHated', @web.select.by_revision.first.name
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pages_by_match
|
def test_pages_by_match
|
||||||
add_sample_pages
|
add_sample_pages
|
||||||
assert_equal 2, @web.select { |page| page.content =~ /me/i }.length
|
assert_equal 2, @web.select { |page| page.content =~ /me/i }.length
|
||||||
assert_equal 1, @web.select { |page| page.content =~ /Who/i }.length
|
assert_equal 1, @web.select { |page| page.content =~ /Who/i }.length
|
||||||
assert_equal 0, @web.select { |page| page.content =~ /none/i }.length
|
assert_equal 0, @web.select { |page| page.content =~ /none/i }.length
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_references
|
def test_references
|
||||||
add_sample_pages
|
add_sample_pages
|
||||||
assert_equal 1, @web.select.pages_that_reference('EverBeenHated').length
|
assert_equal 1, @web.select.pages_that_reference('EverBeenHated').length
|
||||||
assert_equal 0, @web.select.pages_that_reference('EverBeenInLove').length
|
assert_equal 0, @web.select.pages_that_reference('EverBeenInLove').length
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_delete
|
def test_delete
|
||||||
add_sample_pages
|
add_sample_pages
|
||||||
assert_equal 2, @web.pages.length
|
assert_equal 2, @web.pages.length
|
||||||
@web.remove_pages([ @web.page('EverBeenInLove') ])
|
@web.remove_pages([ @web.page('EverBeenInLove') ])
|
||||||
assert_equal 1, @web.pages(true).length
|
assert_equal 1, @web.pages(true).length
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_make_link
|
def test_make_link
|
||||||
add_sample_pages
|
add_sample_pages
|
||||||
|
|
||||||
existing_page_wiki_url =
|
existing_page_wiki_url =
|
||||||
'<a class="existingWikiWord" href="../show/EverBeenInLove">Ever Been In Love</a>'
|
'<a class="existingWikiWord" href="../show/EverBeenInLove">Ever Been In Love</a>'
|
||||||
existing_page_published_url =
|
existing_page_published_url =
|
||||||
'<a class="existingWikiWord" href="../published/EverBeenInLove">Ever Been In Love</a>'
|
'<a class="existingWikiWord" href="../published/EverBeenInLove">Ever Been In Love</a>'
|
||||||
existing_page_static_url =
|
existing_page_static_url =
|
||||||
'<a class="existingWikiWord" href="EverBeenInLove.html">Ever Been In Love</a>'
|
'<a class="existingWikiWord" href="EverBeenInLove.html">Ever Been In Love</a>'
|
||||||
new_page_wiki_url =
|
new_page_wiki_url =
|
||||||
'<span class="newWikiWord">Unknown Word<a href="../show/UnknownWord">?</a></span>'
|
'<span class="newWikiWord">Unknown Word<a href="../show/UnknownWord">?</a></span>'
|
||||||
new_page_published_url =
|
new_page_published_url =
|
||||||
new_page_static_url =
|
new_page_static_url =
|
||||||
'<span class="newWikiWord">Unknown Word</span>'
|
'<span class="newWikiWord">Unknown Word</span>'
|
||||||
|
|
||||||
# no options
|
# no options
|
||||||
assert_equal existing_page_wiki_url, @web.make_link('EverBeenInLove')
|
assert_equal existing_page_wiki_url, @web.make_link('EverBeenInLove')
|
||||||
|
|
||||||
# :mode => :export
|
# :mode => :export
|
||||||
assert_equal existing_page_static_url, @web.make_link('EverBeenInLove', nil, :mode => :export)
|
assert_equal existing_page_static_url, @web.make_link('EverBeenInLove', nil, :mode => :export)
|
||||||
|
|
||||||
# :mode => :publish
|
# :mode => :publish
|
||||||
assert_equal existing_page_published_url,
|
assert_equal existing_page_published_url,
|
||||||
@web.make_link('EverBeenInLove', nil, :mode => :publish)
|
@web.make_link('EverBeenInLove', nil, :mode => :publish)
|
||||||
|
|
||||||
# new page, no options
|
# new page, no options
|
||||||
assert_equal new_page_wiki_url, @web.make_link('UnknownWord')
|
assert_equal new_page_wiki_url, @web.make_link('UnknownWord')
|
||||||
|
|
||||||
# new page, :mode => :export
|
# new page, :mode => :export
|
||||||
assert_equal new_page_static_url, @web.make_link('UnknownWord', nil, :mode => :export)
|
assert_equal new_page_static_url, @web.make_link('UnknownWord', nil, :mode => :export)
|
||||||
|
|
||||||
# new page, :mode => :publish
|
# new page, :mode => :publish
|
||||||
assert_equal new_page_published_url, @web.make_link('UnknownWord', nil, :mode => :publish)
|
assert_equal new_page_published_url, @web.make_link('UnknownWord', nil, :mode => :publish)
|
||||||
|
|
||||||
# Escaping special characters in the name
|
# Escaping special characters in the name
|
||||||
assert_equal(
|
assert_equal(
|
||||||
'<span class="newWikiWord">Smith & Wesson<a href="../show/Smith+%26+Wesson">?</a></span>',
|
'<span class="newWikiWord">Smith & Wesson<a href="../show/Smith+%26+Wesson">?</a></span>',
|
||||||
@web.make_link('Smith & Wesson'))
|
@web.make_link('Smith & Wesson'))
|
||||||
|
|
||||||
# optionally using text as the link text
|
# optionally using text as the link text
|
||||||
assert_equal(
|
assert_equal(
|
||||||
existing_page_published_url.sub(/>Ever Been In Love</, ">Haven't you ever been in love?<"),
|
existing_page_published_url.sub(/>Ever Been In Love</, ">Haven't you ever been in love?<"),
|
||||||
@web.make_link('EverBeenInLove', "Haven't you ever been in love?", :mode => :publish))
|
@web.make_link('EverBeenInLove', "Haven't you ever been in love?", :mode => :publish))
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_initialize
|
def test_initialize
|
||||||
web = Web.new(:name => 'Wiki2', :address => 'wiki2', :password => '123')
|
web = Web.new(:name => 'Wiki2', :address => 'wiki2', :password => '123')
|
||||||
|
|
||||||
assert_equal 'Wiki2', web.name
|
assert_equal 'Wiki2', web.name
|
||||||
assert_equal 'wiki2', web.address
|
assert_equal 'wiki2', web.address
|
||||||
assert_equal '123', web.password
|
assert_equal '123', web.password
|
||||||
|
|
||||||
# new web should be set for maximum features enabled
|
# new web should be set for maximum features enabled
|
||||||
assert_equal :textile, web.markup
|
assert_equal :textile, web.markup
|
||||||
assert_equal '008B26', web.color
|
assert_equal '008B26', web.color
|
||||||
assert !web.safe_mode?
|
assert !web.safe_mode?
|
||||||
assert_equal([], web.pages)
|
assert_equal([], web.pages)
|
||||||
assert web.allow_uploads?
|
assert web.allow_uploads?
|
||||||
assert_nil web.additional_style
|
assert_nil web.additional_style
|
||||||
assert !web.published?
|
assert !web.published?
|
||||||
assert !web.brackets_only?
|
assert !web.brackets_only?
|
||||||
assert !web.count_pages?
|
assert !web.count_pages?
|
||||||
assert_equal 100, web.max_upload_size
|
assert_equal 100, web.max_upload_size
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_initialize_invalid_name
|
def test_initialize_invalid_name
|
||||||
assert_raises(Instiki::ValidationError) {
|
assert_raises(Instiki::ValidationError) {
|
||||||
Web.create(:name => 'Wiki2', :address => "wiki\234", :password => '123')
|
Web.create(:name => 'Wiki2', :address => "wiki\234", :password => '123')
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_new_page_linked_from_mother_page
|
def test_new_page_linked_from_mother_page
|
||||||
# this was a bug in revision 204
|
# this was a bug in revision 204
|
||||||
home = @web.add_page('HomePage', 'This page refers to AnotherPage',
|
home = @web.add_page('HomePage', 'This page refers to AnotherPage',
|
||||||
Time.local(2004, 4, 4, 16, 50), 'Alexey Verkhovsky')
|
Time.local(2004, 4, 4, 16, 50), 'Alexey Verkhovsky')
|
||||||
@web.add_page('AnotherPage', 'This is \AnotherPage',
|
@web.add_page('AnotherPage', 'This is \AnotherPage',
|
||||||
Time.local(2004, 4, 4, 16, 51), 'Alexey Verkhovsky')
|
Time.local(2004, 4, 4, 16, 51), 'Alexey Verkhovsky')
|
||||||
|
|
||||||
@web.pages(true)
|
@web.pages(true)
|
||||||
assert_equal [home], @web.select.pages_that_link_to('AnotherPage')
|
assert_equal [home], @web.select.pages_that_link_to('AnotherPage')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_orphaned_pages
|
def test_orphaned_pages
|
||||||
add_sample_pages
|
add_sample_pages
|
||||||
home = @web.add_page('HomePage',
|
home = @web.add_page('HomePage',
|
||||||
'This is a home page, it should not be an orphan',
|
'This is a home page, it should not be an orphan',
|
||||||
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky')
|
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky')
|
||||||
author = @web.add_page('AlexeyVerkhovsky',
|
author = @web.add_page('AlexeyVerkhovsky',
|
||||||
'This is an author page, it should not be an orphan',
|
'This is an author page, it should not be an orphan',
|
||||||
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky')
|
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky')
|
||||||
self_linked = @web.add_page('SelfLinked',
|
self_linked = @web.add_page('SelfLinked',
|
||||||
'I am me SelfLinked and link to EverBeenInLove',
|
'I am me SelfLinked and link to EverBeenInLove',
|
||||||
Time.local(2004, 4, 4, 16, 50), 'AnonymousCoward')
|
Time.local(2004, 4, 4, 16, 50), 'AnonymousCoward')
|
||||||
|
|
||||||
# page that links to itself, and nobody else links to it must be an orphan
|
# page that links to itself, and nobody else links to it must be an orphan
|
||||||
assert_equal ['EverBeenHated', 'SelfLinked'],
|
assert_equal ['EverBeenHated', 'SelfLinked'],
|
||||||
@web.select.orphaned_pages.collect{ |page| page.name }.sort
|
@web.select.orphaned_pages.collect{ |page| page.name }.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def add_sample_pages
|
def add_sample_pages
|
||||||
@in_love = @web.add_page('EverBeenInLove', 'Who am I me',
|
@in_love = @web.add_page('EverBeenInLove', 'Who am I me',
|
||||||
Time.local(2004, 4, 4, 16, 50), 'DavidHeinemeierHansson')
|
Time.local(2004, 4, 4, 16, 50), 'DavidHeinemeierHansson')
|
||||||
@hated = @web.add_page('EverBeenHated', 'I am me EverBeenHated',
|
@hated = @web.add_page('EverBeenHated', 'I am me EverBeenHated',
|
||||||
Time.local(2004, 4, 4, 16, 51), 'DavidHeinemeierHansson')
|
Time.local(2004, 4, 4, 16, 51), 'DavidHeinemeierHansson')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue