Converting linefeeds to Unix-style

This commit is contained in:
Alexey Verkhovsky 2006-03-19 21:49:53 +00:00
parent da24698a4c
commit d6fedc7f84
21 changed files with 5541 additions and 5541 deletions

View file

@ -1,32 +1,32 @@
class RevisionSweeper < ActionController::Caching::Sweeper
observe Revision, Page
def after_save(record)
if record.is_a?(Revision)
expire_caches(record.page)
end
end
def after_delete(record)
if record.is_a?(Page)
expire_caches(record)
end
end
private
def expire_caches(page)
web = page.web
([page.name] + WikiReference.pages_that_reference(page.name)).uniq.each do |page_name|
expire_action :controller => 'wiki', :web => web.address,
:action => %w(show published), :id => page_name
end
expire_action :controller => 'wiki', :web => web.address,
:action => %w(authors recently_revised list)
expire_fragment :controller => 'wiki', :web => web.address,
:action => %w(rss_with_headlines rss_with_content)
end
end
class RevisionSweeper < ActionController::Caching::Sweeper
observe Revision, Page
def after_save(record)
if record.is_a?(Revision)
expire_caches(record.page)
end
end
def after_delete(record)
if record.is_a?(Page)
expire_caches(record)
end
end
private
def expire_caches(page)
web = page.web
([page.name] + WikiReference.pages_that_reference(page.name)).uniq.each do |page_name|
expire_action :controller => 'wiki', :web => web.address,
:action => %w(show published), :id => page_name
end
expire_action :controller => 'wiki', :web => web.address,
:action => %w(authors recently_revised list)
expire_fragment :controller => 'wiki', :web => web.address,
:action => %w(rss_with_headlines rss_with_content)
end
end

View file

@ -1,15 +1,15 @@
# This class maintains the state of wiki references for newly created or newly deleted pages
class PageObserver < ActiveRecord::Observer
def after_create(page)
WikiReference.update_all("link_type = '#{WikiReference::LINKED_PAGE}'",
['referenced_name = ?', page.name])
end
def before_destroy(page)
WikiReference.delete_all ['page_id = ?', page.id]
WikiReference.update_all("link_type = '#{WikiReference::WANTED_PAGE}'",
['referenced_name = ?', page.name])
end
# This class maintains the state of wiki references for newly created or newly deleted pages
class PageObserver < ActiveRecord::Observer
def after_create(page)
WikiReference.update_all("link_type = '#{WikiReference::LINKED_PAGE}'",
['referenced_name = ?', page.name])
end
def before_destroy(page)
WikiReference.delete_all ['page_id = ?', page.id]
WikiReference.update_all("link_type = '#{WikiReference::WANTED_PAGE}'",
['referenced_name = ?', page.name])
end
end

View file

@ -1,64 +1,64 @@
class WikiFile < ActiveRecord::Base
belongs_to :web
before_save :write_content_to_file
before_destroy :delete_content_file
validates_presence_of %w( web file_name )
validates_length_of :file_name, :within=>1..50
validates_length_of :description, :maximum=>255
def self.find_by_file_name(file_name)
find(:first, :conditions => ['file_name = ?', file_name])
end
SANE_FILE_NAME = /^[a-zA-Z0-9\-_\. ]*$/
def validate
if file_name
if file_name !~ SANE_FILE_NAME
errors.add("file_name", "is invalid. Only latin characters, digits, dots, underscores, " +
"dashes and spaces are accepted")
elsif file_name == '.' or file_name == '..'
errors.add("file_name", "cannot be '.' or '..'")
end
end
if @web and @content
if (@content.size > @web.max_upload_size.kilobytes)
errors.add("content", "size (#{(@content.size / 1024.0).round} kilobytes) exceeds " +
"the maximum (#{web.max_upload_size} kilobytes) set for this wiki")
end
end
errors.add("content", "is empty") if @content.nil? or @content.empty?
end
def content=(content)
if content.respond_to? :read
@content = content.read
else
@content = content
end
end
def content
@content ||= ( File.open(content_path, 'rb') { |f| f.read } )
end
def content_path
web.files_path + '/' + file_name
end
def write_content_to_file
web.create_files_directory unless File.exists?(web.files_path)
File.open(self.content_path, 'wb') { |f| f.write(@content) }
end
def delete_content_file
require 'fileutils'
FileUtils.rm_f(content_path) if File.exists?(content_path)
end
end
class WikiFile < ActiveRecord::Base
belongs_to :web
before_save :write_content_to_file
before_destroy :delete_content_file
validates_presence_of %w( web file_name )
validates_length_of :file_name, :within=>1..50
validates_length_of :description, :maximum=>255
def self.find_by_file_name(file_name)
find(:first, :conditions => ['file_name = ?', file_name])
end
SANE_FILE_NAME = /^[a-zA-Z0-9\-_\. ]*$/
def validate
if file_name
if file_name !~ SANE_FILE_NAME
errors.add("file_name", "is invalid. Only latin characters, digits, dots, underscores, " +
"dashes and spaces are accepted")
elsif file_name == '.' or file_name == '..'
errors.add("file_name", "cannot be '.' or '..'")
end
end
if @web and @content
if (@content.size > @web.max_upload_size.kilobytes)
errors.add("content", "size (#{(@content.size / 1024.0).round} kilobytes) exceeds " +
"the maximum (#{web.max_upload_size} kilobytes) set for this wiki")
end
end
errors.add("content", "is empty") if @content.nil? or @content.empty?
end
def content=(content)
if content.respond_to? :read
@content = content.read
else
@content = content
end
end
def content
@content ||= ( File.open(content_path, 'rb') { |f| f.read } )
end
def content_path
web.files_path + '/' + file_name
end
def write_content_to_file
web.create_files_directory unless File.exists?(web.files_path)
File.open(self.content_path, 'wb') { |f| f.write(@content) }
end
def delete_content_file
require 'fileutils'
FileUtils.rm_f(content_path) if File.exists?(content_path)
end
end

View file

@ -1,82 +1,82 @@
class WikiReference < ActiveRecord::Base
LINKED_PAGE = 'L'
WANTED_PAGE = 'W'
INCLUDED_PAGE = 'I'
CATEGORY = 'C'
AUTHOR = 'A'
FILE = 'F'
WANTED_FILE = 'E'
belongs_to :page
validates_inclusion_of :link_type, :in => [LINKED_PAGE, WANTED_PAGE, INCLUDED_PAGE, CATEGORY, AUTHOR, FILE, WANTED_FILE]
# FIXME all finders below MUST restrict their results to pages belonging to a particular web
def self.link_type(web, page_name)
web.has_page?(page_name) ? LINKED_PAGE : WANTED_PAGE
end
def self.pages_that_reference(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ?' +
"AND wiki_references.link_type in ('#{LINKED_PAGE}', '#{WANTED_PAGE}', '#{INCLUDED_PAGE}')"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end
def self.pages_that_link_to(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type in ('#{LINKED_PAGE}', '#{WANTED_PAGE}')"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end
def self.pages_that_include(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type = '#{INCLUDED_PAGE}'"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end
def self.pages_in_category(category)
query =
'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type = '#{CATEGORY}'"
names = connection.select_all(sanitize_sql([query, category])).map { |row| row['name'] }
end
def self.list_categories
query = "SELECT DISTINCT referenced_name FROM wiki_references WHERE link_type = '#{CATEGORY}'"
connection.select_all(query).map { |row| row['referenced_name'] }
end
def wiki_word?
linked_page? or wanted_page?
end
def wiki_link?
linked_page? or wanted_page? or file? or wanted_file?
end
def linked_page?
link_type == LINKED_PAGE
end
def wanted_page?
link_type == WANTED_PAGE
end
def included_page?
link_type == INCLUDED_PAGE
end
def file?
link_type == FILE
end
def wanted_file?
link_type == WANTED_FILE
end
end
class WikiReference < ActiveRecord::Base
LINKED_PAGE = 'L'
WANTED_PAGE = 'W'
INCLUDED_PAGE = 'I'
CATEGORY = 'C'
AUTHOR = 'A'
FILE = 'F'
WANTED_FILE = 'E'
belongs_to :page
validates_inclusion_of :link_type, :in => [LINKED_PAGE, WANTED_PAGE, INCLUDED_PAGE, CATEGORY, AUTHOR, FILE, WANTED_FILE]
# FIXME all finders below MUST restrict their results to pages belonging to a particular web
def self.link_type(web, page_name)
web.has_page?(page_name) ? LINKED_PAGE : WANTED_PAGE
end
def self.pages_that_reference(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ?' +
"AND wiki_references.link_type in ('#{LINKED_PAGE}', '#{WANTED_PAGE}', '#{INCLUDED_PAGE}')"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end
def self.pages_that_link_to(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type in ('#{LINKED_PAGE}', '#{WANTED_PAGE}')"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end
def self.pages_that_include(page_name)
query = 'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type = '#{INCLUDED_PAGE}'"
names = connection.select_all(sanitize_sql([query, page_name])).map { |row| row['name'] }
end
def self.pages_in_category(category)
query =
'SELECT name FROM pages JOIN wiki_references ON pages.id = wiki_references.page_id ' +
'WHERE wiki_references.referenced_name = ? ' +
"AND wiki_references.link_type = '#{CATEGORY}'"
names = connection.select_all(sanitize_sql([query, category])).map { |row| row['name'] }
end
def self.list_categories
query = "SELECT DISTINCT referenced_name FROM wiki_references WHERE link_type = '#{CATEGORY}'"
connection.select_all(query).map { |row| row['referenced_name'] }
end
def wiki_word?
linked_page? or wanted_page?
end
def wiki_link?
linked_page? or wanted_page? or file? or wanted_file?
end
def linked_page?
link_type == LINKED_PAGE
end
def wanted_page?
link_type == WANTED_PAGE
end
def included_page?
link_type == INCLUDED_PAGE
end
def file?
link_type == FILE
end
def wanted_file?
link_type == WANTED_FILE
end
end

View file

@ -1,21 +1,21 @@
xml.rss('version' => '2.0') do
xml.channel do
xml.title(@web.name)
xml.link(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => 'HomePage'))
xml.description('An Instiki wiki')
xml.language('en-us')
xml.ttl('40')
for page in @pages_by_revision
xml.item do
xml.title(page.plain_name)
unless @hide_description
xml.description(rendered_content(page))
end
xml.pubDate(page.revised_at.getgm.strftime('%a, %d %b %Y %H:%M:%S Z'))
xml.guid(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => page.name))
xml.link(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => page.name))
end
end
end
end
xml.rss('version' => '2.0') do
xml.channel do
xml.title(@web.name)
xml.link(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => 'HomePage'))
xml.description('An Instiki wiki')
xml.language('en-us')
xml.ttl('40')
for page in @pages_by_revision
xml.item do
xml.title(page.plain_name)
unless @hide_description
xml.description(rendered_content(page))
end
xml.pubDate(page.revised_at.getgm.strftime('%a, %d %b %Y %H:%M:%S Z'))
xml.guid(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => page.name))
xml.link(url_for(:only_path => false, :web => @web_name, :action => @link_action, :id => page.name))
end
end
end
end

View file

@ -1,17 +1,17 @@
unless defined?(RAILS_ROOT)
root_path = File.join(File.dirname(__FILE__), '..')
unless RUBY_PLATFORM =~ /mswin32/
require 'pathname'
root_path = Pathname.new(root_path).cleanpath.to_s
end
RAILS_ROOT = root_path
end
if File.directory?("#{RAILS_ROOT}/vendor/rails")
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
else
require 'rubygems'
require 'initializer'
end
unless defined?(RAILS_ROOT)
root_path = File.join(File.dirname(__FILE__), '..')
unless RUBY_PLATFORM =~ /mswin32/
require 'pathname'
root_path = Pathname.new(root_path).cleanpath.to_s
end
RAILS_ROOT = root_path
end
if File.directory?("#{RAILS_ROOT}/vendor/rails")
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
else
require 'rubygems'
require 'initializer'
end
Rails::Initializer.run(:set_load_path)

View file

@ -1,95 +1,95 @@
development:
adapter: mysql
host: localhost
database: instiki_dev
username: root
password:
test:
adapter: mysql
host: localhost
database: instiki_test
username: root
password:
# "Out of the box", Instiki stores it's data in sqlite3 database. Other options are listed below.
production:
adapter: sqlite3
database: db/production.db.sqlite3
# MySQL (default setup). Versions 4.1 and 5.0 are recommended.
#
# Get the fast C bindings:
# gem install mysql
# (on OS X: gem install mysql -- --include=/usr/local/lib)
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
mysql_example:
adapter: mysql
database: instiki_development
username: root
password:
socket: /path/to/your/mysql.sock
# Connect on a TCP socket. If omitted, the adapter will connect on the
# domain socket given by socket instead.
#host: localhost
#port: 3306
# Warning: The database defined as 'test' will be erased and
# re-generated from your development database when you run 'rake'.
# Do not set this db to the same as development or production.
mysql_example:
adapter: mysql
database: instiki_test
username: root
password:
socket: /path/to/your/mysql.sock
# PostgreSQL versions 7.4 - 8.1
#
# Get the C bindings:
# gem install postgres
# or use the pure-Ruby bindings on Windows:
# gem install postgres-pr
postgresql_example:
adapter: postgresql
database: instiki_development
username: instiki
password:
# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration.
#host: remote-database
#port: 5432
# Schema search path. The server defaults to $user,public
#schema_search_path: myapp,sharedapp,public
# Character set encoding. The server defaults to sql_ascii.
#encoding: UTF8
# Minimum log levels, in increasing order:
# debug5, debug4, debug3, debug2, debug1,
# info, notice, warning, error, log, fatal, or panic
# The server defaults to notice.
#min_messages: warning
# SQLite version 2.x
# gem install sqlite-ruby
sqlite_example:
adapter: sqlite
database: db/development.sqlite2
# SQLite version 3.x
# gem install sqlite3-ruby
sqlite3_example:
adapter: sqlite3
database: db/development.sqlite3
# In-memory SQLite 3 database. Useful for tests.
sqlite3_in_memory_example:
adapter: sqlite3
development:
adapter: mysql
host: localhost
database: instiki_dev
username: root
password:
test:
adapter: mysql
host: localhost
database: instiki_test
username: root
password:
# "Out of the box", Instiki stores it's data in sqlite3 database. Other options are listed below.
production:
adapter: sqlite3
database: db/production.db.sqlite3
# MySQL (default setup). Versions 4.1 and 5.0 are recommended.
#
# Get the fast C bindings:
# gem install mysql
# (on OS X: gem install mysql -- --include=/usr/local/lib)
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
mysql_example:
adapter: mysql
database: instiki_development
username: root
password:
socket: /path/to/your/mysql.sock
# Connect on a TCP socket. If omitted, the adapter will connect on the
# domain socket given by socket instead.
#host: localhost
#port: 3306
# Warning: The database defined as 'test' will be erased and
# re-generated from your development database when you run 'rake'.
# Do not set this db to the same as development or production.
mysql_example:
adapter: mysql
database: instiki_test
username: root
password:
socket: /path/to/your/mysql.sock
# PostgreSQL versions 7.4 - 8.1
#
# Get the C bindings:
# gem install postgres
# or use the pure-Ruby bindings on Windows:
# gem install postgres-pr
postgresql_example:
adapter: postgresql
database: instiki_development
username: instiki
password:
# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration.
#host: remote-database
#port: 5432
# Schema search path. The server defaults to $user,public
#schema_search_path: myapp,sharedapp,public
# Character set encoding. The server defaults to sql_ascii.
#encoding: UTF8
# Minimum log levels, in increasing order:
# debug5, debug4, debug3, debug2, debug1,
# info, notice, warning, error, log, fatal, or panic
# The server defaults to notice.
#min_messages: warning
# SQLite version 2.x
# gem install sqlite-ruby
sqlite_example:
adapter: sqlite
database: db/development.sqlite2
# SQLite version 3.x
# gem install sqlite3-ruby
sqlite3_example:
adapter: sqlite3
database: db/development.sqlite3
# In-memory SQLite 3 database. Useful for tests.
sqlite3_in_memory_example:
adapter: sqlite3
database: ":memory:"

View file

@ -1,134 +1,134 @@
require 'diff'
# Temporary class containing all rendering stuff from a Revision
# I want to shift all rendering loguc to the controller eventually
class PageRenderer
include HTMLDiff
def self.setup_url_generator(url_generator)
@@url_generator = url_generator
end
def self.teardown_url_generator
@@url_generator = nil
end
attr_reader :revision
def initialize(revision = nil)
self.revision = revision
end
def revision=(r)
@revision = r
@display_content = @display_published = @wiki_words_cache = @wiki_includes_cache =
@wiki_references_cache = nil
end
def display_content(update_references = false)
@display_content ||= render(:update_references => update_references)
end
def display_content_for_export
render :mode => :export
end
def display_published
@display_published ||= render(:mode => :publish)
end
def display_diff
previous_revision = @revision.page.previous_revision(@revision)
if previous_revision
rendered_previous_revision = WikiContent.new(previous_revision, @@url_generator).render!
diff(rendered_previous_revision, display_content)
else
display_content
end
end
# Returns an array of all the WikiIncludes present in the content of this revision.
def wiki_includes
unless @wiki_includes_cache
chunks = display_content.find_chunks(Include)
@wiki_includes_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
end
@wiki_includes_cache
end
# Returns an array of all the WikiReferences present in the content of this revision.
def wiki_references
unless @wiki_references_cache
chunks = display_content.find_chunks(WikiChunk::WikiReference)
@wiki_references_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
end
@wiki_references_cache
end
# Returns an array of all the WikiWords present in the content of this revision.
def wiki_words
@wiki_words_cache ||= find_wiki_words(display_content)
end
def find_wiki_words(rendering_result)
wiki_links = rendering_result.find_chunks(WikiChunk::WikiLink)
# Exclude backslash-escaped wiki words, such as \WikiWord, as well as links to files
# and pictures, such as [[foo.txt:file]] or [[foo.jpg:pic]]
wiki_links.delete_if { |link| link.escaped? or [:pic, :file].include?(link.link_type) }
# convert to the list of unique page names
wiki_links.map { |link| ( link.page_name ) }.uniq
end
# Returns an array of all the WikiWords present in the content of this revision.
# that already exists as a page in the web.
def existing_pages
wiki_words.select { |wiki_word| @revision.page.web.page(wiki_word) }
end
# 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.
def unexisting_pages
wiki_words - existing_pages
end
private
def render(options = {})
rendering_result = WikiContent.new(@revision, @@url_generator, options).render!
update_references(rendering_result) if options[:update_references]
rendering_result
end
def update_references(rendering_result)
WikiReference.delete_all ['page_id = ?', @revision.page_id]
references = @revision.page.wiki_references
wiki_words = find_wiki_words(rendering_result)
# TODO it may be desirable to save links to files and pictures as WikiReference objects
# present version doesn't do it
wiki_words.each do |referenced_name|
# Links to self are always considered linked
if referenced_name == @revision.page.name
link_type = WikiReference::LINKED_PAGE
else
link_type = WikiReference.link_type(@revision.page.web, referenced_name)
end
references.create :referenced_name => referenced_name, :link_type => link_type
end
include_chunks = rendering_result.find_chunks(Include)
includes = include_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
includes.each do |included_page_name|
references.create :referenced_name => included_page_name,
:link_type => WikiReference::INCLUDED_PAGE
end
categories = rendering_result.find_chunks(Category).map { |cat| cat.list }.flatten
categories.each do |category|
references.create :referenced_name => category, :link_type => WikiReference::CATEGORY
end
end
end
require 'diff'
# Temporary class containing all rendering stuff from a Revision
# I want to shift all rendering loguc to the controller eventually
class PageRenderer
include HTMLDiff
def self.setup_url_generator(url_generator)
@@url_generator = url_generator
end
def self.teardown_url_generator
@@url_generator = nil
end
attr_reader :revision
def initialize(revision = nil)
self.revision = revision
end
def revision=(r)
@revision = r
@display_content = @display_published = @wiki_words_cache = @wiki_includes_cache =
@wiki_references_cache = nil
end
def display_content(update_references = false)
@display_content ||= render(:update_references => update_references)
end
def display_content_for_export
render :mode => :export
end
def display_published
@display_published ||= render(:mode => :publish)
end
def display_diff
previous_revision = @revision.page.previous_revision(@revision)
if previous_revision
rendered_previous_revision = WikiContent.new(previous_revision, @@url_generator).render!
diff(rendered_previous_revision, display_content)
else
display_content
end
end
# Returns an array of all the WikiIncludes present in the content of this revision.
def wiki_includes
unless @wiki_includes_cache
chunks = display_content.find_chunks(Include)
@wiki_includes_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
end
@wiki_includes_cache
end
# Returns an array of all the WikiReferences present in the content of this revision.
def wiki_references
unless @wiki_references_cache
chunks = display_content.find_chunks(WikiChunk::WikiReference)
@wiki_references_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
end
@wiki_references_cache
end
# Returns an array of all the WikiWords present in the content of this revision.
def wiki_words
@wiki_words_cache ||= find_wiki_words(display_content)
end
def find_wiki_words(rendering_result)
wiki_links = rendering_result.find_chunks(WikiChunk::WikiLink)
# Exclude backslash-escaped wiki words, such as \WikiWord, as well as links to files
# and pictures, such as [[foo.txt:file]] or [[foo.jpg:pic]]
wiki_links.delete_if { |link| link.escaped? or [:pic, :file].include?(link.link_type) }
# convert to the list of unique page names
wiki_links.map { |link| ( link.page_name ) }.uniq
end
# Returns an array of all the WikiWords present in the content of this revision.
# that already exists as a page in the web.
def existing_pages
wiki_words.select { |wiki_word| @revision.page.web.page(wiki_word) }
end
# 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.
def unexisting_pages
wiki_words - existing_pages
end
private
def render(options = {})
rendering_result = WikiContent.new(@revision, @@url_generator, options).render!
update_references(rendering_result) if options[:update_references]
rendering_result
end
def update_references(rendering_result)
WikiReference.delete_all ['page_id = ?', @revision.page_id]
references = @revision.page.wiki_references
wiki_words = find_wiki_words(rendering_result)
# TODO it may be desirable to save links to files and pictures as WikiReference objects
# present version doesn't do it
wiki_words.each do |referenced_name|
# Links to self are always considered linked
if referenced_name == @revision.page.name
link_type = WikiReference::LINKED_PAGE
else
link_type = WikiReference.link_type(@revision.page.web, referenced_name)
end
references.create :referenced_name => referenced_name, :link_type => link_type
end
include_chunks = rendering_result.find_chunks(Include)
includes = include_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
includes.each do |included_page_name|
references.create :referenced_name => included_page_name,
:link_type => WikiReference::INCLUDED_PAGE
end
categories = rendering_result.find_chunks(Category).map { |cat| cat.list }.flatten
categories.each do |category|
references.create :referenced_name => category, :link_type => WikiReference::CATEGORY
end
end
end

View file

@ -1,121 +1,121 @@
class AbstractUrlGenerator
def initialize(controller)
raise 'Controller cannot be nil' if controller.nil?
@controller = controller
end
# Create a link for the given page (or file) name and link text based
# on the render mode in options and whether the page (file) exists
# in the web.
def make_link(name, web, text = nil, options = {})
text = CGI.escapeHTML(text || WikiWords.separate(name))
mode = (options[:mode] || :show).to_sym
link_type = (options[:link_type] || :show).to_sym
if (link_type == :show)
known_page = web.has_page?(name)
else
known_page = web.has_file?(name)
end
case link_type
when :show
page_link(mode, name, text, web.address, known_page)
when :file
file_link(mode, name, text, web.address, known_page)
when :pic
pic_link(mode, name, text, web.address, known_page)
else
raise "Unknown link type: #{link_type}"
end
end
end
class UrlGenerator < AbstractUrlGenerator
private
def file_link(mode, name, text, web_address, known_file)
case mode
when :export
if known_file
%{<a class="existingWikiWord" href="#{CGI.escape(name)}.html">#{text}</a>}
else
%{<span class="newWikiWord">#{text}</span>}
end
when :publish
if known_file
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else
%{<span class="newWikiWord">#{text}</span>}
end
else
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
if known_file
%{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end
end
end
def page_link(mode, name, text, web_address, known_page)
case mode
when :export
if known_page
%{<a class="existingWikiWord" href="#{CGI.escape(name)}.html">#{text}</a>}
else
%{<span class="newWikiWord">#{text}</span>}
end
when :publish
if known_page
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'published',
:id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else
%{<span class="newWikiWord">#{text}</span>}
end
else
if known_page
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'show',
:id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'new',
:id => name
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end
end
end
def pic_link(mode, name, text, web_address, known_pic)
case mode
when :export
if known_pic
%{<img alt="#{text}" src="#{CGI.escape(name)}" />}
else
%{<img alt="#{text}" src="no image" />}
end
when :publish
if known_pic
%{<img alt="#{text}" src="#{CGI.escape(name)}" />}
else
%{<span class="newWikiWord">#{text}</span>}
end
else
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
if known_pic
%{<img alt="#{text}" src="#{href}" />}
else
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end
end
end
end
class AbstractUrlGenerator
def initialize(controller)
raise 'Controller cannot be nil' if controller.nil?
@controller = controller
end
# Create a link for the given page (or file) name and link text based
# on the render mode in options and whether the page (file) exists
# in the web.
def make_link(name, web, text = nil, options = {})
text = CGI.escapeHTML(text || WikiWords.separate(name))
mode = (options[:mode] || :show).to_sym
link_type = (options[:link_type] || :show).to_sym
if (link_type == :show)
known_page = web.has_page?(name)
else
known_page = web.has_file?(name)
end
case link_type
when :show
page_link(mode, name, text, web.address, known_page)
when :file
file_link(mode, name, text, web.address, known_page)
when :pic
pic_link(mode, name, text, web.address, known_page)
else
raise "Unknown link type: #{link_type}"
end
end
end
class UrlGenerator < AbstractUrlGenerator
private
def file_link(mode, name, text, web_address, known_file)
case mode
when :export
if known_file
%{<a class="existingWikiWord" href="#{CGI.escape(name)}.html">#{text}</a>}
else
%{<span class="newWikiWord">#{text}</span>}
end
when :publish
if known_file
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else
%{<span class="newWikiWord">#{text}</span>}
end
else
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
if known_file
%{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end
end
end
def page_link(mode, name, text, web_address, known_page)
case mode
when :export
if known_page
%{<a class="existingWikiWord" href="#{CGI.escape(name)}.html">#{text}</a>}
else
%{<span class="newWikiWord">#{text}</span>}
end
when :publish
if known_page
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'published',
:id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else
%{<span class="newWikiWord">#{text}</span>}
end
else
if known_page
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'show',
:id => name
%{<a class="existingWikiWord" href="#{href}">#{text}</a>}
else
href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'new',
:id => name
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end
end
end
def pic_link(mode, name, text, web_address, known_pic)
case mode
when :export
if known_pic
%{<img alt="#{text}" src="#{CGI.escape(name)}" />}
else
%{<img alt="#{text}" src="no image" />}
end
when :publish
if known_pic
%{<img alt="#{text}" src="#{CGI.escape(name)}" />}
else
%{<span class="newWikiWord">#{text}</span>}
end
else
href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
if known_pic
%{<img alt="#{text}" src="#{href}" />}
else
%{<span class="newWikiWord">#{text}<a href="#{href}">?</a></span>}
end
end
end
end

View file

@ -1,10 +1,10 @@
#!c:/ruby/bin/ruby
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
require "dispatcher"
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
#!c:/ruby/bin/ruby
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
require "dispatcher"
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
Dispatcher.dispatch

View file

@ -1,24 +1,24 @@
#!c:/ruby/bin/ruby
#
# You may specify the path to the FastCGI crash log (a log of unhandled
# exceptions which forced the FastCGI instance to exit, great for debugging)
# and the number of requests to process before running garbage collection.
#
# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
# and the GC period is nil (turned off). A reasonable number of requests
# could range from 10-100 depending on the memory footprint of your app.
#
# Example:
# # Default log path, normal GC behavior.
# RailsFCGIHandler.process!
#
# # Default log path, 50 requests between GC.
# RailsFCGIHandler.process! nil, 50
#
# # Custom log path, normal GC behavior.
# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
#
require File.dirname(__FILE__) + "/../config/environment"
require 'fcgi_handler'
RailsFCGIHandler.process!
#!c:/ruby/bin/ruby
#
# You may specify the path to the FastCGI crash log (a log of unhandled
# exceptions which forced the FastCGI instance to exit, great for debugging)
# and the number of requests to process before running garbage collection.
#
# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
# and the GC period is nil (turned off). A reasonable number of requests
# could range from 10-100 depending on the memory footprint of your app.
#
# Example:
# # Default log path, normal GC behavior.
# RailsFCGIHandler.process!
#
# # Default log path, 50 requests between GC.
# RailsFCGIHandler.process! nil, 50
#
# # Custom log path, normal GC behavior.
# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
#
require File.dirname(__FILE__) + "/../config/environment"
require 'fcgi_handler'
RailsFCGIHandler.process!

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,47 +1,47 @@
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var Scriptaculous = {
Version: '1.5_rc3',
require: function(libraryName) {
// inserting via DOM fails in Safari 2.0, so brute force approach
document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
},
load: function() {
if((typeof Prototype=='undefined') ||
parseFloat(Prototype.Version.split(".")[0] + "." +
Prototype.Version.split(".")[1]) < 1.4)
throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0");
var scriptTags = document.getElementsByTagName("script");
for(var i=0;i<scriptTags.length;i++) {
if(scriptTags[i].src && scriptTags[i].src.match(/scriptaculous\.js(\?.*)?$/)) {
var path = scriptTags[i].src.replace(/scriptaculous\.js(\?.*)?$/,'');
this.require(path + 'effects.js');
this.require(path + 'dragdrop.js');
this.require(path + 'controls.js');
this.require(path + 'slider.js');
break;
}
}
}
}
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var Scriptaculous = {
Version: '1.5_rc3',
require: function(libraryName) {
// inserting via DOM fails in Safari 2.0, so brute force approach
document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
},
load: function() {
if((typeof Prototype=='undefined') ||
parseFloat(Prototype.Version.split(".")[0] + "." +
Prototype.Version.split(".")[1]) < 1.4)
throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0");
var scriptTags = document.getElementsByTagName("script");
for(var i=0;i<scriptTags.length;i++) {
if(scriptTags[i].src && scriptTags[i].src.match(/scriptaculous\.js(\?.*)?$/)) {
var path = scriptTags[i].src.replace(/scriptaculous\.js(\?.*)?$/,'');
this.require(path + 'effects.js');
this.require(path + 'dragdrop.js');
this.require(path + 'controls.js');
this.require(path + 'slider.js');
break;
}
}
}
}
Scriptaculous.load();

View file

@ -1,258 +1,258 @@
// Copyright (c) 2005 Marty Haught
//
// See scriptaculous.js for full license.
if(!Control) var Control = {};
Control.Slider = Class.create();
// options:
// axis: 'vertical', or 'horizontal' (default)
// increment: (default: 1)
// step: (default: 1)
//
// callbacks:
// onChange(value)
// onSlide(value)
Control.Slider.prototype = {
initialize: function(handle, track, options) {
this.handle = $(handle);
this.track = $(track);
this.options = options || {};
this.axis = this.options.axis || 'horizontal';
this.increment = this.options.increment || 1;
this.step = parseInt(this.options.step) || 1;
this.value = 0;
var defaultMaximum = Math.round(this.track.offsetWidth / this.increment);
if(this.isVertical()) defaultMaximum = Math.round(this.track.offsetHeight / this.increment);
this.maximum = this.options.maximum || defaultMaximum;
this.minimum = this.options.minimum || 0;
// Will be used to align the handle onto the track, if necessary
this.alignX = parseInt (this.options.alignX) || 0;
this.alignY = parseInt (this.options.alignY) || 0;
// Zero out the slider position
this.setCurrentLeft(Position.cumulativeOffset(this.track)[0] - Position.cumulativeOffset(this.handle)[0] + this.alignX);
this.setCurrentTop(this.trackTop() - Position.cumulativeOffset(this.handle)[1] + this.alignY);
this.offsetX = 0;
this.offsetY = 0;
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
this.originalZ = parseInt(this.handle.style.zIndex || "0");
// Prepopulate Slider value
this.setSliderValue(parseInt(this.options.sliderValue) || 0);
this.active = false;
this.dragging = false;
this.disabled = false;
// FIXME: use css
this.handleImage = $(this.options.handleImage) || false;
this.handleDisabled = this.options.handleDisabled || false;
this.handleEnabled = false;
if(this.handleImage)
this.handleEnabled = this.handleImage.src || false;
if(this.options.disabled)
this.setDisabled();
// Value Array
this.values = this.options.values || false; // Add method to validate and sort??
Element.makePositioned(this.handle); // fix IE
this.eventMouseDown = this.startDrag.bindAsEventListener(this);
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.update.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown);
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
},
dispose: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
Event.stopObserving(document, "mouseup", this.eventMouseUp);
Event.stopObserving(document, "mousemove", this.eventMouseMove);
Event.stopObserving(document, "keypress", this.eventKeypress);
},
setDisabled: function(){
this.disabled = true;
if(this.handleDisabled)
this.handleImage.src = this.handleDisabled;
},
setEnabled: function(){
this.disabled = false;
if(this.handleEnabled)
this.handleImage.src = this.handleEnabled;
},
currentLeft: function() {
return parseInt(this.handle.style.left || '0');
},
currentTop: function() {
return parseInt(this.handle.style.top || '0');
},
setCurrentLeft: function(left) {
this.handle.style.left = left +"px";
},
setCurrentTop: function(top) {
this.handle.style.top = top +"px";
},
trackLeft: function(){
return Position.cumulativeOffset(this.track)[0];
},
trackTop: function(){
return Position.cumulativeOffset(this.track)[1];
},
getNearestValue: function(value){
if(this.values){
var i = 0;
var offset = Math.abs(this.values[0] - value);
var newValue = this.values[0];
for(i=0; i < this.values.length; i++){
var currentOffset = Math.abs(this.values[i] - value);
if(currentOffset < offset){
newValue = this.values[i];
offset = currentOffset;
}
}
return newValue;
}
return value;
},
setSliderValue: function(sliderValue){
// First check our max and minimum and nearest values
sliderValue = this.getNearestValue(sliderValue);
if(sliderValue > this.maximum) sliderValue = this.maximum;
if(sliderValue < this.minimum) sliderValue = this.minimum;
var offsetDiff = (sliderValue - (this.value||this.minimum)) * this.increment;
if(this.isVertical()){
this.setCurrentTop(offsetDiff + this.currentTop());
} else {
this.setCurrentLeft(offsetDiff + this.currentLeft());
}
this.value = sliderValue;
this.updateFinished();
},
minimumOffset: function(){
return(this.isVertical() ?
this.trackTop() + this.alignY :
this.trackLeft() + this.alignX);
},
maximumOffset: function(){
return(this.isVertical() ?
this.trackTop() + this.alignY + (this.maximum - this.minimum) * this.increment :
this.trackLeft() + this.alignX + (this.maximum - this.minimum) * this.increment);
},
isVertical: function(){
return (this.axis == 'vertical');
},
startDrag: function(event) {
if(Event.isLeftClick(event)) {
if(!this.disabled){
this.active = true;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
var offsets = Position.cumulativeOffset(this.handle);
this.offsetX = (pointer[0] - offsets[0]);
this.offsetY = (pointer[1] - offsets[1]);
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
}
Event.stop(event);
}
},
update: function(event) {
if(this.active) {
if(!this.dragging) {
var style = this.handle.style;
this.dragging = true;
if(style.position=="") style.position = "relative";
style.zIndex = this.options.zindex;
}
this.draw(event);
// fix AppleWebKit rendering
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
Event.stop(event);
}
},
draw: function(event) {
var pointer = [Event.pointerX(event), Event.pointerY(event)];
var offsets = Position.cumulativeOffset(this.handle);
offsets[0] -= this.currentLeft();
offsets[1] -= this.currentTop();
// Adjust for the pointer's position on the handle
pointer[0] -= this.offsetX;
pointer[1] -= this.offsetY;
var style = this.handle.style;
if(this.isVertical()){
if(pointer[1] > this.maximumOffset())
pointer[1] = this.maximumOffset();
if(pointer[1] < this.minimumOffset())
pointer[1] = this.minimumOffset();
// Increment by values
if(this.values){
this.value = this.getNearestValue(Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum);
pointer[1] = this.trackTop() + this.alignY + (this.value - this.minimum) * this.increment;
} else {
this.value = Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum;
}
style.top = pointer[1] - offsets[1] + "px";
} else {
if(pointer[0] > this.maximumOffset()) pointer[0] = this.maximumOffset();
if(pointer[0] < this.minimumOffset()) pointer[0] = this.minimumOffset();
// Increment by values
if(this.values){
this.value = this.getNearestValue(Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum);
pointer[0] = this.trackLeft() + this.alignX + (this.value - this.minimum) * this.increment;
} else {
this.value = Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum;
}
style.left = (pointer[0] - offsets[0]) + "px";
}
if(this.options.onSlide) this.options.onSlide(this.value);
},
endDrag: function(event) {
if(this.active && this.dragging) {
this.finishDrag(event, true);
Event.stop(event);
}
this.active = false;
this.dragging = false;
},
finishDrag: function(event, success) {
this.active = false;
this.dragging = false;
this.handle.style.zIndex = this.originalZ;
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
this.updateFinished();
},
updateFinished: function() {
if(this.options.onChange) this.options.onChange(this.value);
},
keyPress: function(event) {
if(this.active && !this.disabled) {
switch(event.keyCode) {
case Event.KEY_ESC:
this.finishDrag(event, false);
Event.stop(event);
break;
}
if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
}
}
}
// Copyright (c) 2005 Marty Haught
//
// See scriptaculous.js for full license.
if(!Control) var Control = {};
Control.Slider = Class.create();
// options:
// axis: 'vertical', or 'horizontal' (default)
// increment: (default: 1)
// step: (default: 1)
//
// callbacks:
// onChange(value)
// onSlide(value)
Control.Slider.prototype = {
initialize: function(handle, track, options) {
this.handle = $(handle);
this.track = $(track);
this.options = options || {};
this.axis = this.options.axis || 'horizontal';
this.increment = this.options.increment || 1;
this.step = parseInt(this.options.step) || 1;
this.value = 0;
var defaultMaximum = Math.round(this.track.offsetWidth / this.increment);
if(this.isVertical()) defaultMaximum = Math.round(this.track.offsetHeight / this.increment);
this.maximum = this.options.maximum || defaultMaximum;
this.minimum = this.options.minimum || 0;
// Will be used to align the handle onto the track, if necessary
this.alignX = parseInt (this.options.alignX) || 0;
this.alignY = parseInt (this.options.alignY) || 0;
// Zero out the slider position
this.setCurrentLeft(Position.cumulativeOffset(this.track)[0] - Position.cumulativeOffset(this.handle)[0] + this.alignX);
this.setCurrentTop(this.trackTop() - Position.cumulativeOffset(this.handle)[1] + this.alignY);
this.offsetX = 0;
this.offsetY = 0;
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
this.originalZ = parseInt(this.handle.style.zIndex || "0");
// Prepopulate Slider value
this.setSliderValue(parseInt(this.options.sliderValue) || 0);
this.active = false;
this.dragging = false;
this.disabled = false;
// FIXME: use css
this.handleImage = $(this.options.handleImage) || false;
this.handleDisabled = this.options.handleDisabled || false;
this.handleEnabled = false;
if(this.handleImage)
this.handleEnabled = this.handleImage.src || false;
if(this.options.disabled)
this.setDisabled();
// Value Array
this.values = this.options.values || false; // Add method to validate and sort??
Element.makePositioned(this.handle); // fix IE
this.eventMouseDown = this.startDrag.bindAsEventListener(this);
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.update.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown);
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
},
dispose: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
Event.stopObserving(document, "mouseup", this.eventMouseUp);
Event.stopObserving(document, "mousemove", this.eventMouseMove);
Event.stopObserving(document, "keypress", this.eventKeypress);
},
setDisabled: function(){
this.disabled = true;
if(this.handleDisabled)
this.handleImage.src = this.handleDisabled;
},
setEnabled: function(){
this.disabled = false;
if(this.handleEnabled)
this.handleImage.src = this.handleEnabled;
},
currentLeft: function() {
return parseInt(this.handle.style.left || '0');
},
currentTop: function() {
return parseInt(this.handle.style.top || '0');
},
setCurrentLeft: function(left) {
this.handle.style.left = left +"px";
},
setCurrentTop: function(top) {
this.handle.style.top = top +"px";
},
trackLeft: function(){
return Position.cumulativeOffset(this.track)[0];
},
trackTop: function(){
return Position.cumulativeOffset(this.track)[1];
},
getNearestValue: function(value){
if(this.values){
var i = 0;
var offset = Math.abs(this.values[0] - value);
var newValue = this.values[0];
for(i=0; i < this.values.length; i++){
var currentOffset = Math.abs(this.values[i] - value);
if(currentOffset < offset){
newValue = this.values[i];
offset = currentOffset;
}
}
return newValue;
}
return value;
},
setSliderValue: function(sliderValue){
// First check our max and minimum and nearest values
sliderValue = this.getNearestValue(sliderValue);
if(sliderValue > this.maximum) sliderValue = this.maximum;
if(sliderValue < this.minimum) sliderValue = this.minimum;
var offsetDiff = (sliderValue - (this.value||this.minimum)) * this.increment;
if(this.isVertical()){
this.setCurrentTop(offsetDiff + this.currentTop());
} else {
this.setCurrentLeft(offsetDiff + this.currentLeft());
}
this.value = sliderValue;
this.updateFinished();
},
minimumOffset: function(){
return(this.isVertical() ?
this.trackTop() + this.alignY :
this.trackLeft() + this.alignX);
},
maximumOffset: function(){
return(this.isVertical() ?
this.trackTop() + this.alignY + (this.maximum - this.minimum) * this.increment :
this.trackLeft() + this.alignX + (this.maximum - this.minimum) * this.increment);
},
isVertical: function(){
return (this.axis == 'vertical');
},
startDrag: function(event) {
if(Event.isLeftClick(event)) {
if(!this.disabled){
this.active = true;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
var offsets = Position.cumulativeOffset(this.handle);
this.offsetX = (pointer[0] - offsets[0]);
this.offsetY = (pointer[1] - offsets[1]);
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
}
Event.stop(event);
}
},
update: function(event) {
if(this.active) {
if(!this.dragging) {
var style = this.handle.style;
this.dragging = true;
if(style.position=="") style.position = "relative";
style.zIndex = this.options.zindex;
}
this.draw(event);
// fix AppleWebKit rendering
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
Event.stop(event);
}
},
draw: function(event) {
var pointer = [Event.pointerX(event), Event.pointerY(event)];
var offsets = Position.cumulativeOffset(this.handle);
offsets[0] -= this.currentLeft();
offsets[1] -= this.currentTop();
// Adjust for the pointer's position on the handle
pointer[0] -= this.offsetX;
pointer[1] -= this.offsetY;
var style = this.handle.style;
if(this.isVertical()){
if(pointer[1] > this.maximumOffset())
pointer[1] = this.maximumOffset();
if(pointer[1] < this.minimumOffset())
pointer[1] = this.minimumOffset();
// Increment by values
if(this.values){
this.value = this.getNearestValue(Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum);
pointer[1] = this.trackTop() + this.alignY + (this.value - this.minimum) * this.increment;
} else {
this.value = Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum;
}
style.top = pointer[1] - offsets[1] + "px";
} else {
if(pointer[0] > this.maximumOffset()) pointer[0] = this.maximumOffset();
if(pointer[0] < this.minimumOffset()) pointer[0] = this.minimumOffset();
// Increment by values
if(this.values){
this.value = this.getNearestValue(Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum);
pointer[0] = this.trackLeft() + this.alignX + (this.value - this.minimum) * this.increment;
} else {
this.value = Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum;
}
style.left = (pointer[0] - offsets[0]) + "px";
}
if(this.options.onSlide) this.options.onSlide(this.value);
},
endDrag: function(event) {
if(this.active && this.dragging) {
this.finishDrag(event, true);
Event.stop(event);
}
this.active = false;
this.dragging = false;
},
finishDrag: function(event, success) {
this.active = false;
this.dragging = false;
this.handle.style.zIndex = this.originalZ;
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
this.updateFinished();
},
updateFinished: function() {
if(this.options.onChange) this.options.onChange(this.value);
},
keyPress: function(event) {
if(this.active && !this.disabled) {
switch(event.keyCode) {
case Event.KEY_ESC:
this.finishDrag(event, false);
Event.stop(event);
break;
}
if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
}
}
}

View file

@ -1,10 +1,10 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake.
require(File.join(File.dirname(__FILE__), 'config', 'boot'))
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake.
require(File.join(File.dirname(__FILE__), 'config', 'boot'))
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
require 'tasks/rails'

View file

@ -1,112 +1,112 @@
my_way_1:
id: 1
page_id: 2
referenced_name: MyWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
smart_engine_1:
id: 2
page_id: 3
referenced_name: SmartEngine
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
that_way_1:
id: 3
page_id: 4
referenced_name: ThatWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_1:
id: 4
page_id: 1
referenced_name: HisWay
link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_2:
id: 5
page_id: 1
referenced_name: MyWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_3:
id: 6
page_id: 1
referenced_name: ThatWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_4:
id: 7
page_id: 1
referenced_name: SmartEngine
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_1:
id: 8
page_id: 6
referenced_name: HisWay
link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_2:
id: 9
page_id: 6
referenced_name: MyWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_3:
id: 10
page_id: 6
referenced_name: ThatWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_4:
id: 11
page_id: 6
referenced_name: OverThere
link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_5:
id: 12
page_id: 6
referenced_name: SmartEngine
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
oak_1:
id: 13
page_id: 7
referenced_name: trees
link_type: C
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
elephant_1:
id: 14
page_id: 8
referenced_name: animals
link_type: C
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
my_way_1:
id: 1
page_id: 2
referenced_name: MyWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
smart_engine_1:
id: 2
page_id: 3
referenced_name: SmartEngine
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
that_way_1:
id: 3
page_id: 4
referenced_name: ThatWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_1:
id: 4
page_id: 1
referenced_name: HisWay
link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_2:
id: 5
page_id: 1
referenced_name: MyWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_3:
id: 6
page_id: 1
referenced_name: ThatWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
home_page_4:
id: 7
page_id: 1
referenced_name: SmartEngine
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_1:
id: 8
page_id: 6
referenced_name: HisWay
link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_2:
id: 9
page_id: 6
referenced_name: MyWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_3:
id: 10
page_id: 6
referenced_name: ThatWay
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_4:
id: 11
page_id: 6
referenced_name: OverThere
link_type: W
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
first_page_5:
id: 12
page_id: 6
referenced_name: SmartEngine
link_type: L
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
oak_1:
id: 13
page_id: 7
referenced_name: trees
link_type: C
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>
elephant_1:
id: 14
page_id: 8
referenced_name: animals
link_type: C
created_at: <%= Time.now.to_formatted_s(:db) %>
updated_at: <%= Time.now.to_formatted_s(:db) %>

View file

@ -1,377 +1,377 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class PageRendererTest < Test::Unit::TestCase
fixtures :webs, :pages, :revisions, :system, :wiki_references
def setup
@wiki = Wiki.new
@web = webs(:test_wiki)
@page = pages(:home_page)
@revision = revisions(:home_page_second_revision)
end
def test_wiki_word_linking
@web.add_page('SecondPage', 'Yo, yo. Have you EverBeenHated',
Time.now, 'DavidHeinemeierHansson', test_renderer)
assert_equal('<p>Yo, yo. Have you <span class="newWikiWord">Ever Been Hated' +
'<a href="../show/EverBeenHated">?</a></span></p>',
rendered_content(@web.page("SecondPage")))
@web.add_page('EverBeenHated', 'Yo, yo. Have you EverBeenHated', Time.now,
'DavidHeinemeierHansson', test_renderer)
assert_equal('<p>Yo, yo. Have you <a class="existingWikiWord" ' +
'href="../show/EverBeenHated">Ever Been Hated</a></p>',
rendered_content(@web.page("SecondPage")))
end
def test_wiki_words
assert_equal %w( HisWay MyWay SmartEngine SmartEngineGUI ThatWay ),
test_renderer(@revision).wiki_words.sort
@wiki.write_page('wiki1', 'NoWikiWord', 'hey you!', Time.now, 'Me', test_renderer)
assert_equal [], test_renderer(@wiki.read_page('wiki1', 'NoWikiWord').revisions.last).wiki_words
end
def test_existing_pages
assert_equal %w( MyWay SmartEngine ThatWay ), test_renderer(@revision).existing_pages.sort
end
def test_unexisting_pages
assert_equal %w( HisWay SmartEngineGUI ), test_renderer(@revision).unexisting_pages.sort
end
def test_content_with_wiki_links
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 ' +
'<a class="existingWikiWord" href="../show/ThatWay">That Way</a> in ' +
'<span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' +
'though <a class="existingWikiWord" href="../show/MyWay">My Way</a> OverThere&#8212;see ' +
'<a class="existingWikiWord" href="../show/SmartEngine">Smart Engine</a> in that ' +
'<span class="newWikiWord">Smart Engine GUI' +
'<a href="../show/SmartEngineGUI">?</a></span></p>',
test_renderer(@revision).display_content
end
def test_markdown
set_web_property :markup, :markdown
assert_markup_parsed_as(
%{<h1>My Headline</h1>\n\n<p>that <span class="newWikiWord">} +
%{Smart Engine GUI<a href="../show/SmartEngineGUI">?</a></span></p>},
"My Headline\n===========\n\nthat SmartEngineGUI")
code_block = [
'This is a code block:',
'',
' def a_method(arg)',
' return ThatWay',
'',
'Nice!'
].join("\n")
assert_markup_parsed_as(
%{<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>},
code_block)
end
def test_markdown_hyperlink_with_slash
# in response to a bug, see http://dev.instiki.org/attachment/ticket/177
set_web_property :markup, :markdown
assert_markup_parsed_as(
'<p><a href="http://example/with/slash">text</a></p>',
'[text](http://example/with/slash)')
end
def test_mixed_formatting
textile_and_markdown = [
'Markdown heading',
'================',
'',
'h2. Textile heading',
'',
'*some* **text** _with_ -styles-',
'',
'* list 1',
'* list 2'
].join("\n")
set_web_property :markup, :markdown
assert_markup_parsed_as(
"<h1>Markdown heading</h1>\n\n" +
"<p>h2. Textile heading</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>",
textile_and_markdown)
set_web_property :markup, :textile
assert_markup_parsed_as(
"<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<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
textile_and_markdown)
set_web_property :markup, :mixed
assert_markup_parsed_as(
"<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" +
"<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
textile_and_markdown)
end
def test_rdoc
set_web_property :markup, :rdoc
@revision = Revision.new(:page => @page, :content => '+hello+ that SmartEngineGUI',
:author => Author.new('DavidHeinemeierHansson'))
assert_equal "<tt>hello</tt> that <span class=\"newWikiWord\">Smart Engine GUI" +
"<a href=\"../show/SmartEngineGUI\">?</a></span>\n\n",
test_renderer(@revision).display_content
end
def test_content_with_auto_links
assert_markup_parsed_as(
'<p><a href="http://www.loudthinking.com/">http://www.loudthinking.com/</a> ' +
'points to <a class="existingWikiWord" href="../show/ThatWay">That Way</a> from ' +
'<a href="mailto:david@loudthinking.com">david@loudthinking.com</a></p>',
'http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com')
end
def test_content_with_aliased_links
assert_markup_parsed_as(
'<p>Would a <a class="existingWikiWord" href="../show/SmartEngine">clever motor' +
'</a> go by any other name?</p>',
'Would a [[SmartEngine|clever motor]] go by any other name?')
end
def test_content_with_wikiword_in_em
assert_markup_parsed_as(
'<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>' +
'</span> </em></p>',
'_should we go ThatWay or ThisWay _')
end
def test_content_with_wikiword_in_tag
assert_markup_parsed_as(
'<p>That is some <em style="WikiWord">Stylish Emphasis</em></p>',
'That is some <em style="WikiWord">Stylish Emphasis</em>')
end
def test_content_with_escaped_wikiword
# there should be no wiki link
assert_markup_parsed_as('<p>WikiWord</p>', '\WikiWord')
end
def test_content_with_pre_blocks
assert_markup_parsed_as(
'<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>')
end
def test_content_with_autolink_in_parentheses
assert_markup_parsed_as(
'<p>The <span class="caps">W3C</span> body (<a href="http://www.w3c.org">' +
'http://www.w3c.org</a>) sets web standards</p>',
'The W3C body (http://www.w3c.org) sets web standards')
end
def test_content_with_link_in_parentheses
assert_markup_parsed_as(
'<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)')
end
def test_content_with_image_link
assert_markup_parsed_as(
'<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.')
end
def test_content_with_inlined_img_tag
assert_markup_parsed_as(
'<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.')
assert_markup_parsed_as(
'<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.')
end
def test_nowiki_tag
assert_markup_parsed_as(
'<p>Do not mark up [[this text]] or http://www.thislink.com.</p>',
'Do not mark up <nowiki>[[this text]]</nowiki> ' +
'or <nowiki>http://www.thislink.com</nowiki>.')
end
def test_multiline_nowiki_tag
assert_markup_parsed_as(
"<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>',
"Do not <nowiki>mark \n up [[this text]] \n" +
"and http://this.url.com </nowiki> but markup [[this]]")
end
def test_content_with_bracketted_wiki_word
set_web_property :brackets_only, true
assert_markup_parsed_as(
'<p>This is a WikiWord and a tricky name <span class="newWikiWord">' +
'Sperberg-McQueen<a href="../show/Sperberg-McQueen">?</a></span>.</p>',
'This is a WikiWord and a tricky name [[Sperberg-McQueen]].')
end
def test_content_for_export
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="ThatWay.html">That Way</a> in ' +
'<span class="newWikiWord">His Way</span> though ' +
'<a class="existingWikiWord" href="MyWay.html">My Way</a> OverThere&#8212;see ' +
'<a class="existingWikiWord" href="SmartEngine.html">Smart Engine</a> in that ' +
'<span class="newWikiWord">Smart Engine GUI</span></p>',
test_renderer(@revision).display_content_for_export
end
def test_double_replacing
@revision.content = "VersionHistory\r\n\r\ncry VersionHistory"
assert_equal '<p><span class="newWikiWord">Version History' +
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
'<span class="newWikiWord">Version History<a href="../show/VersionHistory">?</a>' +
'</span></p>',
test_renderer(@revision).display_content
@revision.content = "f\r\nVersionHistory\r\n\r\ncry VersionHistory"
assert_equal "<p>f<br /><span class=\"newWikiWord\">Version History" +
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
"<span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a>" +
"</span></p>",
test_renderer(@revision).display_content
end
def test_difficult_wiki_words
@revision.content = "[[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>",
test_renderer(@revision).display_content
end
def test_revisions_diff
Revision.create(:page => @page, :content => 'What a blue and lovely morning',
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
Revision.create(:page => @page, :content => 'What a red and lovely morning today',
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
assert_equal "<p>What a <del class=\"diffmod\">blue</del><ins class=\"diffmod\">red" +
"</ins> and lovely morning<ins class=\"diffins\"> today</ins></p>", test_renderer(@page.revisions.last).display_diff
end
def test_link_to_file
assert_markup_parsed_as(
'<p><span class="newWikiWord">doc.pdf<a href="../file/doc.pdf">?</a></span></p>',
'[[doc.pdf:file]]')
end
def test_link_to_pic
WikiFile.delete_all
require 'fileutils'
FileUtils.rm_rf("#{RAILS_ROOT}/public/wiki1/files/*")
@web.wiki_files.create(:file_name => 'square.jpg', :description => 'Square', :content => 'never mind')
assert_markup_parsed_as(
'<p><img alt="Square" src="../file/square.jpg" /></p>',
'[[square.jpg|Square:pic]]')
assert_markup_parsed_as(
'<p><img alt="square.jpg" src="../file/square.jpg" /></p>',
'[[square.jpg:pic]]')
end
def test_link_to_non_existant_pic
assert_markup_parsed_as(
'<p><span class="newWikiWord">NonExistant<a href="../file/NonExistant.jpg">?</a>' +
'</span></p>',
'[[NonExistant.jpg|NonExistant:pic]]')
assert_markup_parsed_as(
'<p><span class="newWikiWord">NonExistant.jpg<a href="../file/NonExistant.jpg">?</a>' +
'</span></p>',
'[[NonExistant.jpg:pic]]')
end
def test_wiki_link_with_colon
assert_markup_parsed_as(
'<p><span class="newWikiWord">With:Colon<a href="../show/With%3AColon">?</a></span></p>',
'[[With:Colon]]')
end
def test_list_with_tildas
list_with_tildas = <<-EOL
* "a":~b
* c~ d
EOL
assert_markup_parsed_as(
"<ul>\n\t<li><a href=\"~b\">a</a></li>\n\t\t<li>c~ d</li>\n\t</ul>",
list_with_tildas)
end
def test_textile_image_in_mixed_wiki
set_web_property :markup, :mixed
assert_markup_parsed_as(
"<p><img src=\"http://google.com\" alt=\"\" />\nss</p>",
"!http://google.com!\r\nss")
end
def test_references_creation_links
new_page = @web.add_page('NewPage', 'HomePage NewPage',
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true)
assert_equal 2, references.size
assert_equal 'HomePage', references[0].referenced_name
assert_equal WikiReference::LINKED_PAGE, references[0].link_type
assert_equal 'NewPage', references[1].referenced_name
assert_equal WikiReference::LINKED_PAGE, references[1].link_type
end
def test_references_creation_includes
new_page = @web.add_page('NewPage', '[[!include IncludedPage]]',
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true)
assert_equal 1, references.size
assert_equal 'IncludedPage', references[0].referenced_name
assert_equal WikiReference::INCLUDED_PAGE, references[0].link_type
end
def test_references_creation_categories
new_page = @web.add_page('NewPage', "Foo\ncategory: NewPageCategory",
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true)
assert_equal 1, references.size
assert_equal 'NewPageCategory', references[0].referenced_name
assert_equal WikiReference::CATEGORY, references[0].link_type
end
private
def add_sample_pages
@in_love = @web.add_page('EverBeenInLove', 'Who am I me',
Time.local(2004, 4, 4, 16, 50), 'DavidHeinemeierHansson', test_renderer)
@hated = @web.add_page('EverBeenHated', 'I am me EverBeenHated',
Time.local(2004, 4, 4, 16, 51), 'DavidHeinemeierHansson', test_renderer)
end
def assert_markup_parsed_as(expected_output, input)
revision = Revision.new(:page => @page, :content => input, :author => Author.new('AnAuthor'))
assert_equal expected_output, test_renderer(revision).display_content, 'Rendering output not as expected'
end
def rendered_content(page)
test_renderer(page.revisions.last).display_content
end
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class PageRendererTest < Test::Unit::TestCase
fixtures :webs, :pages, :revisions, :system, :wiki_references
def setup
@wiki = Wiki.new
@web = webs(:test_wiki)
@page = pages(:home_page)
@revision = revisions(:home_page_second_revision)
end
def test_wiki_word_linking
@web.add_page('SecondPage', 'Yo, yo. Have you EverBeenHated',
Time.now, 'DavidHeinemeierHansson', test_renderer)
assert_equal('<p>Yo, yo. Have you <span class="newWikiWord">Ever Been Hated' +
'<a href="../show/EverBeenHated">?</a></span></p>',
rendered_content(@web.page("SecondPage")))
@web.add_page('EverBeenHated', 'Yo, yo. Have you EverBeenHated', Time.now,
'DavidHeinemeierHansson', test_renderer)
assert_equal('<p>Yo, yo. Have you <a class="existingWikiWord" ' +
'href="../show/EverBeenHated">Ever Been Hated</a></p>',
rendered_content(@web.page("SecondPage")))
end
def test_wiki_words
assert_equal %w( HisWay MyWay SmartEngine SmartEngineGUI ThatWay ),
test_renderer(@revision).wiki_words.sort
@wiki.write_page('wiki1', 'NoWikiWord', 'hey you!', Time.now, 'Me', test_renderer)
assert_equal [], test_renderer(@wiki.read_page('wiki1', 'NoWikiWord').revisions.last).wiki_words
end
def test_existing_pages
assert_equal %w( MyWay SmartEngine ThatWay ), test_renderer(@revision).existing_pages.sort
end
def test_unexisting_pages
assert_equal %w( HisWay SmartEngineGUI ), test_renderer(@revision).unexisting_pages.sort
end
def test_content_with_wiki_links
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 ' +
'<a class="existingWikiWord" href="../show/ThatWay">That Way</a> in ' +
'<span class="newWikiWord">His Way<a href="../show/HisWay">?</a></span> ' +
'though <a class="existingWikiWord" href="../show/MyWay">My Way</a> OverThere&#8212;see ' +
'<a class="existingWikiWord" href="../show/SmartEngine">Smart Engine</a> in that ' +
'<span class="newWikiWord">Smart Engine GUI' +
'<a href="../show/SmartEngineGUI">?</a></span></p>',
test_renderer(@revision).display_content
end
def test_markdown
set_web_property :markup, :markdown
assert_markup_parsed_as(
%{<h1>My Headline</h1>\n\n<p>that <span class="newWikiWord">} +
%{Smart Engine GUI<a href="../show/SmartEngineGUI">?</a></span></p>},
"My Headline\n===========\n\nthat SmartEngineGUI")
code_block = [
'This is a code block:',
'',
' def a_method(arg)',
' return ThatWay',
'',
'Nice!'
].join("\n")
assert_markup_parsed_as(
%{<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>},
code_block)
end
def test_markdown_hyperlink_with_slash
# in response to a bug, see http://dev.instiki.org/attachment/ticket/177
set_web_property :markup, :markdown
assert_markup_parsed_as(
'<p><a href="http://example/with/slash">text</a></p>',
'[text](http://example/with/slash)')
end
def test_mixed_formatting
textile_and_markdown = [
'Markdown heading',
'================',
'',
'h2. Textile heading',
'',
'*some* **text** _with_ -styles-',
'',
'* list 1',
'* list 2'
].join("\n")
set_web_property :markup, :markdown
assert_markup_parsed_as(
"<h1>Markdown heading</h1>\n\n" +
"<p>h2. Textile heading</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>",
textile_and_markdown)
set_web_property :markup, :textile
assert_markup_parsed_as(
"<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<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
textile_and_markdown)
set_web_property :markup, :mixed
assert_markup_parsed_as(
"<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" +
"<ul>\n\t<li>list 1</li>\n\t\t<li>list 2</li>\n\t</ul>",
textile_and_markdown)
end
def test_rdoc
set_web_property :markup, :rdoc
@revision = Revision.new(:page => @page, :content => '+hello+ that SmartEngineGUI',
:author => Author.new('DavidHeinemeierHansson'))
assert_equal "<tt>hello</tt> that <span class=\"newWikiWord\">Smart Engine GUI" +
"<a href=\"../show/SmartEngineGUI\">?</a></span>\n\n",
test_renderer(@revision).display_content
end
def test_content_with_auto_links
assert_markup_parsed_as(
'<p><a href="http://www.loudthinking.com/">http://www.loudthinking.com/</a> ' +
'points to <a class="existingWikiWord" href="../show/ThatWay">That Way</a> from ' +
'<a href="mailto:david@loudthinking.com">david@loudthinking.com</a></p>',
'http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com')
end
def test_content_with_aliased_links
assert_markup_parsed_as(
'<p>Would a <a class="existingWikiWord" href="../show/SmartEngine">clever motor' +
'</a> go by any other name?</p>',
'Would a [[SmartEngine|clever motor]] go by any other name?')
end
def test_content_with_wikiword_in_em
assert_markup_parsed_as(
'<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>' +
'</span> </em></p>',
'_should we go ThatWay or ThisWay _')
end
def test_content_with_wikiword_in_tag
assert_markup_parsed_as(
'<p>That is some <em style="WikiWord">Stylish Emphasis</em></p>',
'That is some <em style="WikiWord">Stylish Emphasis</em>')
end
def test_content_with_escaped_wikiword
# there should be no wiki link
assert_markup_parsed_as('<p>WikiWord</p>', '\WikiWord')
end
def test_content_with_pre_blocks
assert_markup_parsed_as(
'<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>')
end
def test_content_with_autolink_in_parentheses
assert_markup_parsed_as(
'<p>The <span class="caps">W3C</span> body (<a href="http://www.w3c.org">' +
'http://www.w3c.org</a>) sets web standards</p>',
'The W3C body (http://www.w3c.org) sets web standards')
end
def test_content_with_link_in_parentheses
assert_markup_parsed_as(
'<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)')
end
def test_content_with_image_link
assert_markup_parsed_as(
'<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.')
end
def test_content_with_inlined_img_tag
assert_markup_parsed_as(
'<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.')
assert_markup_parsed_as(
'<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.')
end
def test_nowiki_tag
assert_markup_parsed_as(
'<p>Do not mark up [[this text]] or http://www.thislink.com.</p>',
'Do not mark up <nowiki>[[this text]]</nowiki> ' +
'or <nowiki>http://www.thislink.com</nowiki>.')
end
def test_multiline_nowiki_tag
assert_markup_parsed_as(
"<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>',
"Do not <nowiki>mark \n up [[this text]] \n" +
"and http://this.url.com </nowiki> but markup [[this]]")
end
def test_content_with_bracketted_wiki_word
set_web_property :brackets_only, true
assert_markup_parsed_as(
'<p>This is a WikiWord and a tricky name <span class="newWikiWord">' +
'Sperberg-McQueen<a href="../show/Sperberg-McQueen">?</a></span>.</p>',
'This is a WikiWord and a tricky name [[Sperberg-McQueen]].')
end
def test_content_for_export
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="ThatWay.html">That Way</a> in ' +
'<span class="newWikiWord">His Way</span> though ' +
'<a class="existingWikiWord" href="MyWay.html">My Way</a> OverThere&#8212;see ' +
'<a class="existingWikiWord" href="SmartEngine.html">Smart Engine</a> in that ' +
'<span class="newWikiWord">Smart Engine GUI</span></p>',
test_renderer(@revision).display_content_for_export
end
def test_double_replacing
@revision.content = "VersionHistory\r\n\r\ncry VersionHistory"
assert_equal '<p><span class="newWikiWord">Version History' +
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
'<span class="newWikiWord">Version History<a href="../show/VersionHistory">?</a>' +
'</span></p>',
test_renderer(@revision).display_content
@revision.content = "f\r\nVersionHistory\r\n\r\ncry VersionHistory"
assert_equal "<p>f<br /><span class=\"newWikiWord\">Version History" +
"<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\n\t<p>cry " +
"<span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a>" +
"</span></p>",
test_renderer(@revision).display_content
end
def test_difficult_wiki_words
@revision.content = "[[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>",
test_renderer(@revision).display_content
end
def test_revisions_diff
Revision.create(:page => @page, :content => 'What a blue and lovely morning',
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
Revision.create(:page => @page, :content => 'What a red and lovely morning today',
:author => Author.new('DavidHeinemeierHansson'), :revised_at => Time.now)
assert_equal "<p>What a <del class=\"diffmod\">blue</del><ins class=\"diffmod\">red" +
"</ins> and lovely morning<ins class=\"diffins\"> today</ins></p>", test_renderer(@page.revisions.last).display_diff
end
def test_link_to_file
assert_markup_parsed_as(
'<p><span class="newWikiWord">doc.pdf<a href="../file/doc.pdf">?</a></span></p>',
'[[doc.pdf:file]]')
end
def test_link_to_pic
WikiFile.delete_all
require 'fileutils'
FileUtils.rm_rf("#{RAILS_ROOT}/public/wiki1/files/*")
@web.wiki_files.create(:file_name => 'square.jpg', :description => 'Square', :content => 'never mind')
assert_markup_parsed_as(
'<p><img alt="Square" src="../file/square.jpg" /></p>',
'[[square.jpg|Square:pic]]')
assert_markup_parsed_as(
'<p><img alt="square.jpg" src="../file/square.jpg" /></p>',
'[[square.jpg:pic]]')
end
def test_link_to_non_existant_pic
assert_markup_parsed_as(
'<p><span class="newWikiWord">NonExistant<a href="../file/NonExistant.jpg">?</a>' +
'</span></p>',
'[[NonExistant.jpg|NonExistant:pic]]')
assert_markup_parsed_as(
'<p><span class="newWikiWord">NonExistant.jpg<a href="../file/NonExistant.jpg">?</a>' +
'</span></p>',
'[[NonExistant.jpg:pic]]')
end
def test_wiki_link_with_colon
assert_markup_parsed_as(
'<p><span class="newWikiWord">With:Colon<a href="../show/With%3AColon">?</a></span></p>',
'[[With:Colon]]')
end
def test_list_with_tildas
list_with_tildas = <<-EOL
* "a":~b
* c~ d
EOL
assert_markup_parsed_as(
"<ul>\n\t<li><a href=\"~b\">a</a></li>\n\t\t<li>c~ d</li>\n\t</ul>",
list_with_tildas)
end
def test_textile_image_in_mixed_wiki
set_web_property :markup, :mixed
assert_markup_parsed_as(
"<p><img src=\"http://google.com\" alt=\"\" />\nss</p>",
"!http://google.com!\r\nss")
end
def test_references_creation_links
new_page = @web.add_page('NewPage', 'HomePage NewPage',
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true)
assert_equal 2, references.size
assert_equal 'HomePage', references[0].referenced_name
assert_equal WikiReference::LINKED_PAGE, references[0].link_type
assert_equal 'NewPage', references[1].referenced_name
assert_equal WikiReference::LINKED_PAGE, references[1].link_type
end
def test_references_creation_includes
new_page = @web.add_page('NewPage', '[[!include IncludedPage]]',
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true)
assert_equal 1, references.size
assert_equal 'IncludedPage', references[0].referenced_name
assert_equal WikiReference::INCLUDED_PAGE, references[0].link_type
end
def test_references_creation_categories
new_page = @web.add_page('NewPage', "Foo\ncategory: NewPageCategory",
Time.local(2004, 4, 4, 16, 50), 'AlexeyVerkhovsky', test_renderer)
references = new_page.wiki_references(true)
assert_equal 1, references.size
assert_equal 'NewPageCategory', references[0].referenced_name
assert_equal WikiReference::CATEGORY, references[0].link_type
end
private
def add_sample_pages
@in_love = @web.add_page('EverBeenInLove', 'Who am I me',
Time.local(2004, 4, 4, 16, 50), 'DavidHeinemeierHansson', test_renderer)
@hated = @web.add_page('EverBeenHated', 'I am me EverBeenHated',
Time.local(2004, 4, 4, 16, 51), 'DavidHeinemeierHansson', test_renderer)
end
def assert_markup_parsed_as(expected_output, input)
revision = Revision.new(:page => @page, :content => input, :author => Author.new('AnAuthor'))
assert_equal expected_output, test_renderer(revision).display_content, 'Rendering output not as expected'
end
def rendered_content(page)
test_renderer(page.revisions.last).display_content
end
end

View file

@ -1,84 +1,84 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'fileutils'
class WikiFileTest < Test::Unit::TestCase
include FileUtils
fixtures :webs, :pages, :revisions, :system, :wiki_references
def setup
@web = webs(:test_wiki)
mkdir_p("#{RAILS_ROOT}/public/wiki1/files/")
rm_rf("#{RAILS_ROOT}/public/wiki1/files/*")
WikiFile.delete_all
end
def test_basic_store_and_retrieve_ascii_file
@web.wiki_files.create(:file_name => 'binary_file', :description => 'Binary file', :content => "\001\002\003")
binary = WikiFile.find_by_file_name('binary_file')
assert_equal "\001\002\003", binary.content
end
def test_basic_store_and_retrieve_binary_file
@web.wiki_files.create(:file_name => 'text_file', :description => 'Text file', :content => "abc")
text = WikiFile.find_by_file_name('text_file')
assert_equal "abc", text.content
end
def test_storing_an_image
rails_gif = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read }
assert_equal rails_gif.size, File.size("#{RAILS_ROOT}/test/fixtures/rails.gif")
@web.wiki_files.create(:file_name => 'rails.gif', :description => 'Rails logo', :content => rails_gif)
rails_gif_from_db = WikiFile.find_by_file_name('rails.gif')
assert_equal rails_gif.size, rails_gif_from_db.content.size
assert_equal rails_gif, rails_gif_from_db.content
end
def test_mandatory_fields_validations
assert_validation(:file_name, '', :fail)
assert_validation(:file_name, nil, :fail)
assert_validation(:content, '', :fail)
assert_validation(:content, nil, :fail)
end
def test_upload_size_validation
assert_validation(:content, 'a' * 100.kilobytes, :pass)
assert_validation(:content, 'a' * (100.kilobytes + 1), :fail)
end
def test_file_name_size_validation
assert_validation(:file_name, '', :fail)
assert_validation(:file_name, 'a', :pass)
assert_validation(:file_name, 'a' * 50, :pass)
assert_validation(:file_name, 'a' * 51, :fail)
end
def test_file_name_pattern_validation
assert_validation(:file_name, ".. Accep-table File.name", :pass)
assert_validation(:file_name, "/bad", :fail)
assert_validation(:file_name, "~bad", :fail)
assert_validation(:file_name, "..\bad", :fail)
assert_validation(:file_name, "\001bad", :fail)
assert_validation(:file_name, ".", :fail)
assert_validation(:file_name, "..", :fail)
end
def test_find_by_file_name
assert_equal @file1, WikiFile.find_by_file_name('file1.txt')
assert_nil WikiFile.find_by_file_name('unknown_file')
end
def assert_validation(field, value, expected_result)
values = {:file_name => '0', :description => '0', :content => '0'}
raise "WikiFile has no attribute named #{field.inspect}" unless values.has_key?(field)
values[field] = value
new_object = @web.wiki_files.create(values)
if expected_result == :pass then assert(new_object.valid?, new_object.errors.inspect)
elsif expected_result == :fail then assert(!new_object.valid?)
else raise "Unknown value of expected_result: #{expected_result.inspect}"
end
end
end
require File.dirname(__FILE__) + '/../test_helper'
require 'fileutils'
class WikiFileTest < Test::Unit::TestCase
include FileUtils
fixtures :webs, :pages, :revisions, :system, :wiki_references
def setup
@web = webs(:test_wiki)
mkdir_p("#{RAILS_ROOT}/public/wiki1/files/")
rm_rf("#{RAILS_ROOT}/public/wiki1/files/*")
WikiFile.delete_all
end
def test_basic_store_and_retrieve_ascii_file
@web.wiki_files.create(:file_name => 'binary_file', :description => 'Binary file', :content => "\001\002\003")
binary = WikiFile.find_by_file_name('binary_file')
assert_equal "\001\002\003", binary.content
end
def test_basic_store_and_retrieve_binary_file
@web.wiki_files.create(:file_name => 'text_file', :description => 'Text file', :content => "abc")
text = WikiFile.find_by_file_name('text_file')
assert_equal "abc", text.content
end
def test_storing_an_image
rails_gif = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read }
assert_equal rails_gif.size, File.size("#{RAILS_ROOT}/test/fixtures/rails.gif")
@web.wiki_files.create(:file_name => 'rails.gif', :description => 'Rails logo', :content => rails_gif)
rails_gif_from_db = WikiFile.find_by_file_name('rails.gif')
assert_equal rails_gif.size, rails_gif_from_db.content.size
assert_equal rails_gif, rails_gif_from_db.content
end
def test_mandatory_fields_validations
assert_validation(:file_name, '', :fail)
assert_validation(:file_name, nil, :fail)
assert_validation(:content, '', :fail)
assert_validation(:content, nil, :fail)
end
def test_upload_size_validation
assert_validation(:content, 'a' * 100.kilobytes, :pass)
assert_validation(:content, 'a' * (100.kilobytes + 1), :fail)
end
def test_file_name_size_validation
assert_validation(:file_name, '', :fail)
assert_validation(:file_name, 'a', :pass)
assert_validation(:file_name, 'a' * 50, :pass)
assert_validation(:file_name, 'a' * 51, :fail)
end
def test_file_name_pattern_validation
assert_validation(:file_name, ".. Accep-table File.name", :pass)
assert_validation(:file_name, "/bad", :fail)
assert_validation(:file_name, "~bad", :fail)
assert_validation(:file_name, "..\bad", :fail)
assert_validation(:file_name, "\001bad", :fail)
assert_validation(:file_name, ".", :fail)
assert_validation(:file_name, "..", :fail)
end
def test_find_by_file_name
assert_equal @file1, WikiFile.find_by_file_name('file1.txt')
assert_nil WikiFile.find_by_file_name('unknown_file')
end
def assert_validation(field, value, expected_result)
values = {:file_name => '0', :description => '0', :content => '0'}
raise "WikiFile has no attribute named #{field.inspect}" unless values.has_key?(field)
values[field] = value
new_object = @web.wiki_files.create(values)
if expected_result == :pass then assert(new_object.valid?, new_object.errors.inspect)
elsif expected_result == :fail then assert(!new_object.valid?)
else raise "Unknown value of expected_result: #{expected_result.inspect}"
end
end
end