Upgrade openid_consumer_plugin to latest. Thanks to Matt Pelletier for the rewrite.

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@503 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
lukemelia 2007-03-30 05:00:25 +00:00
parent 226655da8a
commit e0787cd627
244 changed files with 668 additions and 17990 deletions

View file

@ -1,13 +0,0 @@
* trunk *
break with true value [Kaspar Schiess]
* 2.1 *
After actions [Saimon Moore]
* 2.0 * (2006-01-20 15:26:28 -0500)
Enter / Exit actions
Transition guards
Guards and actions can be a symbol pointing to a method or a Proc
* 1.0 * (2006-01-15 12:16:55 -0500)
Initial Release

View file

@ -1,20 +0,0 @@
Copyright (c) 2006 Scott Barron
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.

View file

@ -1,33 +0,0 @@
= Acts As State Machine
This act gives an Active Record model the ability to act as a finite state
machine (FSM).
Acquire via subversion at:
http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk
If prompted, use the user/pass anonymous/anonymous.
== Example
class Order < ActiveRecord::Base
acts_as_state_machine :initial => :opened
state :opened
state :closed, :enter => Proc.new {|o| Mailer.send_notice(o)}
state :returned
event :close do
transitions :to => :closed, :from => :opened
end
event :return do
transitions :to => :returned, :from => :closed
end
end
o = Order.create
o.close! # notice is sent by mailer
o.return!

View file

@ -1,28 +0,0 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => [:clean_db, :test]
desc 'Remove the stale db file'
task :clean_db do
`rm -f #{File.dirname(__FILE__)}/test/state_machine.sqlite.db`
end
desc 'Test the acts as state machine plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the acts as state machine plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'Acts As State Machine'
rdoc.options << '--line-numbers --inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('TODO')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View file

@ -1,11 +0,0 @@
* Currently invalid events are ignored, create an option so that they can be
ignored or raise an exception.
* Query for a list of possible next states.
* Make listing states optional since they can be inferred from the events.
Only required to list a state if you want to define a transition block for it.
* Real transition actions
* Default states

View file

@ -1,5 +0,0 @@
require 'acts_as_state_machine'
ActiveRecord::Base.class_eval do
include ScottBarron::Acts::StateMachine
end

View file

@ -1,268 +0,0 @@
module ScottBarron #:nodoc:
module Acts #:nodoc:
module StateMachine #:nodoc:
class InvalidState < Exception #:nodoc:
end
class NoInitialState < Exception #:nodoc:
end
def self.included(base) #:nodoc:
base.extend ActMacro
end
module SupportingClasses
class State
attr_reader :name
def initialize(name, opts)
@name, @opts = name, opts
end
def entering(record)
enteract = @opts[:enter]
record.send(:run_transition_action, enteract) if enteract
end
def entered(record)
afteractions = @opts[:after]
return unless afteractions
Array(afteractions).each do |afteract|
record.send(:run_transition_action, afteract)
end
end
def exited(record)
exitact = @opts[:exit]
record.send(:run_transition_action, exitact) if exitact
end
end
class StateTransition
attr_reader :from, :to, :opts
def initialize(opts)
@from, @to, @guard = opts[:from], opts[:to], opts[:guard]
@opts = opts
end
def guard(obj)
@guard ? obj.send(:run_transition_action, @guard) : true
end
def perform(record)
return false unless guard(record)
loopback = record.current_state == to
states = record.class.read_inheritable_attribute(:states)
next_state = states[to]
old_state = states[record.current_state]
next_state.entering(record) unless loopback
record.update_attribute(record.class.state_column, to.to_s)
next_state.entered(record) unless loopback
old_state.exited(record) unless loopback
true
end
def ==(obj)
@from == obj.from && @to == obj.to
end
end
class Event
attr_reader :name
attr_reader :transitions
attr_reader :opts
def initialize(name, opts, transition_table, &block)
@name = name.to_sym
@transitions = transition_table[@name] = []
instance_eval(&block) if block
@opts = opts
@opts.freeze
@transitions.freeze
freeze
end
def next_states(record)
@transitions.select { |t| t.from == record.current_state }
end
def fire(record)
next_states(record).each do |transition|
break true if transition.perform(record)
end
end
def transitions(trans_opts)
Array(trans_opts[:from]).each do |s|
@transitions << SupportingClasses::StateTransition.new(trans_opts.merge({:from => s.to_sym}))
end
end
end
end
module ActMacro
# Configuration options are
#
# * +column+ - specifies the column name to use for keeping the state (default: state)
# * +initial+ - specifies an initial state for newly created objects (required)
def acts_as_state_machine(opts)
self.extend(ClassMethods)
raise NoInitialState unless opts[:initial]
write_inheritable_attribute :states, {}
write_inheritable_attribute :initial_state, opts[:initial]
write_inheritable_attribute :transition_table, {}
write_inheritable_attribute :event_table, {}
write_inheritable_attribute :state_column, opts[:column] || 'state'
class_inheritable_reader :initial_state
class_inheritable_reader :state_column
class_inheritable_reader :transition_table
class_inheritable_reader :event_table
self.send(:include, ScottBarron::Acts::StateMachine::InstanceMethods)
before_create :set_initial_state
after_create :run_initial_state_actions
end
end
module InstanceMethods
def set_initial_state #:nodoc:
write_attribute self.class.state_column, self.class.initial_state.to_s
end
def run_initial_state_actions
initial = self.class.read_inheritable_attribute(:states)[self.class.initial_state.to_sym]
initial.entering(self)
initial.entered(self)
end
# Returns the current state the object is in, as a Ruby symbol.
def current_state
self.send(self.class.state_column).to_sym
end
# Returns what the next state for a given event would be, as a Ruby symbol.
def next_state_for_event(event)
ns = next_states_for_event(event)
ns.empty? ? nil : ns.first.to
end
def next_states_for_event(event)
self.class.read_inheritable_attribute(:transition_table)[event.to_sym].select do |s|
s.from == current_state
end
end
def run_transition_action(action)
Symbol === action ? self.method(action).call : action.call(self)
end
private :run_transition_action
end
module ClassMethods
# Returns an array of all known states.
def states
read_inheritable_attribute(:states).keys
end
# Define an event. This takes a block which describes all valid transitions
# for this event.
#
# Example:
#
# class Order < ActiveRecord::Base
# acts_as_state_machine :initial => :open
#
# state :open
# state :closed
#
# event :close_order do
# transitions :to => :closed, :from => :open
# end
# end
#
# +transitions+ takes a hash where <tt>:to</tt> is the state to transition
# to and <tt>:from</tt> is a state (or Array of states) from which this
# event can be fired.
#
# This creates an instance method used for firing the event. The method
# created is the name of the event followed by an exclamation point (!).
# Example: <tt>order.close_order!</tt>.
def event(event, opts={}, &block)
tt = read_inheritable_attribute(:transition_table)
et = read_inheritable_attribute(:event_table)
e = et[event.to_sym] = SupportingClasses::Event.new(event, opts, tt, &block)
define_method("#{event.to_s}!") { e.fire(self) }
end
# Define a state of the system. +state+ can take an optional Proc object
# which will be executed every time the system transitions into that
# state. The proc will be passed the current object.
#
# Example:
#
# class Order < ActiveRecord::Base
# acts_as_state_machine :initial => :open
#
# state :open
# state :closed, Proc.new { |o| Mailer.send_notice(o) }
# end
def state(name, opts={})
state = SupportingClasses::State.new(name.to_sym, opts)
read_inheritable_attribute(:states)[name.to_sym] = state
define_method("#{state.name}?") { current_state == state.name }
end
# Wraps ActiveRecord::Base.find to conveniently find all records in
# a given state. Options:
#
# * +number+ - This is just :first or :all from ActiveRecord +find+
# * +state+ - The state to find
# * +args+ - The rest of the args are passed down to ActiveRecord +find+
def find_in_state(number, state, *args)
with_state_scope state do
find(number, *args)
end
end
# Wraps ActiveRecord::Base.count to conveniently count all records in
# a given state. Options:
#
# * +state+ - The state to find
# * +args+ - The rest of the args are passed down to ActiveRecord +find+
def count_in_state(state, *args)
with_state_scope state do
count(*args)
end
end
# Wraps ActiveRecord::Base.calculate to conveniently calculate all records in
# a given state. Options:
#
# * +state+ - The state to find
# * +args+ - The rest of the args are passed down to ActiveRecord +calculate+
def calculate_in_state(state, *args)
with_state_scope state do
calculate(*args)
end
end
protected
def with_state_scope(state)
raise InvalidState unless states.include?(state)
with_scope :find => {:conditions => ["#{table_name}.#{state_column} = ?", state.to_s]} do
yield if block_given?
end
end
end
end
end
end

View file

@ -1,224 +0,0 @@
require File.dirname(__FILE__) + '/test_helper'
include ScottBarron::Acts::StateMachine
class ActsAsStateMachineTest < Test::Unit::TestCase
fixtures :conversations
def test_no_initial_value_raises_exception
assert_raise(NoInitialState) {
Person.acts_as_state_machine({})
}
end
def test_initial_state_value
assert_equal :needs_attention, Conversation.initial_state
end
def test_column_was_set
assert_equal 'state_machine', Conversation.state_column
end
def test_initial_state
c = Conversation.create
assert_equal :needs_attention, c.current_state
assert c.needs_attention?
end
def test_states_were_set
[:needs_attention, :read, :closed, :awaiting_response, :junk].each do |s|
assert Conversation.states.include?(s)
end
end
def test_event_methods_created
c = Conversation.create
%w(new_message! view! reply! close! junk! unjunk!).each do |event|
assert c.respond_to?(event)
end
end
def test_query_methods_created
c = Conversation.create
%w(needs_attention? read? closed? awaiting_response? junk?).each do |event|
assert c.respond_to?(event)
end
end
def test_transition_table
tt = Conversation.transition_table
assert tt[:new_message].include?(SupportingClasses::StateTransition.new(:from => :read, :to => :needs_attention))
assert tt[:new_message].include?(SupportingClasses::StateTransition.new(:from => :closed, :to => :needs_attention))
assert tt[:new_message].include?(SupportingClasses::StateTransition.new(:from => :awaiting_response, :to => :needs_attention))
end
def test_next_state_for_event
c = Conversation.create
assert_equal :read, c.next_state_for_event(:view)
end
def test_change_state
c = Conversation.create
c.view!
assert c.read?
end
def test_can_go_from_read_to_closed_because_guard_passes
c = Conversation.create
c.can_close = true
c.view!
c.reply!
c.close!
assert_equal :closed, c.current_state
end
def test_cannot_go_from_read_to_closed_because_of_guard
c = Conversation.create
c.can_close = false
c.view!
c.reply!
c.close!
assert_equal :read, c.current_state
end
def test_ignore_invalid_events
c = Conversation.create
c.view!
c.junk!
# This is the invalid event
c.new_message!
assert_equal :junk, c.current_state
end
def test_entry_action_executed
c = Conversation.create
c.read_enter = false
c.view!
assert c.read_enter
end
def test_after_actions_executed
c = Conversation.create
c.read_after_first = false
c.read_after_second = false
c.closed_after = false
c.view!
assert c.read_after_first
assert c.read_after_second
c.can_close = true
c.close!
assert c.closed_after
assert_equal :closed, c.current_state
end
def test_after_actions_not_run_on_loopback_transition
c = Conversation.create
c.view!
c.read_after_first = false
c.read_after_second = false
c.view!
assert !c.read_after_first
assert !c.read_after_second
c.can_close = true
c.close!
c.closed_after = false
c.close!
assert !c.closed_after
end
def test_exit_action_executed
c = Conversation.create
c.read_exit = false
c.view!
c.junk!
assert c.read_exit
end
def test_entry_and_exit_not_run_on_loopback_transition
c = Conversation.create
c.view!
c.read_enter = false
c.read_exit = false
c.view!
assert !c.read_enter
assert !c.read_exit
end
def test_entry_and_after_actions_called_for_initial_state
c = Conversation.create
assert c.needs_attention_enter
assert c.needs_attention_after
end
def test_run_transition_action_is_private
c = Conversation.create
assert_raise(NoMethodError) { c.run_transition_action :foo }
end
def test_find_all_in_state
cs = Conversation.find_in_state(:all, :read)
assert_equal 2, cs.size
end
def test_find_first_in_state
c = Conversation.find_in_state(:first, :read)
assert_equal conversations(:first).id, c.id
end
def test_find_all_in_state_with_conditions
cs = Conversation.find_in_state(:all, :read, :conditions => ['subject = ?', conversations(:second).subject])
assert_equal 1, cs.size
assert_equal conversations(:second).id, cs.first.id
end
def test_find_first_in_state_with_conditions
c = Conversation.find_in_state(:first, :read, :conditions => ['subject = ?', conversations(:second).subject])
assert_equal conversations(:second).id, c.id
end
def test_count_in_state
cnt0 = Conversation.count(['state_machine = ?', 'read'])
cnt = Conversation.count_in_state(:read)
assert_equal cnt0, cnt
end
def test_count_in_state_with_conditions
cnt0 = Conversation.count(['state_machine = ? AND subject = ?', 'read', 'Foo'])
cnt = Conversation.count_in_state(:read, ['subject = ?', 'Foo'])
assert_equal cnt0, cnt
end
def test_find_in_invalid_state_raises_exception
assert_raise(InvalidState) {
Conversation.find_in_state(:all, :dead)
}
end
def test_count_in_invalid_state_raises_exception
assert_raise(InvalidState) {
Conversation.count_in_state(:dead)
}
end
def test_can_access_events_via_event_table
event = Conversation.event_table[:junk]
assert_equal :junk, event.name
assert_equal "finished", event.opts[:note]
end
end

View file

@ -1,18 +0,0 @@
sqlite:
:adapter: sqlite
:dbfile: state_machine.sqlite.db
sqlite3:
:adapter: sqlite3
:dbfile: state_machine.sqlite3.db
postgresql:
:adapter: postgresql
:username: postgres
:password: postgres
:database: state_machine_test
:min_messages: ERROR
mysql:
:adapter: mysql
:host: localhost
:username: rails
:password:
:database: state_machine_test

View file

@ -1,67 +0,0 @@
class Conversation < ActiveRecord::Base
attr_writer :can_close
attr_accessor :read_enter, :read_exit, :read_after_first, :read_after_second,
:closed_after, :needs_attention_enter, :needs_attention_after
acts_as_state_machine :initial => :needs_attention, :column => 'state_machine'
state :needs_attention, :enter => Proc.new { |o| o.needs_attention_enter = true },
:after => Proc.new { |o| o.needs_attention_after = true }
state :read, :enter => :read_enter_action,
:exit => Proc.new { |o| o.read_exit = true },
:after => [:read_after_first_action, :read_after_second_action]
state :closed, :after => :closed_after_action
state :awaiting_response
state :junk
event :new_message do
transitions :to => :needs_attention, :from => [:read, :closed, :awaiting_response]
end
event :view do
transitions :to => :read, :from => [:needs_attention, :read]
end
event :reply do
transitions :to => :awaiting_response, :from => [:read, :closed]
end
event :close do
transitions :to => :closed, :from => [:read, :awaiting_response], :guard => Proc.new {|o| o.can_close?}
transitions :to => :read, :from => [:read, :awaiting_response], :guard => :always_true
end
event :junk, :note => "finished" do
transitions :to => :junk, :from => [:read, :closed, :awaiting_response]
end
event :unjunk do
transitions :to => :closed, :from => :junk
end
def can_close?
@can_close
end
def read_enter_action
self.read_enter = true
end
def always_true
true
end
def read_after_first_action
self.read_after_first = true
end
def read_after_second_action
self.read_after_second = true
end
def closed_after_action
self.closed_after = true
end
end

View file

@ -1,11 +0,0 @@
first:
id: 1
state_machine: read
subject: This is a test
closed: false
second:
id: 2
state_machine: read
subject: Foo
closed: false

View file

@ -1,2 +0,0 @@
class Person < ActiveRecord::Base
end

View file

@ -1,11 +0,0 @@
ActiveRecord::Schema.define(:version => 1) do
create_table :conversations, :force => true do |t|
t.column :state_machine, :string
t.column :subject, :string
t.column :closed, :boolean
end
create_table :people, :force => true do |t|
t.column :name, :string
end
end

View file

@ -1,38 +0,0 @@
$:.unshift(File.dirname(__FILE__) + '/../lib')
RAILS_ROOT = File.dirname(__FILE__)
require 'rubygems'
require 'test/unit'
require 'active_record'
require 'active_record/fixtures'
require 'active_support/binding_of_caller'
require 'active_support/breakpoint'
require "#{File.dirname(__FILE__)}/../init"
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite'])
load(File.dirname(__FILE__) + "/schema.rb") if File.exist?(File.dirname(__FILE__) + "/schema.rb")
Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
class Test::Unit::TestCase #:nodoc:
def create_fixtures(*table_names)
if block_given?
Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield }
else
Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
end
end
# Turn off transactional fixtures if you're working with MyISAM tables in MySQL
self.use_transactional_fixtures = true
# Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
self.use_instantiated_fixtures = false
# Add more helper methods to be used by all tests here...
end

View file

@ -1,28 +0,0 @@
ARTS is Another RJS Test System
For a complete tutorial, see http://glu.ttono.us/articles/2006/05/29/guide-test-driven-rjs-with-arts.
Usage:
assert_rjs :alert, 'Hi!'
assert_rjs :assign, 'a', '2'
assert_rjs :call, 'foo', 'bar', 'baz'
assert_rjs :draggable, 'draggable_item'
assert_rjs :drop_receiving, 'receiving_item'
assert_rjs :hide, "post_1", "post_2", "post_3"
assert_rjs :insert_html, :bottom, 'posts'
assert_rjs :redirect_to, :action => 'list'
assert_rjs :remove, "post_1", "post_2", "post_3"
assert_rjs :replace, 'completely_replaced_div'
assert_rjs :replace, 'completely_replaced_div', '<p>This replaced the div</p>'
assert_rjs :replace, 'completely_replaced_div', /replaced the div/
assert_rjs :replace_html, 'replaceable_div', "This goes inside the div"
assert_rjs :show, "post_1", "post_2", "post_3"
assert_rjs :sortable, 'sortable_item'
assert_rjs :toggle, "post_1", "post_2", "post_3"
assert_rjs :visual_effect, :highlight, "posts", :duration => '1.0'
For the square bracket syntax (page['some_id'].toggle) use :page followed by the id and then subsequent method calls. Assignment requires a '=' at the end of the method name followed by the value.
assert_rjs :page, 'some_id', :toggle
assert_rjs :page, 'some_id', :style, :color=, 'red'

View file

@ -1,7 +0,0 @@
author: Kevin Clark
summary: RJS Assertion Plugin
homepage: http://glu.ttono.us
plugin:
version: 0.5
license: MIT
rails_version: 1.1.2+

View file

@ -1,3 +0,0 @@
# Give testing some culture
require 'test/unit/testcase'
Test::Unit::TestCase.send :include, Arts

View file

@ -1 +0,0 @@
puts IO.read(File.join(File.dirname(__FILE__), 'README'))

View file

@ -1,133 +0,0 @@
module Arts
include ActionView::Helpers::PrototypeHelper
include ActionView::Helpers::ScriptaculousHelper
include ActionView::Helpers::JavaScriptHelper
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::TagHelper
def assert_rjs(action, *args, &block)
respond_to?("assert_rjs_#{action}") ?
send("assert_rjs_#{action}", *args) :
assert(lined_response.include?(create_generator.send(action, *args, &block)),
generic_error(action, args))
end
def assert_no_rjs(action, *args, &block)
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs(action, *args, &block) }
end
def assert_rjs_insert_html(*args)
position = args.shift
item_id = args.shift
content = extract_matchable_content(args)
unless content.blank?
case content
when Regexp
assert_match Regexp.new("new Insertion\.#{position.to_s.camelize}(.*#{item_id}.*,.*#{content.source}.*);"),
@response.body
when String
assert lined_response.include?("new Insertion.#{position.to_s.camelize}(\"#{item_id}\", #{content});"),
"No insert_html call found for \n" +
" position: '#{position}' id: '#{item_id}' \ncontent: \n" +
"#{content}\n" +
"in response:\n#{lined_response}"
else
raise "Invalid content type"
end
else
assert_match Regexp.new("new Insertion\.#{position.to_s.camelize}(.*#{item_id}.*,.*?);"),
@response.body
end
end
def assert_rjs_replace_html(*args)
div = args.shift
content = extract_matchable_content(args)
unless content.blank?
case content
when Regexp
assert_match Regexp.new("Element.update(.*#{div}.*,.*#{content.source}.*);"),
@response.body
when String
assert lined_response.include?("Element.update(\"#{div}\", #{content});"),
"No replace_html call found on div: '#{div}' and content: \n#{content}\n" +
"in response:\n#{lined_response}"
else
raise "Invalid content type"
end
else
assert_match Regexp.new("Element.update(.*#{div}.*,.*?);"), @response.body
end
end
def assert_rjs_replace(*args)
div = args.shift
content = extract_matchable_content(args)
unless content.blank?
case content
when Regexp
assert_match Regexp.new("Element.replace(.*#{div}.*,.*#{content.source}.*);"),
@response.body
when String
assert lined_response.include?("Element.replace(\"#{div}\", #{content});"),
"No replace call found on div: '#{div}' and content: \n#{content}\n" +
"in response:\n#{lined_response}"
else
raise "Invalid content type"
end
else
assert_match Regexp.new("Element.replace(.*#{div}.*,.*?);"), @response.body
end
end
# To deal with [] syntax. I hate JavaScriptProxy so.. SO very much
def assert_rjs_page(*args)
content = build_method_chain!(args)
assert_match Regexp.new(Regexp.escape(content)), @response.body,
"Content did not include:\n #{content.to_s}"
end
protected
def build_method_chain!(args)
content = create_generator.send(:[], args.shift) # start $('some_id')....
while !args.empty?
if (method = args.shift.to_s) =~ /(.*)=$/
content = content.__send__(method, args.shift)
break
else
content = content.__send__(method)
content = content.__send__(:function_chain).first if args.empty?
end
end
content
end
def lined_response
@response.body.split("\n")
end
def create_generator
block = Proc.new { |*args| yield *args if block_given? }
JavaScriptGenerator.new self, &block
end
def generic_error(action, args)
"#{action} with args [#{args.join(" ")}] does not show up in response:\n#{lined_response}"
end
def extract_matchable_content(args)
if args.size == 1 and args.first.is_a? Regexp
return args.first
else
return create_generator.send(:arguments_for_call, args)
end
end
end

View file

@ -1,402 +0,0 @@
$:.unshift(File.dirname(__FILE__) + '/../lib')
require File.dirname(__FILE__) + '/../../../../config/environment'
require 'test/unit'
require 'rubygems'
require 'breakpoint'
require 'action_controller/test_process'
ActionController::Base.logger = nil
ActionController::Base.ignore_missing_templates = false
ActionController::Routing::Routes.reload rescue nil
class ArtsController < ActionController::Base
def alert
render :update do |page|
page.alert 'This is an alert'
end
end
def assign
render :update do |page|
page.assign 'a', '2'
end
end
def call
render :update do |page|
page.call 'foo', 'bar', 'baz'
end
end
def draggable
render :update do |page|
page.draggable 'my_image', :revert => true
end
end
def drop_receiving
render :update do |page|
page.drop_receiving "my_cart", :url => { :controller => "cart", :action => "add" }
end
end
def hide
render :update do |page|
page.hide 'some_div'
end
end
def insert_html
render :update do |page|
page.insert_html :bottom, 'content', 'Stuff in the content div'
end
end
def redirect
render :update do |page|
page.redirect_to :controller => 'sample', :action => 'index'
end
end
def remove
render :update do |page|
page.remove 'offending_div'
end
end
def replace
render :update do |page|
page.replace 'person_45', '<div>This replaces person_45</div>'
end
end
def replace_html
render :update do |page|
page.replace_html 'person_45', 'This goes inside person_45'
end
end
def show
render :update do |page|
page.show 'post_1', 'post_2', 'post_3'
end
end
def sortable
render :update do |page|
page.sortable 'sortable_item'
end
end
def toggle
render :update do |page|
page.toggle "post_1", "post_2", "post_3"
end
end
def visual_effect
render :update do |page|
page.visual_effect :highlight, "posts", :duration => '1.0'
end
end
def page_with_one_chained_method
render :update do |page|
page['some_id'].toggle
end
end
def page_with_assignment
render :update do |page|
page['some_id'].style.color = 'red'
end
end
def rescue_errors(e) raise e end
end
class ArtsTest < Test::Unit::TestCase
def setup
@controller = ArtsController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_alert
get :alert
assert_nothing_raised { assert_rjs :alert, 'This is an alert' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :alert, 'This is not an alert'
end
assert_nothing_raised { assert_no_rjs :alert, 'This is not an alert' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :alert, 'This is an alert'
end
end
def test_assign
get :assign
assert_nothing_raised { assert_rjs :assign, 'a', '2' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :assign, 'a', '3'
end
assert_nothing_raised { assert_no_rjs :assign, 'a', '3' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :assign, 'a', '2'
end
end
def test_call
get :call
assert_nothing_raised { assert_rjs :call, 'foo', 'bar', 'baz' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :call, 'foo', 'bar'
end
assert_nothing_raised { assert_no_rjs :call, 'foo', 'bar' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :call, 'foo', 'bar', 'baz'
end
end
def test_draggable
get :draggable
assert_nothing_raised { assert_rjs :draggable, 'my_image', :revert => true }
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :draggable, 'not_my_image'
end
assert_nothing_raised { assert_no_rjs :draggable, 'not_my_image' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :draggable, 'my_image', :revert => true
end
end
def test_drop_receiving
get :drop_receiving
assert_nothing_raised { assert_rjs :drop_receiving, "my_cart", :url => { :controller => "cart", :action => "add" } }
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :drop_receiving, "my_cart"
end
assert_nothing_raised { assert_no_rjs :drop_receiving, "my_cart" }
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :drop_receiving, "my_cart", :url => { :controller => "cart", :action => "add" }
end
end
def test_hide
get :hide
assert_nothing_raised { assert_rjs :hide, 'some_div' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :hide, 'some_other_div'
end
assert_nothing_raised { assert_no_rjs :hide, 'not_some_div' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :hide, 'some_div'
end
end
def test_insert_html
get :insert_html
assert_nothing_raised do
# No content matching
assert_rjs :insert_html, :bottom, 'content'
# Exact content matching
assert_rjs :insert_html, :bottom, 'content', 'Stuff in the content div'
# Regex matching
assert_rjs :insert_html, :bottom, 'content', /in.*content/
assert_no_rjs :insert_html, :bottom, 'not_our_div'
assert_no_rjs :insert_html, :bottom, 'content', /in.*no content/
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :insert_html, :bottom, 'content'
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :insert_html, :bottom, 'no_content'
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :insert_html, :bottom, 'content', /in the/
end
end
def test_redirect_to
get :redirect
assert_nothing_raised do
assert_rjs :redirect_to, :controller => 'sample', :action => 'index'
assert_no_rjs :redirect_to, :controller => 'sample', :action => 'show'
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :redirect_to, :controller => 'doesnt', :action => 'exist'
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :redirect_to, :controller => 'sample', :action => 'index'
end
end
def test_remove
get :remove
assert_nothing_raised do
assert_rjs :remove, 'offending_div'
assert_no_rjs :remove, 'dancing_happy_div'
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :remove, 'dancing_happy_div'
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :remove, 'offending_div'
end
end
def test_replace
get :replace
assert_nothing_raised do
# No content matching
assert_rjs :replace, 'person_45'
# String content matching
assert_rjs :replace, 'person_45', '<div>This replaces person_45</div>'
# regexp content matching
assert_rjs :replace, 'person_45', /<div>.*person_45.*<\/div>/
assert_no_rjs :replace, 'person_45', '<div>This replaces person_46</div>'
assert_no_rjs :replace, 'person_45', /person_46/
end
assert_raises(Test::Unit::AssertionFailedError) { assert_no_rjs :replace, 'person_45' }
assert_raises(Test::Unit::AssertionFailedError) { assert_no_rjs :replace, 'person_45', /person_45/ }
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs :replace, 'person_46' }
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs :replace, 'person_45', 'bad stuff' }
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs :replace, 'person_45', /not there/}
end
def test_replace_html
get :replace_html
assert_nothing_raised do
# No content matching
assert_rjs :replace_html, 'person_45'
# String content matching
assert_rjs :replace_html, 'person_45', 'This goes inside person_45'
# Regexp content matching
assert_rjs :replace_html, 'person_45', /goes inside/
assert_no_rjs :replace_html, 'person_46'
assert_no_rjs :replace_html, 'person_45', /doesn't go inside/
end
assert_raises(Test::Unit::AssertionFailedError) { assert_no_rjs :replace_html, 'person_45' }
assert_raises(Test::Unit::AssertionFailedError) { assert_no_rjs :replace_html, 'person_45', /goes/ }
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs :replace_html, 'person_46' }
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs :replace_html, 'person_45', /gos inside/ }
end
def test_show
get :show
assert_nothing_raised do
assert_rjs :show, "post_1", "post_2", "post_3"
assert_no_rjs :show, 'post_4'
end
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs :show, 'post_4' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :show, "post_1", "post_2", "post_3"
end
end
def test_sortable
get :sortable
assert_nothing_raised do
assert_rjs :sortable, 'sortable_item'
assert_no_rjs :sortable, 'non-sortable-item'
end
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs :sortable, 'non-sortable-item' }
assert_raises(Test::Unit::AssertionFailedError) { assert_no_rjs :sortable, 'sortable_item' }
end
def test_toggle
get :toggle
assert_nothing_raised do
assert_rjs :toggle, "post_1", "post_2", "post_3"
assert_no_rjs :toggle, 'post_4'
end
assert_raises(Test::Unit::AssertionFailedError) { assert_rjs :toggle, 'post_4' }
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :toggle, "post_1", "post_2", "post_3"
end
end
def test_visual_effect
get :visual_effect
assert_nothing_raised do
assert_rjs :visual_effect, :highlight, "posts", :duration => '1.0'
assert_no_rjs :visual_effect, :highlight, "lists"
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :visual_effect, :highlight, "lists"
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :visual_effect, :highlight, "posts", :duration => '1.0'
end
end
# [] support
def test_page_with_one_chained_method
get :page_with_one_chained_method
assert_nothing_raised do
assert_rjs :page, 'some_id', :toggle
assert_no_rjs :page, 'some_other_id', :toggle
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_rjs :page, 'some_other_id', :toggle
assert_no_rjs :page, 'some_id', :toggle
end
end
def test_page_with_assignment
get :page_with_assignment
assert_nothing_raised do
assert_rjs :page, 'some_id', :style, :color=, 'red'
assert_no_rjs :page, 'some_id', :color=, 'red'
end
assert_raises(Test::Unit::AssertionFailedError) do
assert_no_rjs :page, 'some_id', :style, :color=, 'red'
assert_rjs :page, 'some_other_id', :style, :color=, 'red'
end
end
end

View file

@ -1,2 +0,0 @@
require 'extra_validations'
ActiveRecord::Base.extend ExtraValidations

View file

@ -1,29 +0,0 @@
module ExtraValidations
# Validates the value of the specified attribute by checking for a forbidden string
#
# class Person < ActiveRecord::Base
# validates_does_not_contain :first_name, :string => ','
# end
#
# A string must be provided or else an exception will be raised.
#
# Configuration options:
# * <tt>message</tt> - A custom error message (default is: "is invalid")
# * <tt>string</tt> - The string to verify is not included (note: must be supplied!)
# * <tt>on</tt> Specifies when this validation is active (default is :save, other options :create, :update)
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
# method, proc or string should return or evaluate to a true or false value.
def validates_does_not_contain(*attr_names)
configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :string => nil }
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
raise(ArgumentError, "A string must be supplied as the :string option of the configuration hash") unless configuration[:string].is_a?(String)
validates_each(attr_names, configuration) do |record, attr_name, value|
record.errors.add(attr_name, configuration[:message]) if value.to_s =~ Regexp.new(Regexp.escape(configuration[:string]))
end
end
end

View file

@ -1,184 +0,0 @@
Academic Free License (AFL) v. 3.0
This Academic Free License (the "License") applies to any original work
of authorship (the "Original Work") whose owner (the "Licensor") has
placed the following licensing notice adjacent to the copyright notice
for the Original Work:
Licensed under the Academic Free License version 3.0
1) Grant of Copyright License. Licensor grants You a worldwide,
royalty-free, non-exclusive, sublicensable license, for the duration of
the copyright, to do the following:
a) to reproduce the Original Work in copies, either alone or as part of
a collective work;
b) to translate, adapt, alter, transform, modify, or arrange the
Original Work, thereby creating derivative works ("Derivative Works")
based upon the Original Work;
c) to distribute or communicate copies of the Original Work and
Derivative Works to the public, under any license of your choice that
does not contradict the terms and conditions, including Licensor's
reserved rights and remedies, in this Academic Free License;
d) to perform the Original Work publicly; and
e) to display the Original Work publicly.
2) Grant of Patent License. Licensor grants You a worldwide,
royalty-free, non-exclusive, sublicensable license, under patent claims
owned or controlled by the Licensor that are embodied in the Original
Work as furnished by the Licensor, for the duration of the patents, to
make, use, sell, offer for sale, have made, and import the Original Work
and Derivative Works.
3) Grant of Source Code License. The term "Source Code" means the
preferred form of the Original Work for making modifications to it and
all available documentation describing how to modify the Original Work.
Licensor agrees to provide a machine-readable copy of the Source Code of
the Original Work along with each copy of the Original Work that
Licensor distributes. Licensor reserves the right to satisfy this
obligation by placing a machine-readable copy of the Source Code in an
information repository reasonably calculated to permit inexpensive and
convenient access by You for as long as Licensor continues to distribute
the Original Work.
4) Exclusions From License Grant. Neither the names of Licensor, nor the
names of any contributors to the Original Work, nor any of their
trademarks or service marks, may be used to endorse or promote products
derived from this Original Work without express prior permission of the
Licensor. Except as expressly stated herein, nothing in this License
grants any license to Licensor's trademarks, copyrights, patents, trade
secrets or any other intellectual property. No patent license is granted
to make, use, sell, offer for sale, have made, or import embodiments of
any patent claims other than the licensed claims defined in Section 2.
No license is granted to the trademarks of Licensor even if such marks
are included in the Original Work. Nothing in this License shall be
interpreted to prohibit Licensor from licensing under terms different
from this License any Original Work that Licensor otherwise would have a
right to license.
5) External Deployment. The term "External Deployment" means the use,
distribution, or communication of the Original Work or Derivative Works
in any way such that the Original Work or Derivative Works may be used
by anyone other than You, whether those works are distributed or
communicated to those persons or made available as an application
intended for use over a network. As an express condition for the grants
of license hereunder, You must treat any External Deployment by You of
the Original Work or a Derivative Work as a distribution under section
1(c).
6) Attribution Rights. You must retain, in the Source Code of any
Derivative Works that You create, all copyright, patent, or trademark
notices from the Source Code of the Original Work, as well as any
notices of licensing and any descriptive text identified therein as an
"Attribution Notice." You must cause the Source Code for any Derivative
Works that You create to carry a prominent Attribution Notice reasonably
calculated to inform recipients that You have modified the Original
Work.
7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants
that the copyright in and to the Original Work and the patent rights
granted herein by Licensor are owned by the Licensor or are sublicensed
to You under the terms of this License with the permission of the
contributor(s) of those copyrights and patent rights. Except as
expressly stated in the immediately preceding sentence, the Original
Work is provided under this License on an "AS IS" BASIS and WITHOUT
WARRANTY, either express or implied, including, without limitation, the
warranties of non-infringement, merchantability or fitness for a
particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL
WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential
part of this License. No license to the Original Work is granted by this
License except under this disclaimer.
8) Limitation of Liability. Under no circumstances and under no legal
theory, whether in tort (including negligence), contract, or otherwise,
shall the Licensor be liable to anyone for any indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or the use of the Original Work including,
without limitation, damages for loss of goodwill, work stoppage,
computer failure or malfunction, or any and all other commercial damages
or losses. This limitation of liability shall not apply to the extent
applicable law prohibits such limitation.
9) Acceptance and Termination. If, at any time, You expressly assented
to this License, that assent indicates your clear and irrevocable
acceptance of this License and all of its terms and conditions. If You
distribute or communicate copies of the Original Work or a Derivative
Work, You must make a reasonable effort under the circumstances to
obtain the express assent of recipients to the terms of this License.
This License conditions your rights to undertake the activities listed
in Section 1, including your right to create Derivative Works based upon
the Original Work, and doing so without honoring these terms and
conditions is prohibited by copyright law and international treaty.
Nothing in this License is intended to affect copyright exceptions and
limitations (including "fair use" or "fair dealing"). This License shall
terminate immediately and You may no longer exercise any of the rights
granted to You by this License upon your failure to honor the conditions
in Section 1(c).
10) Termination for Patent Action. This License shall terminate
automatically and You may no longer exercise any of the rights granted
to You by this License as of the date You commence an action, including
a cross-claim or counterclaim, against Licensor or any licensee alleging
that the Original Work infringes a patent. This termination provision
shall not apply for an action alleging patent infringement by
combinations of the Original Work with other software or hardware.
11) Jurisdiction, Venue and Governing Law. Any action or suit relating
to this License may be brought only in the courts of a jurisdiction
wherein the Licensor resides or in which Licensor conducts its primary
business, and under the laws of that jurisdiction excluding its
conflict-of-law provisions. The application of the United Nations
Convention on Contracts for the International Sale of Goods is expressly
excluded. Any use of the Original Work outside the scope of this License
or after its termination shall be subject to the requirements and
penalties of copyright or patent law in the appropriate jurisdiction.
This section shall survive the termination of this License.
12) Attorneys' Fees. In any action to enforce the terms of this License
or seeking damages relating thereto, the prevailing party shall be
entitled to recover its costs and expenses, including, without
limitation, reasonable attorneys' fees and costs incurred in connection
with such action, including any appeal of such action. This section
shall survive the termination of this License.
13) Miscellaneous. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable.
14) Definition of "You" in This License. "You" throughout this License,
whether in upper or lower case, means an individual or a legal entity
exercising rights under, and complying with all of the terms of, this
License. For legal entities, "You" includes any entity that controls, is
controlled by, or is under common control with you. For purposes of this
definition, "control" means (i) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
15) Right to Use. You may use the Original Work in all ways not
otherwise restricted or conditioned by this License or by law, and
Licensor promises not to interfere with or be responsible for such uses
by You.
16) Modification of This License. This License is Copyright (c) 2005
Lawrence Rosen. Permission is granted to copy, distribute, or
communicate this License without modification. Nothing in this License
permits You to modify this License as applied to the Original Work or to
Derivative Works. However, You may modify the text of this License and
copy, distribute or communicate your modified version (the "Modified
License") and apply it to other original works of authorship subject to
the following conditions: (i) You may not indicate in any way that your
Modified License is the "Academic Free License" or "AFL" and you may not
use those names in the name of your Modified License; (ii) You must
replace the notice specified in the first paragraph above with the
notice "Licensed under <insert your license name here>" or with a notice
of your own that is not confusingly similar to the notice in this
License; and (iii) You may not claim that your original works are open
source software unless your Modified License has been approved by Open
Source Initiative (OSI) and You comply with its license review and
certification process.

View file

@ -1,46 +0,0 @@
Self-referential, polymorphic has_many :through helper
Copyright 2006 Evan Weaver (see the LICENSE file)
"model :parent_class" may be required in some controllers or perhaps models in order for reloading to work properly, since the parent setup must be executed on the child every time the child class is reloaded.
Usage and help:
http://blog.evanweaver.com/articles/2006/06/02/has_many_polymorphs
Also see the source code, although it's probably not going to be super helpful to you.
Changelog:
22. api change; prefix on methods is now singular when using :rename_individual_collections
21. add configuration option to cache polymorphic classes in development mode
20. collection methods (push, delete, clear) now on individual collections
19.2. disjoint collection sides bugfix, don't raise on new records
19.1. double classify bugfix
19. large changes to properly support double polymorphism
18.2. bugfix to make sure the type gets checked on doubly polymorphic parents
18.1. bugfix for sqlite3 child attribute retrieval
18. bugfix for instantiating attributes of namespaced models
17.1. bugfix for double polymorphic relationships
17. double polymorphic relationships (includes new API method)
16. namespaced model support
15. bugfix for postgres and mysql under 1.1.6; refactored tests (thanks hildofur); properly handles legacy table names set with set_table_name()
14. sti support added (use the child class names, not the base class)
13. bug regarding table names with underscores in SQL query fixed
12.1. license change
12. file_column bug fixed
11. tests written; after_find and after_initialize now correctly called
10. bugfix
9. rollback
8. SQL performance enhancements added
7. rewrote singletons as full-fledged proxy class so that marshalling works (e.g. in the session)
6. caching added
5. fixed dependency reloading problem in development mode
4. license change
3. added :dependent support on the join table
1-2. no changelog
Known problems:
1. Plugin's test fixtures do not load properly for non-edge postgres, invalidating the tests.
2. quote_value() hack is stupid.

View file

@ -1 +0,0 @@
require 'has_many_polymorphs'

View file

@ -1,581 +0,0 @@
# self-referential, polymorphic has_many :through plugin
# http://blog.evanweaver.com/articles/2006/06/02/has_many_polymorphs
# operates via magic dust, and courage
if defined? Rails::Configuration
class Rails::Configuration
def has_many_polymorphs_cache_classes= *args
::ActiveRecord::Associations::ClassMethods.has_many_polymorphs_cache_classes = *args
end
end
end
module ActiveRecord
if ENV['RAILS_ENV'] =~ /development|test/ and ENV['USER'] == 'eweaver'
# enable this condition to get awesome association debugging
# you will get a folder "generated_models" in the current dir containing valid Ruby files
# explaining all ActiveRecord relationships set up by the plugin, as well as listing the
# line in the plugin that made each particular macro call
class << Base
COLLECTION_METHODS = [:belongs_to, :has_many, :has_and_belongs_to_many, :has_one].each do |method_name|
alias_method "original_#{method_name}".to_sym, method_name
undef_method method_name
end
unless defined? GENERATED_CODE_DIR
# automatic code generation for debugging... bitches
GENERATED_CODE_DIR = "generated_models"
system "rm -rf #{GENERATED_CODE_DIR}"
Dir.mkdir GENERATED_CODE_DIR
alias :original_method_missing :method_missing
def method_missing(method_name, *args, &block)
if COLLECTION_METHODS.include? method_name.to_sym
Dir.chdir GENERATED_CODE_DIR do
filename = "#{ActiveRecord::Associations::ClassMethods.demodulate(self.name.underscore)}.rb"
contents = File.open(filename).read rescue "\nclass #{self.name}\n\nend\n"
line = caller[1][/\:(\d+)\:/, 1]
contents[-5..-5] = "\n #{method_name} #{args[0..-2].inspect[1..-2]},\n #{args[-1].inspect[1..-2].gsub(" :", "\n :").gsub("=>", " => ")}\n#{ block ? " #{block.inspect.sub(/\@.*\//, '@')}\n" : ""} # called from line #{line}\n\n"
File.open(filename, "w") do |file|
file.puts contents
end
end
# doesn't handle blocks
self.send("original_#{method_name}", *args, &block)
else
self.send(:original_method_missing, method_name, *args, &block)
end
end
end
end
# and we want to track the reloader's shenanigans
(::Dependencies.log_activity = true) rescue nil
end
module Associations
module ClassMethods
mattr_accessor :has_many_polymorphs_cache_classes
def acts_as_double_polymorphic_join opts
raise RuntimeError, "Couldn't understand #{opts.inspect} options in acts_as_double_polymorphic_join. Please only specify the two relationships and their member classes; there are no options to set. " unless opts.length == 2
join_name = self.name.tableize.to_sym
opts.each do |polymorphs, children|
parent_hash_key = (opts.keys - [polymorphs]).first # parents are the entries in the _other_ children array
begin
parent_foreign_key = self.reflect_on_association(parent_hash_key.to_s.singularize.to_sym).primary_key_name
rescue NoMethodError
raise RuntimeError, "Couldn't find 'belongs_to' association for :#{parent_hash_key.to_s.singularize} in #{self.name}." unless parent_foreign_key
end
parents = opts[parent_hash_key]
conflicts = (children & parents) # set intersection
parents.each do |parent_name|
parent_class = parent_name.to_s.classify.constantize
reverse_polymorph = parent_hash_key.to_s.singularize
polymorph = polymorphs.to_s.singularize
parent_class.send(:has_many_polymorphs,
polymorphs, {:double => true,
:from => children,
:as => parent_hash_key.to_s.singularize.to_sym,
:through => join_name,
:dependent => :destroy,
:foreign_key => parent_foreign_key,
:foreign_type_key => parent_foreign_key.to_s.sub(/_id$/, '_type'),
:reverse_polymorph => reverse_polymorph,
:conflicts => conflicts,
:rename_individual_collections => false})
if conflicts.include? parent_name
# unify the alternate sides of the conflicting children
(conflicts).each do |method_name|
unless parent_class.instance_methods.include?(method_name)
parent_class.send(:define_method, method_name) do
(self.send("#{reverse_polymorph}_#{method_name}") +
self.send("#{polymorph}_#{method_name}")).freeze
end
end
end
# unify the join model
unless parent_class.instance_methods.include?(join_name)
parent_class.send(:define_method, join_name) do
(self.send("#{join_name}_as_#{reverse_polymorph}") +
self.send("#{join_name}_as_#{polymorph}")).freeze
end
end
end
end
end
end
def has_many_polymorphs(polymorphs, options, &block)
options.assert_valid_keys(:from, :acts_as, :as, :through, :foreign_key, :dependent, :double,
:rename_individual_collections, :foreign_type_key, :reverse_polymorph, :conflicts)
# the way this deals with extra parameters to the associations could use some work
options[:as] ||= options[:acts_as] ||= self.table_name.singularize.to_sym
# foreign keys follow the table name, not the class name in Rails 2.0
options[:foreign_key] ||= "#{options[:as].to_s}_id"
# no conflicts by default
options[:conflicts] ||= []
# construct the join table name
options[:through] ||= join_table((options[:as].to_s.pluralize or self.table_name), polymorphs)
if options[:reverse_polymorph]
options[:through_with_reverse_polymorph] = "#{options[:through]}_as_#{options[:reverse_polymorph]}".to_sym
else
options[:through_with_reverse_polymorph] = options[:through]
end
options[:join_class_name] ||= options[:through].to_s.classify
# the class must have_many on the join_table
opts = {:foreign_key => options[:foreign_key], :dependent => options[:dependent],
:class_name => options[:join_class_name]}
if options[:foreign_type_key]
opts[:conditions] = "#{options[:foreign_type_key]} = #{quote_value self.base_class.name}"
end
has_many demodulate(options[:through_with_reverse_polymorph]), opts
polymorph = polymorphs.to_s.singularize.to_sym
# add the base_class method to the join_table so that STI will work transparently
inject_before_save_into_join_table(options[:join_class_name], polymorph)
# get some reusable info
children, child_associations = {}, {}
options[:from].each do |child_plural|
children[child_plural] = child_plural.to_s.singularize.to_sym
child_associations[child_plural] = (options[:rename_individual_collections] ? "#{polymorph}_#{child_plural}".to_sym : child_plural)
end
# get our models out of the reloadable lists, if requested
if self.has_many_polymorphs_cache_classes
klasses = [self.name, options[:join_class_name], *children.values.map{|x| x.to_s.classify}]
klasses += basify_sti_classnames(klasses).keys.to_a.compact.uniq.map{|x| x.to_s.classify}
klasses.uniq!
klasses.each {|s| logger.debug "Ejecting #{s.inspect} from the autoload lists"}
begin
Dependencies.autoloaded_constants -= klasses
Dependencies.explicitly_unloadable_constants -= klasses
rescue NoMethodError
raise "Rails 1.2.0 or later is required to set config.has_many_polymorphs_cache_classes = true"
end
end
# auto-inject individually named associations for the children into the join model
create_virtual_associations_for_join_to_individual_children(children, polymorph, options)
# iterate through the polymorphic children, running the parent class's :has_many on each one
create_has_many_through_associations_for_parent_to_children(children, child_associations, polymorphs, polymorph, options)
# auto-inject the regular polymorphic associations into the child classes
create_has_many_through_associations_for_children_to_parent(children, polymorph, options)
create_general_collection_association_for_parent(polymorphs, polymorph, basify_sti_classnames(children), options, &block)
end
def self.demodulate(s)
s.to_s.gsub('/', '_').to_sym
end
protected
def demodulate(s)
ActiveRecord::Associations::ClassMethods.demodulate(s)
end
def basify_sti_classnames(hash)
# this blows
result = {}
hash.each do |plural, singular|
klass = plural.to_s.classify.constantize
if klass != klass.base_class
result[klass.base_class.table_name.to_sym] = klass.base_class.table_name.singularize.to_sym
else
result[plural] = singular
end
end
result
end
def inject_before_save_into_join_table(join_class_name, polymorph)
sti_hook = "sti_class_rewrite"
rewrite_procedure = %[
self.send(:#{polymorph}_type=, self.#{polymorph}_type.constantize.base_class.name)
]
# this also blows, and should be abstracted. alias_method_chain is not enough.
join_class_name.constantize.class_eval %[
unless instance_methods.include? "before_save_with_#{sti_hook}"
if instance_methods.include? "before_save"
alias_method :before_save_without_#{sti_hook}, :before_save
def before_save_with_#{sti_hook}
before_save_without_#{sti_hook}
#{rewrite_procedure}
end
else
def before_save_with_#{sti_hook}
#{rewrite_procedure}
end
end
alias_method :before_save, :before_save_with_#{sti_hook}
end
]
end
def create_virtual_associations_for_join_to_individual_children(children, polymorph, options)
children.each do |child_plural, child|
options[:join_class_name].constantize.instance_eval do
association_name = child.to_s
association_name += "_as_#{polymorph}" if options[:conflicts].include?(child_plural)
association = demodulate(association_name)
opts = {:class_name => child.to_s.classify,
:foreign_key => "#{polymorph}_id" }
unless self.reflect_on_all_associations.map(&:name).include? association
belongs_to association, opts
end
end
end
end
def create_has_many_through_associations_for_children_to_parent(children, polymorph, options)
children.each do |child_plural, child|
if child == options[:as]
raise RuntimeError, "You can't have a self-referential polymorphic has_many :through without renaming the non-polymorphic foreign key in the join model."
end
parent = self
child.to_s.classify.constantize.instance_eval do
# this shouldn't be called at all during doubles; there is no way to traverse to a
# double polymorphic parent (XXX is that right?)
unless options[:double] or options[:conflicts].include? self.name.tableize.to_sym
begin
require_dependency parent.name.underscore # XXX why is this here?
rescue MissingSourceFile
end
# the join table
through = demodulate(options[:through_with_reverse_polymorph]).to_s
through += "_as_child" if parent == self
through = through.to_sym
has_many through, :as => polymorph,
:class_name => options[:through].to_s.classify,
:dependent => options[:dependent]
association = options[:as].to_s.pluralize
association += "_of_#{polymorph.to_s.pluralize}" if options[:rename_individual_collections] # XXX check this
# the polymorphic parent association
has_many association.to_sym, :through => through,
:class_name => parent.name,
:source => options[:as],
:foreign_key => options[:foreign_key]
end
end
end
end
def create_has_many_through_associations_for_parent_to_children(children, child_associations, polymorphs, polymorph, options)
children.each do |child_plural, child|
#puts ":source => #{child}"
association = demodulate(child_associations[child_plural]).to_s
source = demodulate(child).to_s
if options[:conflicts].include? child_plural
# XXX what?
association = "#{polymorph}_#{association}" if options[:conflicts].include? self.name.tableize.to_sym
source += "_as_#{polymorph}"
end
# activerecord is broken when you try to anonymously extend an association in a namespaced model,
extension = self.class_eval %[
module #{association.classify + "AssociationExtension"}
def push *args
proxy_owner.send(:#{polymorphs}).send(:push, *args).select{|x| x.is_a? #{child.to_s.classify}}
end
alias :<< :push
def delete *args
proxy_owner.send(:#{polymorphs}).send(:delete, *args)
end
def clear
proxy_owner.send(:#{polymorphs}).send(:clear, #{child.to_s.classify})
end
self # required
end]
has_many association.to_sym, :through => demodulate(options[:through_with_reverse_polymorph]),
:source => source.to_sym,
:conditions => ["#{options[:join_class_name].constantize.table_name}.#{polymorph}_type = ?", child.to_s.classify.constantize.base_class.name],
:extend => extension
end
end
def create_general_collection_association_for_parent(collection_name, polymorph, children, options, &block)
# we need to explicitly rename all the columns because we are fetching all the children objects at once.
# if multiple objects have a 'title' column, for instance, there will be a collision and we will potentially
# lose data. if we alias the fields and then break them up later, there are no collisions.
join_model = options[:through].to_s.classify.constantize
# figure out what fields we wanna grab
select_fields = []
children.each do |plural, singular|
klass = plural.to_s.classify.constantize
klass.columns.map(&:name).each do |name|
select_fields << "#{klass.table_name}.#{name} as #{demodulate plural}_#{name}"
end
end
# now get the join model fields
join_model.columns.map(&:name).each do |name|
select_fields << "#{join_model.table_name}.#{name} as #{join_model.table_name}_#{name}"
end
from_table = self.table_name
left_joins = children.keys.map do |n|
klass = n.to_s.classify.constantize
"LEFT JOIN #{klass.table_name} ON #{join_model.table_name}.#{polymorph}_id = #{klass.table_name}.#{klass.primary_key} AND #{join_model.table_name}.#{polymorph}_type = '#{n.to_s.classify}'"
end
sql_query = 'SELECT ' + select_fields.join(', ') + " FROM #{join_model.table_name}" +
"\nJOIN #{from_table} as polymorphic_parent ON #{join_model.table_name}.#{options[:foreign_key]} = polymorphic_parent.#{self.primary_key}\n" +
left_joins.join("\n") + "\nWHERE "
if options[:foreign_type_key]
sql_query +="#{join_model.table_name}.#{options[:foreign_type_key]} = #{quote_value self.base_class.name} AND "
end
# for sqlite3 you have to reference the left-most table in WHERE clauses or rows with NULL
# join results sometimes get silently dropped. it's stupid.
sql_query += "#{join_model.table_name}.#{options[:foreign_key]} "
#puts("Built collection property query:\n #{sql_query}")
class_eval do
attr_accessor "#{collection_name}_cache"
cattr_accessor "#{collection_name}_options"
define_method(collection_name) do
if collection_name_cache = instance_variable_get("@#{collection_name}_cache")
#puts("Cache hit on #{collection_name}")
collection_name_cache
else
#puts("Cache miss on #{collection_name}")
rows = connection.select_all("#{sql_query}" + (new_record? ? "IS NULL" : "= #{self.id}"))
# this gives us a hash with keys for each object type
objectified = objectify_polymorphic_array(rows, "#{join_model}", "#{polymorph}_type")
# locally cache the different object types found
# this doesn't work... yet.
objectified.each do |key, array|
instance_variable_set("@#{ActiveRecord::Associations::ClassMethods.demodulate(key)}", array)
end
proxy_object = HasManyPolymorphsProxyCollection.new(objectified[:all], self, send("#{collection_name}_options"))
(class << proxy_object; self end).send(:class_eval, &block) if block_given?
instance_variable_set("@#{collection_name}_cache", proxy_object)
end
end
# in order not to break tests, see if we have been defined already
unless instance_methods.include? "reload_with_#{collection_name}"
define_method("reload_with_#{collection_name}") do
send("reload_without_#{collection_name}")
instance_variable_set("@#{collection_name}_cache", nil)
self
end
alias_method "reload_without_#{collection_name}", :reload
alias_method :reload, "reload_with_#{collection_name}"
end
end
send("#{collection_name}_options=",
options.merge(:collection_name => collection_name,
:type_key => "#{polymorph}_type",
:id_key => "#{polymorph}_id"))
# puts("Defined the collection proxy.\n#{collection_name}\n")
end
def join_table(a, b)
[a.to_s, b.to_s].sort.join("_").to_sym
end
unless self.respond_to? :quote_value
# hack it in (very badly) for Rails 1.1.6 people
def quote_value s
"'#{s.inspect[1..-2]}'"
end
end
end
################################################
# decided to leave this alone unless it becomes clear that there is some benefit
# in deriving from AssociationProxy
#
# the benefit would be custom finders on the collection, perhaps...
class HasManyPolymorphsProxyCollection < Array
alias :array_delete :delete
alias :array_push :push
alias :count :length
def initialize(contents, parent, options)
@parent = parent
@options = options
@join_class = options[:join_class_name].constantize
return if contents.blank?
super(contents)
end
def push(objs, args={})
objs = [objs] unless objs.is_a? Array
objs.each do |obj|
data = {@options[:foreign_key] => @parent.id,
@options[:type_key] => obj.class.base_class.to_s, @options[:id_key] => obj.id}
data.merge!({@options[:foreign_type_key] => @parent.class.base_class.to_s}) if @options[:foreign_type_key] # for double polymorphs
conditions_string = data.keys.map(&:to_s).push("").join(" = ? AND ")[0..-6]
if @join_class.find(:first, :conditions => [conditions_string] + data.values).blank?
@join_class.new(data).save!
end
end
if args[:reload]
reload
else
# we have to do this funky stuff instead of just array difference because +/.uniq returns a regular array,
# which doesn't have our special methods and configuration anymore
unless (difference = objs - collection).blank?
@parent.send("#{@options[:collection_name]}_cache=".to_sym, collection.array_push(*difference))
end
end
@parent.send(@options[:collection_name])
end
alias :<< :push
def delete(objs, args={})
if objs
objs = [objs] unless objs.is_a? Array
elsif args[:clear]
objs = collection
objs = objs.select{|obj| obj.is_a? args[:klass]} if args[:klass]
else
raise RuntimeError, "Invalid delete parameters (has_many_polymorphs)."
end
records = []
objs.each do |obj|
records += join_records.select do |record|
record.send(@options[:type_key]) == obj.class.base_class.to_s and
record.send(@options[:id_key]) == obj.id
end
end
reload if args[:reload]
unless records.blank?
records.map(&:destroy)
# XXX could be faster if we reversed the loops
deleted_items = collection.select do |item|
records.select {|join_record|
join_record.send(@options[:type_key]) == item.class.base_class.name and
join_record.send(@options[:id_key]) == item.id
}.length > 0
end
# keep the cache fresh, while we're at it. see comment in .push
deleted_items.each { |item| collection.array_delete(item) }
@parent.send("#{@options[:collection_name]}_cache=", collection)
return deleted_items unless deleted_items.empty?
end
nil
end
def clear(klass = nil)
result = delete(nil, :clear => true, :klass => klass)
return result if result
collection
end
def reload
# reset the cache, postponing reloading from the db until we really need it
@parent.reload
end
private
def join_records
@parent.send(ActiveRecord::Associations::ClassMethods.demodulate(@options[:through]))
end
def collection
@parent.send(@options[:collection_name])
end
end
end
class Base
# turns an array of hashes (db rows) into a hash consisting of :all (array of everything) and
# a hash key for each class type it finds, e.g. :posts and :comments
private
def objectify_polymorphic_array(array, join_model, type_field)
join_model = join_model.constantize
arrays_hash = {}
array.each do |element|
klass = element["#{join_model.table_name}_#{type_field}"].constantize
association = ActiveRecord::Associations::ClassMethods.demodulate(klass.name.pluralize.underscore.downcase)
hash = {}
# puts "Class #{klass.inspect}"
# puts "Association name: #{association.inspect}"
element.each do |key, value|
# puts "key #{key} - value #{value.inspect}"
if key =~ /^#{association}_(.+)/
hash[$1] = value
# puts "#{$1.inspect} assigned #{value.inspect}"
end
end
object = klass.instantiate(hash)
arrays_hash[:all] ||= []
arrays_hash[association] ||= []
arrays_hash[:all] << object
arrays_hash[association] << object
end
arrays_hash
end
end
end
#require 'ruby-debug'
#Debugger.start

View file

@ -1,8 +0,0 @@
swimmy:
id: 1
name: Swimmy
speed: 10
jaws:
id: 2
name: Jaws
speed: 20

View file

@ -1,3 +0,0 @@
shamu:
id: 1
name: Shamu

View file

@ -1,6 +0,0 @@
rover:
id: 1
name: Rover
spot:
id: 2
name: Spot

View file

@ -1,8 +0,0 @@
chloe:
id: 1
cat_type: Kitten
name: Chloe
alice:
id: 2
cat_type: Kitten
name: Alice

View file

@ -1,3 +0,0 @@
froggy:
id: 1
name: Froggy

View file

@ -1,6 +0,0 @@
kibbles:
the_petfood_primary_key: 1
name: Kibbles
bits:
the_petfood_primary_key: 2
name: Bits

View file

@ -1,6 +0,0 @@
puma:
id: 1
name: Puma
jacrazy:
id: 2
name: Jacrazy

View file

@ -1,4 +0,0 @@
class Aquatic::Fish < ActiveRecord::Base
# attr_accessor :after_find_test, :after_initialize_test
end

View file

@ -1,7 +0,0 @@
class Aquatic::PupilsWhale < ActiveRecord::Base
set_table_name "little_whale_pupils"
belongs_to :whale, :class_name => "Aquatic::Whale", :foreign_key => "whale_id"
belongs_to :aquatic_pupil, :polymorphic => true
end

View file

@ -1,11 +0,0 @@
# see http://dev.rubyonrails.org/ticket/5935
module Aquatic; end
require 'aquatic/fish'
require 'aquatic/pupils_whale'
class Aquatic::Whale < ActiveRecord::Base
has_many_polymorphs(:aquatic_pupils, :from => [:dogs, :"aquatic/fish"],
:through => "aquatic/pupils_whales") do
def blow; "result"; end
end
end

View file

@ -1,13 +0,0 @@
class BeautifulFightRelationship < ActiveRecord::Base
set_table_name 'keep_your_enemies_close'
belongs_to :enemy, :polymorphic => true
belongs_to :protector, :polymorphic => true
# polymorphic relationships with column names different from the relationship name
# are not supported by Rails
acts_as_double_polymorphic_join :enemies => [:dogs, :kittens, :frogs],
:protectors => [:wild_boars, :kittens, :"aquatic/fish", :dogs]
end

View file

@ -1,5 +0,0 @@
class Cat < ActiveRecord::Base
# STI base class
self.inheritance_column = 'cat_type'
end

View file

@ -1,16 +0,0 @@
class Dog < ActiveRecord::Base
attr_accessor :after_find_test, :after_initialize_test
set_table_name "bow_wows"
def after_find
@after_find_test = true
# puts "After find called on #{name}."
end
def after_initialize
@after_initialize_test = true
end
end

View file

@ -1,10 +0,0 @@
class EatersFoodstuff < ActiveRecord::Base
belongs_to :foodstuff, :class_name => "Petfood", :foreign_key => "foodstuff_id"
belongs_to :eater, :polymorphic => true
def before_save
self.some_attribute = 3
end
end

View file

@ -1,4 +0,0 @@
class Frog < ActiveRecord::Base
end

View file

@ -1,3 +0,0 @@
class Kitten < Cat
# has_many :eaters_parents, :dependent => true, :as => 'eater'
end

View file

@ -1,21 +0,0 @@
# see http://dev.rubyonrails.org/ticket/5935
require 'eaters_foodstuff'
require 'petfood'
require 'cat'
module Aquatic; end
require 'aquatic/fish'
require 'dog'
require 'wild_boar'
require 'kitten'
require 'tabby'
class Petfood < ActiveRecord::Base
set_primary_key 'the_petfood_primary_key'
has_many_polymorphs :eaters,
:from => [:dogs, :petfoods, :wild_boars, :kittens,
:tabbies, :"aquatic/fish"],
:dependent => :destroy,
:rename_individual_collections => true,
:acts_as => :foodstuff,
:foreign_key => "foodstuff_id"
end

View file

@ -1,2 +0,0 @@
class Tabby < Cat
end

View file

@ -1,3 +0,0 @@
class WildBoar < ActiveRecord::Base
end

View file

@ -1,52 +0,0 @@
ActiveRecord::Schema.define(:version => 0) do
create_table :petfoods, :force => true, :primary_key => :the_petfood_primary_key do |t|
t.column :name, :string
end
create_table :bow_wows, :force => true do |t|
t.column :name, :string
end
create_table :cats, :force => true do |t|
t.column :name, :string
t.column :cat_type, :string
end
create_table :frogs, :force => true do |t|
t.column :name, :string
end
create_table :wild_boars, :force => true do |t|
t.column :name, :string
end
create_table :eaters_foodstuffs, :force => true do |t|
t.column :foodstuff_id, :integer
t.column :eater_id, :integer
t.column :some_attribute, :integer, :default => 0
t.column :eater_type, :string
end
create_table :fish, :force => true do |t|
t.column :name, :string
t.column :speed, :integer
end
create_table :whales, :force => true do |t|
t.column :name, :string
end
create_table :little_whale_pupils, :force => true do |t|
t.column :whale_id, :integer
t.column :aquatic_pupil_id, :integer
t.column :aquatic_pupil_type, :string
end
create_table :keep_your_enemies_close, :force => true do |t|
t.column :enemy_id, :integer
t.column :enemy_type, :string
t.column :protector_id, :integer
t.column :protector_type, :string
end
end

View file

@ -1,23 +0,0 @@
require 'pathname'
# default test helper
begin
require File.dirname(__FILE__) + '/../../../../test/test_helper'
rescue LoadError
require '~/projects/miscellaneous/cookbook/test/test_helper'
end
Inflector.inflections {|i| i.irregular 'fish', 'fish' }
# fixtures
$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/")
# models
$LOAD_PATH.unshift("#{Pathname.new(__FILE__).dirname.to_s}/models")
class Test::Unit::TestCase
self.use_transactional_fixtures = true # must stay true for tests to run on postgres or sqlite3
self.use_instantiated_fixtures = false
end
# test schema
load(File.dirname(__FILE__) + "/schema.rb")

View file

@ -1,487 +0,0 @@
require File.dirname(__FILE__) + '/../test_helper'
class PolymorphTest < Test::Unit::TestCase
fixtures :cats, :bow_wows, :frogs, :wild_boars, :eaters_foodstuffs, :petfoods,
:"aquatic/fish", :"aquatic/whales", :"aquatic/little_whale_pupils",
:keep_your_enemies_close
require 'beautiful_fight_relationship'
# to-do: finder queries on the collection
# order-mask column on the join table for polymorphic order
# rework load order so you could push and pop without ever loading the whole collection
# so that limit works in a sane way
def setup
@kibbles = Petfood.find(1)
@bits = Petfood.find(2)
@shamu = Aquatic::Whale.find(1)
@swimmy = Aquatic::Fish.find(1)
@rover = Dog.find(1)
@spot = Dog.find(2)
@puma = WildBoar.find(1)
@chloe = Kitten.find(1)
@alice = Kitten.find(2)
@froggy = Frog.find(1)
@join_count = EatersFoodstuff.count
@l = @kibbles.eaters.length
@m = @bits.eaters.count
end
def test_all_relationship_validities
# q = []
# ObjectSpace.each_object(Class){|c| q << c if c.ancestors.include? ActiveRecord::Base }
# q.each{|c| puts "#{c.name}.reflect_on_all_associations.map &:check_validity! "}
Petfood.reflect_on_all_associations.map &:check_validity!
Tabby.reflect_on_all_associations.map &:check_validity!
Kitten.reflect_on_all_associations.map &:check_validity!
Dog.reflect_on_all_associations.map &:check_validity!
Aquatic::Fish.reflect_on_all_associations.map &:check_validity!
EatersFoodstuff.reflect_on_all_associations.map &:check_validity!
WildBoar.reflect_on_all_associations.map &:check_validity!
Frog.reflect_on_all_associations.map &:check_validity!
Aquatic::Whale.reflect_on_all_associations.map &:check_validity!
Cat.reflect_on_all_associations.map &:check_validity!
Aquatic::PupilsWhale.reflect_on_all_associations.map &:check_validity!
BeautifulFightRelationship.reflect_on_all_associations.map &:check_validity!
end
def test_assignment
assert @kibbles.eaters.blank?
assert @kibbles.eaters.push(Cat.find_by_name('Chloe'))
assert_equal @l += 1, @kibbles.eaters.count
@kibbles.reload
assert_equal @l, @kibbles.eaters.count
end
def test_duplicate_assignment
# try to add a duplicate item
@kibbles.eaters.push(@alice)
assert @kibbles.eaters.include?(@alice)
@kibbles.eaters.push(@alice)
assert_equal @l + 1, @kibbles.eaters.count
assert_equal @join_count + 1, EatersFoodstuff.count
@kibbles.reload
assert_equal @l + 1, @kibbles.eaters.count
assert_equal @join_count + 1, EatersFoodstuff.count
end
def test_create_and_push
assert @kibbles.eaters.push(@spot)
assert_equal @l += 1, @kibbles.eaters.count
assert @kibbles.eaters << @rover
assert @kibbles.eaters << Kitten.create(:name => "Miranda")
assert_equal @l += 2, @kibbles.eaters.length
@kibbles.reload
assert_equal @l, @kibbles.eaters.length
# test that ids and new flags were set appropriately
assert_not_nil @kibbles.eaters[0].id
assert !@kibbles.eaters[1].new_record?
end
def test_reload
assert @kibbles.reload
assert @kibbles.eaters.reload
end
def test_add_join_record
assert_equal Kitten, @chloe.class
assert @join_record = EatersFoodstuff.new(:foodstuff_id => @bits.id, :eater_id => @chloe.id, :eater_type => @chloe.class.name )
assert @join_record.save!
assert @join_record.id
assert_equal @join_count + 1, EatersFoodstuff.count
# has the parent changed if we don't reload?
assert_equal @m, @bits.eaters.count
# if we do reload, is the new association there?
# XXX no, because TestCase breaks reload. it works fine in the app.
assert_equal Petfood, @bits.eaters.reload.class
assert_equal @m + 1, @bits.eaters.count
assert @bits.eaters.include?(@chloe)
# puts "XXX #{EatersFoodstuff.count}"
end
def test_add_unsaved
# add an unsaved item
assert @bits.eaters << Kitten.new(:name => "Bridget")
assert_nil Kitten.find_by_name("Bridget")
assert_equal @m + 1, @bits.eaters.count
assert @bits.save
@bits.reload
assert_equal @m + 1, @bits.eaters.count
end
def test_self_reference
assert @kibbles.eaters << @bits
assert_equal @l += 1, @kibbles.eaters.count
assert @kibbles.eaters.include?(@bits)
@kibbles.reload
assert @kibbles.foodstuffs_of_eaters.blank?
@bits.reload
assert @bits.foodstuffs_of_eaters.include?(@kibbles)
assert_equal [@kibbles], @bits.foodstuffs_of_eaters
end
def test_remove
assert @kibbles.eaters << @chloe
@kibbles.reload
assert @kibbles.eaters.delete(@kibbles.eaters[0])
assert_equal @l, @kibbles.eaters.count
end
def test_destroy
assert @kibbles.eaters.push(@chloe)
@kibbles.reload
assert @kibbles.eaters.length > 0
assert @kibbles.eaters[0].destroy
@kibbles.reload
assert_equal @l, @kibbles.eaters.count
end
def test_clear
@kibbles.eaters << [@chloe, @spot, @rover]
@kibbles.reload
assert_equal 3, @kibbles.eaters.clear.size
assert @kibbles.eaters.blank?
@kibbles.reload
assert @kibbles.eaters.blank?
assert_equal 0, @kibbles.eaters.clear.size
end
def test_individual_collections
assert @kibbles.eaters.push(@chloe)
# check if individual collections work
assert_equal @kibbles.eater_kittens.length, 1
assert @kibbles.eater_dogs
assert 1, @rover.eaters_foodstuffs.count
end
def test_invididual_collections_push
assert_equal [@chloe], (@kibbles.eater_kittens << @chloe)
@kibbles.reload
assert @kibbles.eaters.include?(@chloe)
assert @kibbles.eater_kittens.include?(@chloe)
assert !@kibbles.eater_dogs.include?(@chloe)
end
def test_invididual_collections_delete
@kibbles.eaters << [@chloe, @spot, @rover]
@kibbles.reload
assert_equal [@chloe], @kibbles.eater_kittens.delete(@chloe)
assert @kibbles.eater_kittens.empty?
assert !@kibbles.eater_kittens.delete(@chloe)
@kibbles.reload
assert @kibbles.eater_kittens.empty?
assert @kibbles.eater_dogs.include?(@spot)
end
def test_invididual_collections_clear
@kibbles.eaters << [@chloe, @spot, @rover]
@kibbles.reload
assert_equal [@chloe], @kibbles.eater_kittens.clear
assert @kibbles.eater_kittens.empty?
assert_equal 2, @kibbles.eaters.size
@kibbles.reload
assert @kibbles.eater_kittens.empty?
assert_equal 2, @kibbles.eaters.size
assert !@kibbles.eater_kittens.include?(@chloe)
assert !@kibbles.eaters.include?(@chloe)
end
def test_childrens_individual_collections
assert Cat.find_by_name('Chloe').eaters_foodstuffs
assert @kibbles.eaters_foodstuffs
end
def test_self_referential_join_tables
# check that the self-reference join tables go the right ways
assert_equal @l, @kibbles.eaters_foodstuffs.count
assert_equal @kibbles.eaters_foodstuffs.count, @kibbles.eaters_foodstuffs_as_child.count
end
def test_dependent
assert @kibbles.eaters << @chloe
@kibbles.reload
# delete ourself and see if :dependent was obeyed
dependent_rows = @kibbles.eaters_foodstuffs
assert_equal dependent_rows.length, @kibbles.eaters.count
@join_count = EatersFoodstuff.count
@kibbles.destroy
assert_equal @join_count - dependent_rows.length, EatersFoodstuff.count
assert_equal 0, EatersFoodstuff.find(:all, :conditions => ['foodstuff_id = ?', 1] ).length
end
def test_normal_callbacks
assert @rover.respond_to?(:after_initialize)
assert @rover.respond_to?(:after_find)
assert @rover.after_initialize_test
assert @rover.after_find_test
end
def test_our_callbacks
assert 0, @bits.eaters.count
assert @bits.eaters.push(@rover)
@bits.save
# puts "Testing callbacks."
@bits2 = Petfood.find_by_name("Bits")
@bits.reload
assert rover = @bits2.eaters.select { |x| x.name == "Rover" }[0]
assert rover.after_initialize_test
assert rover.after_find_test
# puts "Done."
end
def test_number_of_join_records
assert EatersFoodstuff.create(:foodstuff_id => 1, :eater_id => 1, :eater_type => "Cat")
@join_count = EatersFoodstuff.count
assert @join_count > 0
end
def test_number_of_regular_records
dogs = Dog.count
assert Dog.new(:name => "Auggie").save!
assert dogs + 1, Dog.count
end
def test_attributes_come_through_when_child_has_underscore_in_table_name
@join_record = EatersFoodstuff.new(:foodstuff_id => @bits.id, :eater_id => @puma.id, :eater_type => @puma.class.name)
@join_record.save!
@bits.eaters.reload
assert_equal 'Puma', @puma.name
assert_equal 'Puma', @bits.eaters.first.name
end
def test_before_save_on_join_table_is_not_clobbered_by_sti_base_class_fix
assert @kibbles.eaters << @chloe
assert_equal 3, @kibbles.eaters_foodstuffs.first.some_attribute
end
def test_creating_namespaced_relationship
assert @shamu.aquatic_pupils.empty?
@shamu.aquatic_pupils << @swimmy
assert_equal 1, @shamu.aquatic_pupils.length
@shamu.reload
assert_equal 1, @shamu.aquatic_pupils.length
end
def test_namespaced_polymorphic_collection
@shamu.aquatic_pupils << @swimmy
assert @shamu.aquatic_pupils.include?(@swimmy)
@shamu.reload
assert @shamu.aquatic_pupils.include?(@swimmy)
@shamu.aquatic_pupils << @spot
assert @shamu.dogs.include?(@spot)
assert @shamu.aquatic_pupils.include?(@swimmy)
assert_equal @swimmy, @shamu.aquatic_fish.first
assert_equal 10, @shamu.aquatic_fish.first.speed
end
def test_deleting_namespaced_relationship
@shamu.aquatic_pupils << @swimmy
@shamu.aquatic_pupils << @spot
@shamu.reload
@shamu.aquatic_pupils.delete @spot
assert !@shamu.dogs.include?(@spot)
assert !@shamu.aquatic_pupils.include?(@spot)
assert_equal 1, @shamu.aquatic_pupils.length
end
def test_unrenamed_parent_of_namespaced_child
@shamu.aquatic_pupils << @swimmy
assert_equal [@shamu], @swimmy.whales
end
def test_empty_double_collections
assert @puma.enemies.empty?
assert @froggy.protectors.empty?
assert @alice.enemies.empty?
assert @spot.protectors.empty?
assert @alice.beautiful_fight_relationships_as_enemy.empty?
assert @alice.beautiful_fight_relationships_as_protector.empty?
assert @alice.beautiful_fight_relationships.empty?
end
def test_double_collection_assignment
@alice.enemies << @spot
@alice.reload
@spot.reload
assert @spot.protectors.include?(@alice)
assert @alice.enemies.include?(@spot)
assert !@alice.protectors.include?(@alice)
assert_equal 1, @alice.beautiful_fight_relationships_as_protector.size
assert_equal 0, @alice.beautiful_fight_relationships_as_enemy.size
assert_equal 1, @alice.beautiful_fight_relationships.size
# self reference
assert_equal 1, @alice.enemies.length
@alice.enemies.push @alice
assert @alice.enemies.include?(@alice)
assert_equal 2, @alice.enemies.length
@alice.reload
assert_equal 2, @alice.beautiful_fight_relationships_as_protector.size
assert_equal 1, @alice.beautiful_fight_relationships_as_enemy.size
assert_equal 3, @alice.beautiful_fight_relationships.size
end
def test_double_collection_deletion
@alice.enemies << @spot
@alice.reload
assert @alice.enemies.include?(@spot)
@alice.enemies.delete(@spot)
assert !@alice.enemies.include?(@spot)
assert @alice.enemies.empty?
@alice.reload
assert !@alice.enemies.include?(@spot)
assert @alice.enemies.empty?
assert_equal 0, @alice.beautiful_fight_relationships.size
end
def test_double_collection_deletion_from_opposite_side
@alice.protectors << @puma
@alice.reload
assert @alice.protectors.include?(@puma)
@alice.protectors.delete(@puma)
assert !@alice.protectors.include?(@puma)
assert @alice.protectors.empty?
@alice.reload
assert !@alice.protectors.include?(@puma)
assert @alice.protectors.empty?
assert_equal 0, @alice.beautiful_fight_relationships.size
end
def test_individual_collections_created_for_double_relationship
assert @alice.dogs.empty?
@alice.enemies << @spot
assert @alice.enemies.include?(@spot)
assert !@alice.kittens.include?(@alice)
assert !@alice.dogs.include?(@spot)
@alice.reload
assert @alice.dogs.include?(@spot)
assert !WildBoar.find(@alice.id).dogs.include?(@spot) # make sure the parent type is checked
end
def test_individual_collections_created_for_double_relationship_from_opposite_side
assert @alice.wild_boars.empty?
@alice.protectors << @puma
assert @alice.protectors.include?(@puma)
assert !@alice.wild_boars.include?(@puma)
@alice.reload
assert @alice.wild_boars.include?(@puma)
assert !Dog.find(@alice.id).wild_boars.include?(@puma) # make sure the parent type is checked
end
def test_self_referential_individual_collections_created_for_double_relationship
@alice.enemies << @alice
@alice.reload
assert @alice.enemy_kittens.include?(@alice)
assert @alice.protector_kittens.include?(@alice)
assert @alice.kittens.include?(@alice)
assert_equal 2, @alice.kittens.size
@alice.enemies << (@chloe = Kitten.find_by_name('Chloe'))
@alice.reload
assert @alice.enemy_kittens.include?(@chloe)
assert !@alice.protector_kittens.include?(@chloe)
assert @alice.kittens.include?(@chloe)
assert_equal 3, @alice.kittens.size
end
def test_child_of_polymorphic_join_can_reach_parent
@alice.enemies << @spot
@alice.reload
assert @spot.protectors.include?(@alice)
end
def test_double_collection_deletion_from_child_polymorphic_join
@alice.enemies << @spot
@spot.protectors.delete(@alice)
assert !@spot.protectors.include?(@alice)
@alice.reload
assert !@alice.enemies.include?(@spot)
BeautifulFightRelationship.create(:protector_id => 2, :protector_type => "Dog", :enemy_id => @spot.id, :enemy_type => @spot.class.name)
@alice.enemies << @spot
@spot.protectors.delete(@alice)
assert !@spot.protectors.include?(@alice)
end
def test_hmp_passed_block_manipulates_proxy_class
assert_equal "result", @shamu.aquatic_pupils.blow
assert_raises(NoMethodError) { @kibbles.eaters.blow }
end
def test_collection_query_on_unsaved_record
assert Dog.new.enemies.empty?
assert Dog.new.foodstuffs_of_eaters.empty?
end
def test_double_invididual_collections_push
assert_equal [@chloe], (@spot.protector_kittens << @chloe)
@spot.reload
assert @spot.protectors.include?(@chloe)
assert @spot.protector_kittens.include?(@chloe)
assert !@spot.protector_dogs.include?(@chloe)
assert_equal [@froggy], (@spot.frogs << @froggy)
@spot.reload
assert @spot.enemies.include?(@froggy)
assert @spot.frogs.include?(@froggy)
assert !@spot.enemy_dogs.include?(@froggy)
end
def test_double_invididual_collections_delete
@spot.protectors << [@chloe, @puma]
@spot.reload
assert_equal [@chloe], @spot.protector_kittens.delete(@chloe)
assert @spot.protector_kittens.empty?
assert !@spot.protector_kittens.delete(@chloe)
@spot.reload
assert @spot.protector_kittens.empty?
assert @spot.wild_boars.include?(@puma)
end
def test_double_invididual_collections_clear
@spot.protectors << [@chloe, @puma, @alice]
@spot.reload
assert_equal [@chloe, @alice], @spot.protector_kittens.clear.sort_by(&:id)
assert @spot.protector_kittens.empty?
assert_equal 1, @spot.protectors.size
@spot.reload
assert @spot.protector_kittens.empty?
assert_equal 1, @spot.protectors.size
assert !@spot.protector_kittens.include?(@chloe)
assert !@spot.protectors.include?(@chloe)
assert !@spot.protector_kittens.include?(@alice)
assert !@spot.protectors.include?(@alice)
end
end

View file

@ -1,35 +0,0 @@
MemoryTestFix
=============
A simple fix to run tests with sqlite. From example at
http://blog.seagul.co.uk/articles/2006/02/08/in-memory-sqlite-database-for-rails-testing
In your database.yml, use
test:
adapter: sqlite3
database: ":memory:"
It runs much faster!
You can also adjust the verbosity of the output:
test:
adapter: sqlite3
database: ":memory:"
verbosity: silent
== Authors
Chris Roos
Adapted by Geoffrey Grosenbach, http://nubyonrails.com
Verbosity patch by Kakutani Shintaro
== Changelog
* Updated to look for either so it works with Rails 1.2 and also older versions
* Updated to use ActiveRecord::ConnectionAdapters::SQLite3Adapter for Rails 1.2

View file

@ -1,22 +0,0 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
desc 'Test the memory_test_fix plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the memory_test_fix plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'MemoryTestFix'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View file

@ -1,7 +0,0 @@
author: Chris Roos
summary: Makes SQLite3 memory tests possible by preloading the schema.
homepage: http://blog.seagul.co.uk/articles/2006/02/08/in-memory-sqlite-database-for-rails-testing
plugin: http://topfunky.net/svn/plugins/memory_test_fix
license: MIT
version: 0.1
rails_version: 1.1+

View file

@ -1,2 +0,0 @@
require 'memory_test_fix'

View file

@ -1,42 +0,0 @@
# Update: Looks for the SQLite and SQLite3 adapters for
# compatibility with Rails 1.2.2 and also older versions.
def in_memory_database?
if ENV["RAILS_ENV"] == "test" and Rails::Configuration.new.database_configuration['test']['database'] == ':memory:'
begin
if ActiveRecord::Base.connection.class == ActiveRecord::ConnectionAdapters::SQLite3Adapter
return true
end
rescue NameError => e
if ActiveRecord::Base.connection.class == ActiveRecord::ConnectionAdapters::SQLiteAdapter
return true
end
end
end
false
end
def verbosity
Rails::Configuration.new.database_configuration['test']['verbosity']
end
def inform_using_in_memory
puts "Creating sqlite :memory: database"
end
if in_memory_database?
load_schema = lambda {
#load "#{RAILS_ROOT}/db/schema.rb" # use db agnostic schema by default
ActiveRecord::Migrator.up('db/migrate') # use migrations
}
case verbosity
when "silent"
silence_stream(STDOUT, &load_schema)
when "quiet"
inform_using_in_memory
silence_stream(STDOUT, &load_schema)
else
inform_using_in_memory
load_schema.call
end
end

View file

@ -0,0 +1,22 @@
OpenID Consumer
===============
Enable OpenID authentication and profile exchange from your application.
PRE-REQUISITES
--------------
* JanRain's Yadis and OpenID 1.2 libraries in Ruby.
* These can be obtained using 'gem install ruby-openid'
INSTALLATION
------------
To install you need to create a migration and add a controller.
./script/generate open_id_migration add_open_id_tables
./script/generate open_id_consumer_controller open_id
This can be used well in conjunction with a login system such as ActsAsAuthenticated

View file

@ -0,0 +1,39 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
desc 'Test the open_id_consumer plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the open_id_consumer plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'OpenIdConsumer'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View file

@ -0,0 +1,86 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
class OpenIdConsumerControllerGenerator < Rails::Generator::NamedBase
attr_reader :controller_name,
:controller_class_path,
:controller_file_path,
:controller_class_nesting,
:controller_class_nesting_depth,
:controller_class_name,
:controller_singular_name,
:controller_plural_name
alias_method :controller_file_name, :controller_singular_name
alias_method :controller_table_name, :controller_plural_name
def initialize(runtime_args, runtime_options = {})
runtime_args << 'open_id' if runtime_args.empty?
super
# Take controller name from the next argument. Default to the pluralized model name.
@controller_name = args.shift
@controller_name ||= ActiveRecord::Base.pluralize_table_names ? @name.pluralize : @name
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
@controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
if @controller_class_nesting.empty?
@controller_class_name = @controller_class_name_without_nesting
else
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
end
end
def manifest
record do |m|
# Check for class naming collisions.
m.class_collisions controller_class_path, "#{controller_class_name}Controller",
"#{controller_class_name}Helper"
# Controller, helper, views, and test directories.
m.directory File.join('app/controllers', controller_class_path)
m.directory File.join('app/helpers', controller_class_path)
m.directory File.join('app/views', controller_class_path, controller_file_name)
m.directory File.join('test/functional', controller_class_path)
m.template 'controller.rb',
File.join('app/controllers',
controller_class_path,
"#{controller_file_name}_controller.rb")
m.template 'functional_test.rb',
File.join('test/functional',
controller_class_path,
"#{controller_file_name}_controller_test.rb")
m.template 'helper.rb',
File.join('app/helpers',
controller_class_path,
"#{controller_file_name}_helper.rb")
# Controller templates
m.template "index.rhtml",
File.join('app/views', controller_class_path, controller_file_name, "index.rhtml")
end
end
protected
# Override with your own usage banner.
def banner
"Usage: #{$0} open_id_consumer_controller [open_id]"
end
end

View file

@ -0,0 +1,74 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
class <%= controller_class_name %>Controller < ApplicationController
open_id_consumer :required => [:email, :nickname], :optional => [:fullname, :dob, :gender, :country]
def index
@title = 'Welcome'
end
def begin
# If the URL was unusable (either because of network conditions,
# a server error, or that the response returned was not an OpenID
# identity page), the library will return HTTP_FAILURE or PARSE_ERROR.
# Let the user know that the URL is unusable.
case open_id_response.status
when OpenID::SUCCESS
# The URL was a valid identity URL. Now we just need to send a redirect
# to the server using the redirect_url the library created for us.
# redirect to the server
redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + '/'), url_for(:action => 'complete'))
else
flash[:error] = "Unable to find openid server for <q>#{params[:openid_url]}</q>"
render :action => :index
end
end
def complete
case open_id_response.status
when OpenID::FAILURE
# In the case of failure, if info is non-nil, it is the
# URL that we were verifying. We include it in the error
# message to help the user figure out what happened.
if open_id_response.identity_url
flash[:message] = "Verification of #{open_id_response.identity_url} failed. "
else
flash[:message] = "Verification failed. "
end
flash[:message] += open_id_response.msg.to_s
when OpenID::SUCCESS
# Success means that the transaction completed without
# error. If info is nil, it means that the user cancelled
# the verification.
flash[:message] = "You have successfully verified #{open_id_response.identity_url} as your identity."
if open_id_fields.any?
flash[:message] << "<hr /> With simple registration fields:<br/>"
open_id_fields.each {|k,v| flash[:message] << "<br /><b>#{k}</b>: #{v}"}
end
when OpenID::CANCEL
flash[:message] = "Verification cancelled."
else
flash[:message] = "Unknown response status: #{open_id_response.status}"
end
redirect_to :action => 'index'
end
end

View file

@ -0,0 +1,34 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
require File.dirname(__FILE__) + '/../test_helper'
require '<%= controller_file_name %>_controller'
# Re-raise errors caught by the controller.
class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase
def setup
@controller = <%= controller_class_name %>Controller.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_truth
assert true
end
end

View file

@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
module <%= controller_class_name %>Helper
end

View file

@ -0,0 +1,32 @@
<% # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
%>
<h1><%%= @title %></h1>
<div><strong><%%= flash[:message] %></strong></div>
<div><strong><%%= flash[:error] %></strong></div>
<p>Please login with your OpenID Identity URL</p>
<div id="verify-form">
<%%= start_form_tag :action => 'begin' %>
Identity URL:
<input type="text" name="openid_url" style="width: 200px" />
<input type="submit" value="Verify" />
</form>
</div>

View file

@ -0,0 +1,29 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
class OpenIdMigrationGenerator < Rails::Generator::NamedBase
def initialize(runtime_args, runtime_options = {})
runtime_args << 'add_open_id_tables' if runtime_args.empty?
super
end
def manifest
record do |m|
m.migration_template 'migration.rb', 'db/migrate'
end
end
end

View file

@ -0,0 +1,45 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
class <%= class_name %> < ActiveRecord::Migration
def self.up
create_table "open_id_associations", :force => true do |t|
t.column "server_url", :binary
t.column "handle", :string
t.column "secret", :binary
t.column "issued", :integer
t.column "lifetime", :integer
t.column "assoc_type", :string
end
create_table "open_id_nonces", :force => true do |t|
t.column "nonce", :string
t.column "created", :integer
end
create_table "open_id_settings", :force => true do |t|
t.column "setting", :string
t.column "value", :binary
end
end
def self.down
drop_table "open_id_associations"
drop_table "open_id_nonces"
drop_table "open_id_settings"
end
end

View file

@ -0,0 +1,23 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
class << ActionController::Base
def open_id_consumer(options = {})
include OpenIdConsumer::ControllerMethods
self.open_id_consumer_options = options
end
end

View file

@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
puts IO.read(File.join(File.dirname(__FILE__), 'README'))

View file

@ -0,0 +1,103 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
begin
require_gem "ruby-openid", ">= 1.0"
rescue LoadError
require "openid"
end
module OpenIdConsumer
class ActiveRecordOpenIdStore < OpenID::Store
def get_auth_key
setting = Setting.find_by_setting 'auth_key'
if setting.nil?
auth_key = OpenID::Util.random_string(20)
setting = Setting.create :setting => 'auth_key', :value => auth_key
end
setting.value
end
def store_association(server_url, assoc)
remove_association(server_url, assoc.handle)
Association.create(:server_url => server_url,
:handle => assoc.handle,
:secret => assoc.secret,
:issued => assoc.issued,
:lifetime => assoc.lifetime,
:assoc_type => assoc.assoc_type)
end
def get_association(server_url, handle=nil)
assocs = handle.blank? ?
Association.find_all_by_server_url(server_url) :
Association.find_all_by_server_url_and_handle(server_url, handle)
assocs.reverse.each do |assoc|
a = assoc.from_record
if a.expired?
assoc.destroy
else
return a
end
end if assocs.any?
return nil
end
def remove_association(server_url, handle)
assoc = Association.find_by_server_url_and_handle(server_url, handle)
unless assoc.nil?
assoc.destroy
return true
end
false
end
def store_nonce(nonce)
use_nonce(nonce)
Nonce.create :nonce => nonce, :created => Time.now.to_i
end
def use_nonce(nonce)
nonce = Nonce.find_by_nonce(nonce)
return false if nonce.nil?
age = Time.now.to_i - nonce.created
nonce.destroy
age < 6.hours # max nonce age of 6 hours
end
def dumb?
false
end
# not part of the api, but useful
def gc
now = Time.now.to_i
# remove old nonces
nonces = Nonce.find(:all)
nonces.each {|n| n.destroy if now - n.created > 6.hours} unless nonces.nil?
# remove expired assocs
assocs = Association.find(:all)
assocs.each { |a| a.destroy if a.from_record.expired? } unless assocs.nil?
end
end
end

View file

@ -0,0 +1,31 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
begin
require_gem "ruby-openid", ">= 1.0"
rescue LoadError
require "openid"
end
module OpenIdConsumer
class Association < ActiveRecord::Base
set_table_name 'open_id_associations'
def from_record
OpenID::Association.new(handle, secret, issued, lifetime, assoc_type)
end
end
end

View file

@ -0,0 +1,69 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
begin
require_gem "ruby-openid", ">= 1.0"
rescue LoadError
require "openid"
end
module OpenIdConsumer
module ControllerMethods
def self.included(controller)
controller.class_eval do
verify :method => :post, :only => :begin, :params => :openid_url, :redirect_to => { :action => 'index' },
:add_flash => { :error => "Enter an Identity URL to verify." }
verify :method => :get, :only => :complete, :redirect_to => { :action => 'index' }
before_filter :begin_open_id_auth, :only => :begin
before_filter :complete_open_id_auth, :only => :complete
attr_reader :open_id_response
attr_reader :open_id_fields
cattr_accessor :open_id_consumer_options
end
end
protected
def open_id_consumer
@open_id_consumer ||= OpenID::Consumer.new(
session[:openid_session] ||= {},
ActiveRecordOpenIdStore.new)
end
def begin_open_id_auth
@open_id_response = open_id_consumer.begin(params[:openid_url])
add_sreg_params!(@open_id_response) if @open_id_response.status == OpenID::SUCCESS
end
def complete_open_id_auth
@open_id_response = open_id_consumer.complete(params)
return unless open_id_response.status == OpenID::SUCCESS
@open_id_fields = open_id_response.extension_response('sreg')
logger.debug "***************** sreg params ***************"
logger.debug @open_id_fields.inspect
logger.debug "***************** sreg params ***************"
end
def add_sreg_params!(openid_response)
open_id_consumer_options.keys.inject({}) do |params, key|
value = open_id_consumer_options[key]
value = value.collect { |v| v.to_s.strip } * ',' if value.respond_to?(:collect)
openid_response.add_extension_arg('sreg', key.to_s, value.to_s)
end
end
end
end

View file

@ -0,0 +1,22 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
module OpenIdConsumer
class Nonce < ActiveRecord::Base
set_table_name 'open_id_nonces'
end
end

View file

@ -0,0 +1,22 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
module OpenIdConsumer
class Setting < ActiveRecord::Base
set_table_name 'open_id_settings'
end
end

View file

@ -1,7 +0,0 @@
ResourceFeeder
==============
Simple feeds for resources
NOTE: This plugin depends on the latest version of simply_helpful, available here:
http://dev.rubyonrails.org/svn/rails/plugins/simply_helpful/

View file

@ -1,22 +0,0 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
desc 'Test the resource_feed plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the resource_feed plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'ResourceFeed'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View file

@ -1,2 +0,0 @@
require 'resource_feeder'
ActionController::Base.send(:include, ResourceFeeder::Rss, ResourceFeeder::Atom)

View file

@ -1,2 +0,0 @@
require 'resource_feeder/rss'
require 'resource_feeder/atom'

View file

@ -1,78 +0,0 @@
module ResourceFeeder
module Atom
extend self
def render_atom_feed_for(resources, options = {})
render :text => atom_feed_for(resources, options), :content_type => Mime::ATOM
end
def atom_feed_for(resources, options = {})
xml = Builder::XmlMarkup.new(:indent => 2)
options[:feed] ||= {}
options[:item] ||= {}
options[:url_writer] ||= self
if options[:class] || resources.first
klass = options[:class] || resources.first.class
new_record = klass.new
else
options[:feed] = { :title => "Empty", :link => "http://example.com" }
end
options[:feed][:title] ||= klass.name.pluralize
options[:feed][:id] ||= "tag:#{request.host_with_port}:#{klass.name.pluralize}"
options[:feed][:link] ||= SimplyHelpful::RecordIdentifier.polymorphic_url(new_record, options[:url_writer])
options[:item][:title] ||= [ :title, :subject, :headline, :name ]
options[:item][:description] ||= [ :description, :body, :content ]
options[:item][:pub_date] ||= [ :updated_at, :updated_on, :created_at, :created_on ]
options[:item][:author] ||= [ :author, :creator ]
resource_link = lambda { |r| SimplyHelpful::RecordIdentifier.polymorphic_url(r, options[:url_writer]) }
xml.instruct!
xml.feed "xml:lang" => "en-US", "xmlns" => 'http://www.w3.org/2005/Atom' do
xml.title(options[:feed][:title])
xml.id(options[:feed][:id])
xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:feed][:link])
xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:feed][:self]) if options[:feed][:self]
xml.subtitle(options[:feed][:description]) if options[:feed][:description]
for resource in resources
published_at = call_or_read(options[:item][:pub_date], resource)
xml.entry do
xml.title(call_or_read(options[:item][:title], resource))
xml.content(call_or_read(options[:item][:description], resource), :type => 'html')
xml.id("tag:#{request.host_with_port},#{published_at.xmlschema}:#{call_or_read(options[:item][:guid] || options[:item][:link] || resource_link, resource)}")
xml.published(published_at.xmlschema)
xml.updated((resource.respond_to?(:updated_at) ? call_or_read(options[:item][:pub_date] || :updated_at, resource) : published_at).xmlschema)
xml.link(:rel => 'alternate', :type => 'text/html', :href => call_or_read(options[:item][:link] || options[:item][:guid] || resource_link, resource))
if author = call_or_read(options[:item][:author], resource)
xml.author do
xml.name()
end
end
end
end
end
end
private
def call_or_read(procedure_or_attributes, resource)
case procedure_or_attributes
when Array
attributes = procedure_or_attributes
resource.send(attributes.select { |a| resource.respond_to?(a) }.first)
when Symbol
attribute = procedure_or_attributes
resource.send(attribute)
when Proc
procedure = procedure_or_attributes
procedure.call(resource)
end
end
end
end

View file

@ -1,79 +0,0 @@
module ResourceFeeder
module Rss
extend self
def render_rss_feed_for(resources, options = {})
render :text => rss_feed_for(resources, options), :content_type => Mime::RSS
end
def rss_feed_for(resources, options = {})
xml = Builder::XmlMarkup.new(:indent => 2)
options[:feed] ||= {}
options[:item] ||= {}
options[:url_writer] ||= self
if options[:class] || resources.first
klass = options[:class] || resources.first.class
new_record = klass.new
else
options[:feed] = { :title => "Empty", :link => "http://example.com" }
end
use_content_encoded = options[:item].has_key?(:content_encoded)
options[:feed][:title] ||= klass.name.pluralize
options[:feed][:link] ||= SimplyHelpful::RecordIdentifier.polymorphic_url(new_record, options[:url_writer])
options[:feed][:language] ||= "en-us"
options[:feed][:ttl] ||= "40"
options[:item][:title] ||= [ :title, :subject, :headline, :name ]
options[:item][:description] ||= [ :description, :body, :content ]
options[:item][:pub_date] ||= [ :updated_at, :updated_on, :created_at, :created_on ]
resource_link = lambda { |r| SimplyHelpful::RecordIdentifier.polymorphic_url(r, options[:url_writer]) }
rss_root_attributes = { :version => 2.0 }
rss_root_attributes.merge!("xmlns:content" => "http://purl.org/rss/1.0/modules/content/") if use_content_encoded
xml.instruct!
xml.rss(rss_root_attributes) do
xml.channel do
xml.title(options[:feed][:title])
xml.link(options[:feed][:link])
xml.description(options[:feed][:description]) if options[:feed][:description]
xml.language(options[:feed][:language])
xml.ttl(options[:feed][:ttl])
for resource in resources
xml.item do
xml.title(call_or_read(options[:item][:title], resource))
xml.description(call_or_read(options[:item][:description], resource))
if use_content_encoded then
xml.content(:encoded) { xml.cdata!(call_or_read(options[:item][:content_encoded], resource)) }
end
xml.pubDate(call_or_read(options[:item][:pub_date], resource).to_s(:rfc822))
xml.guid(call_or_read(options[:item][:guid] || options[:item][:link] || resource_link, resource))
xml.link(call_or_read(options[:item][:link] || options[:item][:guid] || resource_link, resource))
end
end
end
end
end
private
def call_or_read(procedure_or_attributes, resource)
case procedure_or_attributes
when Array
attributes = procedure_or_attributes
resource.send(attributes.select { |a| resource.respond_to?(a) }.first)
when Symbol
attribute = procedure_or_attributes
resource.send(attribute)
when Proc
procedure = procedure_or_attributes
procedure.call(resource)
end
end
end
end

View file

@ -1,85 +0,0 @@
require File.dirname(__FILE__) + '/test_helper'
class AtomFeedTest < Test::Unit::TestCase
attr_reader :request
def setup
@request = OpenStruct.new
@request.host_with_port = 'example.com'
@records = Array.new(5).fill(Post.new)
@records.each &:save
end
def test_default_atom_feed
atom_feed_for @records
assert_select 'feed' do
assert_select '>title', 'Posts'
assert_select '>id', "tag:#{request.host_with_port}:Posts"
assert_select '>link' do
assert_select "[rel='alternate']"
assert_select "[type='text/html']"
assert_select "[href='http://example.com/posts']"
end
assert_select 'entry', 5 do
assert_select 'title', :text => 'feed title (title)'
assert_select "content[type='html']", '&lt;p&gt;feed description (description)&lt;/p&gt;'
assert_select 'id', "tag:#{request.host_with_port},#{@records.first.created_at.xmlschema}:#{'http://example.com/posts/1'}"
assert_select 'published', @records.first.created_at.xmlschema
assert_select 'updated', @records.first.created_at.xmlschema
assert_select 'link' do
assert_select "[rel='alternate']"
assert_select "[type='text/html']"
assert_select "[href='http://example.com/posts/1']"
end
end
end
end
def test_should_allow_custom_feed_options
atom_feed_for @records, :feed => { :title => 'Custom Posts', :link => '/posts', :description => 'stuff', :self => '/posts.atom' }
assert_select 'feed>title', 'Custom Posts'
assert_select "feed>link[href='/posts']"
assert_select 'feed>subtitle', 'stuff'
assert_select 'feed>link' do
assert_select "[rel='self']"
assert_select "[type='application/atom+xml']"
assert_select "[href='/posts.atom']"
end
end
def test_should_allow_custom_item_attributes
atom_feed_for @records, :item => { :title => :name, :description => :body, :pub_date => :create_date, :link => :id }
assert_select 'entry', 5 do
assert_select 'title', :text => 'feed title (name)'
assert_select "content[type='html']", '&lt;p&gt;feed description (body)&lt;/p&gt;'
assert_select 'published', (@records.first.created_at - 5.minutes).xmlschema
assert_select 'updated', (@records.first.created_at - 5.minutes).xmlschema
assert_select 'id', "tag:#{request.host_with_port},#{(@records.first.created_at - 5.minutes).xmlschema}:1"
assert_select 'link' do
assert_select "[rel='alternate']"
assert_select "[type='text/html']"
assert_select "[href='1']"
end
end
end
def test_should_allow_custom_item_attribute_blocks
atom_feed_for @records, :item => { :title => lambda { |r| r.name }, :description => lambda { |r| r.body }, :pub_date => lambda { |r| r.create_date },
:link => lambda { |r| "/#{r.created_at.to_i}" }, :guid => lambda { |r| r.created_at.to_i } }
assert_select 'entry', 5 do
assert_select 'title', :text => 'feed title (name)'
assert_select "content[type='html']", '&lt;p&gt;feed description (body)&lt;/p&gt;'
assert_select 'published', (@records.first.created_at - 5.minutes).xmlschema
assert_select 'updated', (@records.first.created_at - 5.minutes).xmlschema
assert_select 'id', /:\d+$/
assert_select 'link' do
assert_select "[rel='alternate']"
assert_select "[type='text/html']"
assert_select "[href=?]", /^\/\d+$/
end
end
end
end

View file

@ -1,86 +0,0 @@
require File.dirname(__FILE__) + '/test_helper'
class RssFeedTest < Test::Unit::TestCase
def setup
@records = Array.new(5).fill(Post.new)
@records.each &:save
end
def test_default_rss_feed
rss_feed_for @records
assert_select 'rss[version="2.0"]' do
assert_select 'channel' do
assert_select '>title', 'Posts'
assert_select '>link', 'http://example.com/posts'
assert_select 'language', 'en-us'
assert_select 'ttl', '40'
end
assert_select 'item', 5 do
assert_select 'title', :text => 'feed title (title)'
assert_select 'description', '&lt;p&gt;feed description (description)&lt;/p&gt;'
%w(guid link).each do |node|
assert_select node, 'http://example.com/posts/1'
end
assert_select 'pubDate', @records.first.created_at.to_s(:rfc822)
end
end
end
def test_should_allow_custom_feed_options
rss_feed_for @records, :feed => { :title => 'Custom Posts', :link => '/posts', :description => 'stuff', :language => 'en-gb', :ttl => '80' }
assert_select 'channel>title', 'Custom Posts'
assert_select 'channel>link', '/posts'
assert_select 'channel>description', 'stuff'
assert_select 'channel>language', 'en-gb'
assert_select 'channel>ttl', '80'
end
def test_should_allow_custom_item_attributes
rss_feed_for @records, :item => { :title => :name, :description => :body, :pub_date => :create_date, :link => :id }
assert_select 'item', 5 do
assert_select 'title', :text => 'feed title (name)'
assert_select 'description', '&lt;p&gt;feed description (body)&lt;/p&gt;'
assert_select 'pubDate', (@records.first.created_at - 5.minutes).to_s(:rfc822)
assert_select 'link', '1'
assert_select 'guid', '1'
end
end
def test_should_allow_custom_item_attribute_blocks
rss_feed_for @records, :item => { :title => lambda { |r| r.name }, :description => lambda { |r| r.body }, :pub_date => lambda { |r| r.create_date },
:link => lambda { |r| "/#{r.created_at.to_i}" }, :guid => lambda { |r| r.created_at.to_i } }
assert_select 'item', 5 do
assert_select 'title', :text => 'feed title (name)'
assert_select 'description', '&lt;p&gt;feed description (body)&lt;/p&gt;'
assert_select 'pubDate', (@records.first.created_at - 5.minutes).to_s(:rfc822)
end
end
# note that assert_select isnt easily able to get elements that have xml namespaces (as it thinks they are
# invalid html psuedo children), so we do some manual testing with the response body
def test_should_allow_content_encoded_for_items
rss_feed_for @records, :item => { :content_encoded => :full_html_body }
html_content = "<strong>Here is some <i>full</i> content, with out any excerpts</strong>"
assert_equal 5, @response.body.scan("<![CDATA[#{html_content}]]>").size
assert_select 'item', 5 do
assert_select 'description + *', "<![CDATA[#{html_content}" # assert_select seems to strip the ending cdata tag
end
end
def test_should_have_content_encoded_namespace_if_used
rss_feed_for @records, :item => { :content_encoded => :full_html_body }
assert_equal %[<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">\n],
@response.body.grep(/<rss version="2\.0.*"/).first
end
def test_should_have_normal_rss_root_without_content_encoded
rss_feed_for @records
assert_equal %[<rss version="2.0">\n],
@response.body.grep(/<rss version="2\.0.*"/).first
end
end

View file

@ -1,64 +0,0 @@
RAILS_ENV = 'test'
require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
require 'action_controller/test_process'
require 'breakpoint'
require 'ostruct'
class Post
attr_reader :id, :created_at
def save; @id = 1; @created_at = Time.now.utc end
def new_record?; @id.nil? end
[:title, :name].each do |attr_name|
define_method attr_name do
"feed title (#{attr_name})"
end
end
[:description, :body].each do |attr_name|
define_method attr_name do
"<p>feed description (#{attr_name})</p>"
end
end
def full_html_body
"<strong>Here is some <i>full</i> content, with out any excerpts</strong>"
end
def create_date
@created_at - 5.minutes
end
end
class Test::Unit::TestCase
include ResourceFeeder::Rss, ResourceFeeder::Atom
def render_feed(xml)
@response = OpenStruct.new
@response.headers = {'Content-Type' => 'text/xml'}
@response.body = xml
end
def rss_feed_for_with_ostruct(resources, options = {})
render_feed rss_feed_for_without_ostruct(resources, options)
end
def atom_feed_for_with_ostruct(resources, options = {})
render_feed atom_feed_for_without_ostruct(resources, options)
end
alias_method_chain :rss_feed_for, :ostruct
alias_method_chain :atom_feed_for, :ostruct
def html_document
@html_document ||= HTML::Document.new(@response.body, false, true)
end
def posts_url
"http://example.com/posts"
end
def post_url(post)
"http://example.com/posts/#{post.id}"
end
end

View file

@ -1,192 +0,0 @@
= Selenium on Rails
== Overview
Selenium on Rails provides an easy way to test Rails application with
SeleniumCore[http://www.openqa.org/selenium-core/].
This plugin does four things:
1. The Selenium Core files don't have to pollute <tt>/public</tt>, they can stay in the Selenium gem or in <tt>/vendor/selenium</tt>.
2. No need to create suite files, they are generated on the fly -- one suite per directory in <tt>/test/selenium</tt> (suites can be nested).
3. Instead of writing the test cases in HTML you can use a number of better formats (see <tt>Formats</tt>).
4. Loading of fixtures and wiping of session (<tt>/selenium/setup</tt>).
== Installation
1. Selenium Core needs to be available. It could either be installed as a gem (<tt>gem install selenium</tt>) or in <tt>/vendor/selenium/</tt>.
2. Install Selenium on Rails: <tt>script/plugin install http://svn.openqa.org/svn/selenium-on-rails/selenium-on-rails</tt>
3. <i>If RedCloth is available the Selenese test cases can use it for better markup.</i>
4. Run the Rakefile in the plugin's directory to run the tests in order to see that everything works. (If RedCloth isn't installed a few tests will fail since they assume RedCloth is installed.)
5. Create a test case: <tt>script/generate selenium login</tt>
6. Start the server: <tt>script/server -e test</tt>
7. Point your browser to <tt>http://localhost:3000/selenium</tt>
8. If everything works as expected you should see the Selenium test runner. The north east frame contains all your test cases (just one for now), and the north frame contains your test case.
=== win32-open3
win32-open3[http://raa.ruby-lang.org/project/win32-open3/] is needed if you're
on Windows and want to run your tests as a Rake task
(see <tt>test:acceptance</tt>), i.e. you don't have to install it but it's
recommended.
You can build it from source or install the binary:
1. Download the latest version of win32-open3, open3-0.2.2.so[http://rubyforge.org/frs/download.php/8515/open3-0.2.2.so] at the time of this writing.
2. Open up irb and run this snippet: <tt>require 'rbconfig'; include Config; puts CONFIG['sitearchdir']</tt>
3. Create a <tt>win32</tt> directory under the directory you got, e.g. <tt>c:\ruby\lib\ruby\site_ruby\1.8\i386-msvcrt</tt>
4. Rename the .so file to <tt>open3.so</tt> and put it in the <tt>win32</tt> directory.
5. Profit! (unless you get an error when doing <tt>require 'win32/open3'</tt>)
== Formats
The test cases can be written in a number of formats. Which one you choose is a
matter of taste. You can generate your test files by running
<tt>script/generate selenium</tt> or by creating them manually in your
<tt>/test/selenium</tt> directory.
=== Selenese, .sel
Selenese is the dumbest format (in a good way). You just write your commands
delimited by | characters.
|open|/selenium/setup|
|open|/|
|goBack|
If you don't want to write Selenese tests by hand you can use
SeleniumIDE[http://www.openqa.org/selenium-ide/] which has
support[http://wiki.openqa.org/display/SIDE/SeleniumOnRails] for Selenese.
SeleniumIDE makes it super easy to record test and edit them.
=== RSelenese, .rsel
RSelenese enable you to write your tests in Ruby.
setup :fixtures => :all
open '/'
assert_title 'Home'
('a'..'z').each {|c| open :controller => 'user', :action => 'create', :name => c }
See SeleniumOnRails::TestBuilder for available commands.
=== HTML/RHTML
You can write your tests in HTML/RHTML but that's mostly useful if you have
existing tests you want to reuse.
=== Partial test cases
If you have some common actions you want to do in several test cases you can put
them in a separate partial test case and include them in your other test cases.
A partial test case is just like a normal test case besides that its filename
has to start with _:
#_login.rsel
open '/login'
type 'name', name
type 'password', password
click 'submit', :wait=>true
To include a partial test case you write like this in a Selenese test case:
|includePartial|login|name=John Doe|password=eoD nhoJ|
in a RSelenese test case:
include_partial 'login', :name => 'Jane Doe', :password => 'Jane Doe'.reverse
and in a RHTML test case:
<%= render :partial => 'login', :locals => {:name = 'Joe Schmo', :password => 'Joe Schmo'.reverse} %>
== Configuration
There are a number of settings available. You make them by renaming
<tt>config.yml.example</tt> to <tt>config.yml</tt> and make your changes in that
file.
=== Environments
Per default this plugin is only available in test environment. You can change
this by setting <tt>environments</tt>, such as:
#config.yml
environments:
- test
- development
== <tt>test:acceptance</tt>
You can run all your Selenium tests as a Rake task.
First, if you're on Windows, you have to make sure win32-open3 is installed.
Then you have to configure which browsers you want to run, like this:
#config.yml
browsers:
firefox: 'c:\Program Files\Mozilla Firefox\firefox.exe'
ie: 'c:\Program Files\Internet Explorer\iexplore.exe'
Now you're all set. First start a server:
script/server -e test
Then run the tests:
rake test:acceptance
Now it should work, otherwise let me know!
=== Store results
If you want to store the results from a <tt>test:acceptance</tt> you just need
to set in which directory they should be stored:
#config.yml
result_dir: 'c:\result'
So when you run <tt>rake test:acceptance</tt> the tables with the results will
be stored as <tt>.html</tt> files in that directory.
This can be useful especially for continous integration.
== Todo
=== Standalone mode
More work is needed on <tt>test:acceptance</tt> on Windows to be able to start
the server when needed.
=== user_extension.js
Selenium has support for <tt>user_extension.js</tt> which is a way to extend the
functionality of Selenium Core. However there is currently no easy way to add
such a file in Selenium on Rails.
=== More setup/teardown support?
Currently there is only support to load fixtures and to wipe the session in
<tt>/selenium/setup</tt>. Is there a need for more kinds of setups or teardowns?
=== More documentation
== Not todo
=== Editor
Creating an editor for the test cases is currently considered out of scope for
this plugin. SeleniumIDE[http://www.openqa.org/selenium-ide/] does such a good
job and has support[http://wiki.openqa.org/display/SIDE/SeleniumOnRails] for
the Selenese format.
== Credits
* Jon Tirsen, http://jutopia.tirsen.com -- initial inspiration[http://wiki.rubyonrails.com/rails/pages/SeleniumIntegration]
* Eric Kidd, http://www.randomhacks.net -- contribution of RSelenese
== Information
For more information, check out the website[http://www.openqa.org/selenium-on-rails/].

View file

@ -1,27 +0,0 @@
require 'rake'
require 'rake/testtask'
require 'rdoc/rdoc'
desc 'Default: run unit tests.'
task :default => :test
desc 'Test the Selenium on Rails plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the Selenium on Rails plugin.'
task :rdoc do
rm_rf 'doc'
RDoc::RDoc.new.document(%w(--line-numbers --inline-source --title SeleniumOnRails README lib))
end
begin
require 'rcov/rcovtask'
Rcov::RcovTask.new do |t|
t.test_files = FileList['test/*_test.rb']
end
rescue LoadError #if rcov isn't available, ignore
end

View file

@ -1,27 +0,0 @@
# Rename this file to config.yml in order to configure the plugin
#
# General settings
#
environments:
- test
# - development # Uncomment this line to enable in development environment. N.B. your development database will likely be altered/destroyed/abducted
#selenium_path: 'c:\selenium' #path to selenium installation. only needed when selenium isn't installed in /vendor/selenium or as a gem
#
# rake test:acceptance settings
#
browsers:
firefox: 'c:\Program Files\Mozilla Firefox\firefox.exe'
ie: 'c:\Program Files\Internet Explorer\iexplore.exe'
#host: 'localhost'
#port_start: 3000
#port_end: 3005
#max_browser_duration: 120
#multi_window: false
#result_dir: 'c:\result' # the directory where the results will be stored after a test:acceptance run

View file

@ -1,27 +0,0 @@
# Rename this file to config.yml in order to configure the plugin
#
# General settings
#
environments:
- test
# - development # Uncomment this line to enable in development environment. N.B. your development database will likely be altered/destroyed/abducted
#selenium_path: 'c:\selenium' #path to selenium installation. only needed when selenium isn't installed in /vendor/selenium or as a gem
#
# rake test:acceptance settings
#
browsers:
firefox: 'c:\Program Files\Mozilla Firefox\firefox.exe'
ie: 'c:\Program Files\Internet Explorer\iexplore.exe'
#host: 'localhost'
#port_start: 3000
#port_end: 3005
#max_browser_duration: 120
#multi_window: false
#result_dir: 'c:\result' # the directory where the results will be stored after a test:acceptance run

View file

@ -1,265 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Class: SeleniumController</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Class</strong></td>
<td class="class-name-in-header">SeleniumController</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../files/lib/controllers/selenium_controller_rb.html">
lib/controllers/selenium_controller.rb
</a>
<br />
</td>
</tr>
<tr class="top-aligned-row">
<td><strong>Parent:</strong></td>
<td>
ActionController::Base
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000006">record</a>&nbsp;&nbsp;
<a href="#M000003">setup</a>&nbsp;&nbsp;
<a href="#M000005">support_file</a>&nbsp;&nbsp;
<a href="#M000004">test_file</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="includes">
<h3 class="section-bar">Included Modules</h3>
<div id="includes-list">
<span class="include-name"><a href="SeleniumOnRails/FixtureLoader.html">SeleniumOnRails::FixtureLoader</a></span>
<span class="include-name"><a href="SeleniumOnRails/Renderer.html">SeleniumOnRails::Renderer</a></span>
</div>
</div>
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000006" class="method-detail">
<a name="M000006"></a>
<div class="method-heading">
<a href="#M000006" class="method-signature">
<span class="method-name">record</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000006-source">
<pre>
<span class="ruby-comment cmt"># File lib/controllers/selenium_controller.rb, line 50</span>
50: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">record</span>
51: <span class="ruby-identifier">dir</span> = <span class="ruby-identifier">record_table</span>
52:
53: <span class="ruby-ivar">@result</span> = {<span class="ruby-value str">'resultDir'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">dir</span>}
54: <span class="ruby-keyword kw">for</span> <span class="ruby-identifier">p</span> <span class="ruby-keyword kw">in</span> [<span class="ruby-value str">'result'</span>, <span class="ruby-value str">'numTestFailures'</span>, <span class="ruby-value str">'numTestPasses'</span>, <span class="ruby-value str">'numCommandFailures'</span>, <span class="ruby-value str">'numCommandPasses'</span>, <span class="ruby-value str">'numCommandErrors'</span>, <span class="ruby-value str">'totalTime'</span>]
55: <span class="ruby-ivar">@result</span>[<span class="ruby-identifier">p</span>] = <span class="ruby-identifier">params</span>[<span class="ruby-identifier">p</span>]
56: <span class="ruby-keyword kw">end</span>
57: <span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-identifier">log_path</span>(<span class="ruby-identifier">params</span>[<span class="ruby-identifier">:logFile</span>] <span class="ruby-operator">||</span> <span class="ruby-value str">'default.yml'</span>), <span class="ruby-value str">'w'</span>) {<span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span> <span class="ruby-constant">YAML</span>.<span class="ruby-identifier">dump</span>(<span class="ruby-ivar">@result</span>, <span class="ruby-identifier">f</span>)}
58:
59: <span class="ruby-identifier">render</span> <span class="ruby-identifier">:file</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">view_path</span>(<span class="ruby-value str">'record.rhtml'</span>), <span class="ruby-identifier">:layout</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">layout_path</span>
60: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000003" class="method-detail">
<a name="M000003"></a>
<div class="method-heading">
<a href="#M000003" class="method-signature">
<span class="method-name">setup</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000003-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000003-source">
<pre>
<span class="ruby-comment cmt"># File lib/controllers/selenium_controller.rb, line 7</span>
7: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">setup</span>
8: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">params</span>.<span class="ruby-identifier">has_key?</span> <span class="ruby-identifier">:keep_session</span>
9: <span class="ruby-identifier">reset_session</span>
10: <span class="ruby-ivar">@session_wiped</span> = <span class="ruby-keyword kw">true</span>
11: <span class="ruby-keyword kw">end</span>
12: <span class="ruby-ivar">@cleared_tables</span> = <span class="ruby-identifier">clear_tables</span> <span class="ruby-identifier">params</span>[<span class="ruby-identifier">:clear_tables</span>].<span class="ruby-identifier">to_s</span>
13: <span class="ruby-ivar">@loaded_fixtures</span> = <span class="ruby-identifier">load_fixtures</span> <span class="ruby-identifier">params</span>[<span class="ruby-identifier">:fixtures</span>].<span class="ruby-identifier">to_s</span>
14: <span class="ruby-identifier">render</span> <span class="ruby-identifier">:file</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">view_path</span>(<span class="ruby-value str">'setup.rhtml'</span>), <span class="ruby-identifier">:layout</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">layout_path</span>
15: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000005" class="method-detail">
<a name="M000005"></a>
<div class="method-heading">
<a href="#M000005" class="method-signature">
<span class="method-name">support_file</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000005-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000005-source">
<pre>
<span class="ruby-comment cmt"># File lib/controllers/selenium_controller.rb, line 34</span>
34: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">support_file</span>
35: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">params</span>[<span class="ruby-identifier">:filename</span>].<span class="ruby-identifier">empty?</span>
36: <span class="ruby-identifier">redirect_to</span> <span class="ruby-identifier">:filename</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">'TestRunner.html'</span>, <span class="ruby-identifier">:test</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">'tests'</span>
37: <span class="ruby-keyword kw">return</span>
38: <span class="ruby-keyword kw">end</span>
39:
40: <span class="ruby-identifier">filename</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span> <span class="ruby-identifier">selenium_path</span>, <span class="ruby-identifier">params</span>[<span class="ruby-identifier">:filename</span>]
41: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">file?</span> <span class="ruby-identifier">filename</span>
42: <span class="ruby-identifier">type</span> = <span class="ruby-constant">WEBrick</span><span class="ruby-operator">::</span><span class="ruby-constant">HTTPUtils</span><span class="ruby-operator">::</span><span class="ruby-constant">DefaultMimeTypes</span>[<span class="ruby-identifier">$1</span>.<span class="ruby-identifier">downcase</span>] <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">filename</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/\.(\w+)$/</span>
43: <span class="ruby-identifier">type</span> <span class="ruby-operator">||=</span> <span class="ruby-value str">'text/html'</span>
44: <span class="ruby-identifier">send_file</span> <span class="ruby-identifier">filename</span>, <span class="ruby-identifier">:type</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">type</span>, <span class="ruby-identifier">:disposition</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">'inline'</span>, <span class="ruby-identifier">:stream</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-keyword kw">false</span>
45: <span class="ruby-keyword kw">else</span>
46: <span class="ruby-identifier">render</span> <span class="ruby-identifier">:text</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">'Not found'</span>, <span class="ruby-identifier">:status</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value">404</span>
47: <span class="ruby-keyword kw">end</span>
48: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000004" class="method-detail">
<a name="M000004"></a>
<div class="method-heading">
<a href="#M000004" class="method-signature">
<span class="method-name">test_file</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000004-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000004-source">
<pre>
<span class="ruby-comment cmt"># File lib/controllers/selenium_controller.rb, line 17</span>
17: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">test_file</span>
18: <span class="ruby-identifier">params</span>[<span class="ruby-identifier">:testname</span>] = <span class="ruby-value str">''</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">params</span>[<span class="ruby-identifier">:testname</span>].<span class="ruby-identifier">to_s</span> <span class="ruby-operator">==</span> <span class="ruby-value str">'TestSuite.html'</span>
19: <span class="ruby-identifier">filename</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span> <span class="ruby-identifier">selenium_tests_path</span>, <span class="ruby-identifier">params</span>[<span class="ruby-identifier">:testname</span>]
20: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">directory?</span> <span class="ruby-identifier">filename</span>
21: <span class="ruby-ivar">@suite_path</span> = <span class="ruby-identifier">filename</span>
22: <span class="ruby-identifier">render</span> <span class="ruby-identifier">:file</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">view_path</span>(<span class="ruby-value str">'test_suite.rhtml'</span>), <span class="ruby-identifier">:layout</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">layout_path</span>
23: <span class="ruby-keyword kw">elsif</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">readable?</span> <span class="ruby-identifier">filename</span>
24: <span class="ruby-identifier">render_test_case</span> <span class="ruby-identifier">filename</span>
25: <span class="ruby-keyword kw">else</span>
26: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">directory?</span> <span class="ruby-identifier">selenium_tests_path</span>
27: <span class="ruby-identifier">render</span> <span class="ruby-identifier">:text</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">'Not found'</span>, <span class="ruby-identifier">:status</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value">404</span>
28: <span class="ruby-keyword kw">else</span>
29: <span class="ruby-identifier">render</span> <span class="ruby-identifier">:text</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-node">&quot;Did not find the Selenium tests path (#{selenium_tests_path}). Run script/generate selenium&quot;</span>, <span class="ruby-identifier">:status</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value">404</span>
30: <span class="ruby-keyword kw">end</span>
31: <span class="ruby-keyword kw">end</span>
32: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,148 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Module: SeleniumHelper</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Module</strong></td>
<td class="class-name-in-header">SeleniumHelper</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../files/lib/selenium_helper_rb.html">
lib/selenium_helper.rb
</a>
<br />
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000008">test_case_name</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="includes">
<h3 class="section-bar">Included Modules</h3>
<div id="includes-list">
<span class="include-name"><a href="SeleniumOnRails/SuiteRenderer.html">SeleniumOnRails::SuiteRenderer</a></span>
<span class="include-name"><a href="SeleniumOnRails/FixtureLoader.html">SeleniumOnRails::FixtureLoader</a></span>
</div>
</div>
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000008" class="method-detail">
<a name="M000008"></a>
<div class="method-heading">
<a href="#M000008" class="method-signature">
<span class="method-name">test_case_name</span><span class="method-args">(filename)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000008-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000008-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_helper.rb, line 5</span>
5: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">test_case_name</span> <span class="ruby-identifier">filename</span>
6: <span class="ruby-constant">File</span>.<span class="ruby-identifier">basename</span>(<span class="ruby-identifier">filename</span>).<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/\..*/</span>,<span class="ruby-value str">''</span>).<span class="ruby-identifier">humanize</span>
7: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,124 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Module: SeleniumOnRails</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Module</strong></td>
<td class="class-name-in-header">SeleniumOnRails</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../files/lib/selenium_on_rails/paths_rb.html">
lib/selenium_on_rails/paths.rb
</a>
<br />
<a href="../files/lib/selenium_on_rails_rb.html">
lib/selenium_on_rails.rb
</a>
<br />
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
</div>
<!-- if includes -->
<div id="section">
<div id="class-list">
<h3 class="section-bar">Classes and Modules</h3>
Module <a href="SeleniumOnRails/FixtureLoader.html" class="link">SeleniumOnRails::FixtureLoader</a><br />
Module <a href="SeleniumOnRails/PartialsSupport.html" class="link">SeleniumOnRails::PartialsSupport</a><br />
Module <a href="SeleniumOnRails/Paths.html" class="link">SeleniumOnRails::Paths</a><br />
Module <a href="SeleniumOnRails/Renderer.html" class="link">SeleniumOnRails::Renderer</a><br />
Module <a href="SeleniumOnRails/SuiteRenderer.html" class="link">SeleniumOnRails::SuiteRenderer</a><br />
Module <a href="SeleniumOnRails/TestBuilderAccessors.html" class="link">SeleniumOnRails::TestBuilderAccessors</a><br />
Module <a href="SeleniumOnRails/TestBuilderActions.html" class="link">SeleniumOnRails::TestBuilderActions</a><br />
Class <a href="SeleniumOnRails/RSelenese.html" class="link">SeleniumOnRails::RSelenese</a><br />
Class <a href="SeleniumOnRails/Selenese.html" class="link">SeleniumOnRails::Selenese</a><br />
Class <a href="SeleniumOnRails/TestBuilder.html" class="link">SeleniumOnRails::TestBuilder</a><br />
</div>
<!-- if method_list -->
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,231 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Module: SeleniumOnRails::FixtureLoader</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Module</strong></td>
<td class="class-name-in-header">SeleniumOnRails::FixtureLoader</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../../files/lib/selenium_on_rails/fixture_loader_rb.html">
lib/selenium_on_rails/fixture_loader.rb
</a>
<br />
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000049">available_fixtures</a>&nbsp;&nbsp;
<a href="#M000051">clear_tables</a>&nbsp;&nbsp;
<a href="#M000050">load_fixtures</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="includes">
<h3 class="section-bar">Included Modules</h3>
<div id="includes-list">
<span class="include-name"><a href="Paths.html">SeleniumOnRails::Paths</a></span>
</div>
</div>
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000049" class="method-detail">
<a name="M000049"></a>
<div class="method-heading">
<a href="#M000049" class="method-signature">
<span class="method-name">available_fixtures</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000049-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000049-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/fixture_loader.rb, line 6</span>
6: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">available_fixtures</span>
7: <span class="ruby-identifier">fixtures</span> = {}
8: <span class="ruby-identifier">path</span> = <span class="ruby-identifier">fixtures_path</span> <span class="ruby-operator">+</span> <span class="ruby-value str">'/'</span>
9: <span class="ruby-identifier">files</span> = <span class="ruby-constant">Dir</span>[<span class="ruby-node">&quot;#{path}**/*.{yml,csv}&quot;</span>]
10: <span class="ruby-identifier">files</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">file</span><span class="ruby-operator">|</span>
11: <span class="ruby-identifier">rel_path</span> = <span class="ruby-identifier">file</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-identifier">path</span>, <span class="ruby-value str">''</span>)
12: <span class="ruby-keyword kw">next</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">skip_file?</span> <span class="ruby-identifier">rel_path</span>
13: <span class="ruby-identifier">fixture_set</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-identifier">rel_path</span>)
14: <span class="ruby-identifier">fixture_set</span> = <span class="ruby-value str">''</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">fixture_set</span> <span class="ruby-operator">==</span> <span class="ruby-value str">'.'</span>
15: <span class="ruby-identifier">fixture</span> = <span class="ruby-identifier">rel_path</span>.<span class="ruby-identifier">sub</span> <span class="ruby-regexp re">/\.[^.]*$/</span>, <span class="ruby-value str">''</span>
16: <span class="ruby-identifier">fixtures</span>[<span class="ruby-identifier">fixture_set</span>] <span class="ruby-operator">||=</span> []
17: <span class="ruby-identifier">fixtures</span>[<span class="ruby-identifier">fixture_set</span>] <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">fixture</span>
18: <span class="ruby-keyword kw">end</span>
19:
20: <span class="ruby-identifier">fixtures</span>
21: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000051" class="method-detail">
<a name="M000051"></a>
<div class="method-heading">
<a href="#M000051" class="method-signature">
<span class="method-name">clear_tables</span><span class="method-args">(tables)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000051-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000051-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/fixture_loader.rb, line 45</span>
45: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">clear_tables</span> <span class="ruby-identifier">tables</span>
46: <span class="ruby-identifier">table_names</span> = <span class="ruby-identifier">tables</span>.<span class="ruby-identifier">split</span> <span class="ruby-regexp re">/\s*,\s*/</span>
47: <span class="ruby-identifier">connection</span> = <span class="ruby-constant">ActiveRecord</span><span class="ruby-operator">::</span><span class="ruby-constant">Base</span>.<span class="ruby-identifier">connection</span>
48: <span class="ruby-identifier">table_names</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">table</span><span class="ruby-operator">|</span>
49: <span class="ruby-identifier">connection</span>.<span class="ruby-identifier">execute</span> <span class="ruby-node">&quot;DELETE FROM #{table}&quot;</span>
50: <span class="ruby-keyword kw">end</span>
51: <span class="ruby-identifier">table_names</span>
52: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000050" class="method-detail">
<a name="M000050"></a>
<div class="method-heading">
<a href="#M000050" class="method-signature">
<span class="method-name">load_fixtures</span><span class="method-args">(fixtures_param)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000050-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000050-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/fixture_loader.rb, line 23</span>
23: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">load_fixtures</span> <span class="ruby-identifier">fixtures_param</span>
24: <span class="ruby-identifier">available</span> = <span class="ruby-keyword kw">nil</span>
25: <span class="ruby-identifier">fixtures</span> = <span class="ruby-identifier">fixtures_param</span>.<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">/\s*,\s*/</span>).<span class="ruby-identifier">collect</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span>
26: <span class="ruby-identifier">fixture_set</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span> <span class="ruby-identifier">f</span>
27: <span class="ruby-identifier">fixture_set</span> = <span class="ruby-value str">''</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">fixture_set</span> <span class="ruby-operator">==</span> <span class="ruby-value str">'.'</span>
28: <span class="ruby-identifier">fixture</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">basename</span> <span class="ruby-identifier">f</span>
29: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">fixture</span> <span class="ruby-operator">==</span> <span class="ruby-value str">'all'</span>
30: <span class="ruby-identifier">available</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">available_fixtures</span>
31: <span class="ruby-identifier">available</span>[<span class="ruby-identifier">fixture_set</span>]
32: <span class="ruby-keyword kw">else</span>
33: <span class="ruby-identifier">f</span>
34: <span class="ruby-keyword kw">end</span>
35: <span class="ruby-keyword kw">end</span>
36: <span class="ruby-identifier">fixtures</span>.<span class="ruby-identifier">flatten!</span>
37: <span class="ruby-identifier">fixtures</span>.<span class="ruby-identifier">reject!</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">blank?</span> }
38:
39: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">fixtures</span>.<span class="ruby-identifier">any?</span>
40: <span class="ruby-constant">Fixtures</span>.<span class="ruby-identifier">create_fixtures</span> <span class="ruby-identifier">fixtures_path</span>, <span class="ruby-identifier">fixtures</span>
41: <span class="ruby-keyword kw">end</span>
42: <span class="ruby-identifier">fixtures</span>
43: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,195 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Module: SeleniumOnRails::PartialsSupport</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Module</strong></td>
<td class="class-name-in-header">SeleniumOnRails::PartialsSupport</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../../files/lib/selenium_on_rails/partials_support_rb.html">
lib/selenium_on_rails/partials_support.rb
</a>
<br />
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
<div id="description">
<p>
Provides partials support to test cases so they can include other partial
test cases.
</p>
<p>
The partial&#8217;s commands are returned as html table rows.
</p>
</div>
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000081">extract_commands_from_partial</a>&nbsp;&nbsp;
<a href="#M000080">render_partial</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="includes">
<h3 class="section-bar">Included Modules</h3>
<div id="includes-list">
<span class="include-name"><a href="Paths.html">SeleniumOnRails::Paths</a></span>
</div>
</div>
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000081" class="method-detail">
<a name="M000081"></a>
<div class="method-heading">
<a href="#M000081" class="method-signature">
<span class="method-name">extract_commands_from_partial</span><span class="method-args">(partial)</span>
</a>
</div>
<div class="method-description">
<p>
Extracts the commands from a partial. The partial must contain a html table
and the first row is ignored since it cannot contain a command.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000081-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000081-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/partials_support.rb, line 19</span>
19: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">extract_commands_from_partial</span> <span class="ruby-identifier">partial</span>
20: <span class="ruby-identifier">partial</span> = <span class="ruby-identifier">partial</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/.*&lt;table&gt;.*?&lt;tr&gt;.*?&lt;\/tr&gt;(.*?)&lt;\/table&gt;/i</span><span class="ruby-identifier">m</span>)[<span class="ruby-value">1</span>]
21: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Partial '#{name}' doesn't contain any table&quot;</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">partial</span>
22: <span class="ruby-identifier">partial</span>
23: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000080" class="method-detail">
<a name="M000080"></a>
<div class="method-heading">
<a href="#M000080" class="method-signature">
<span class="method-name">render_partial</span><span class="method-args">(partial_path = default_template_name, object = nil, local_assigns = nil, status = nil)</span>
</a>
</div>
<div class="method-description">
<p>
Overrides where the partial is searched for, and returns only the command
table rows.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000080-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000080-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/partials_support.rb, line 9</span>
9: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">render_partial</span> <span class="ruby-identifier">partial_path</span> = <span class="ruby-identifier">default_template_name</span>, <span class="ruby-identifier">object</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">local_assigns</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">status</span> = <span class="ruby-keyword kw">nil</span>
10: <span class="ruby-identifier">pattern</span> = <span class="ruby-identifier">partial_pattern</span> <span class="ruby-identifier">partial_path</span>
11: <span class="ruby-identifier">filename</span> = <span class="ruby-constant">Dir</span>[<span class="ruby-identifier">pattern</span>].<span class="ruby-identifier">first</span>
12: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Partial '#{partial_path}' cannot be found! (Looking for file: '#{pattern}')&quot;</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">filename</span>
13: <span class="ruby-identifier">partial</span> = <span class="ruby-identifier">render</span> <span class="ruby-identifier">:file</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">filename</span>, <span class="ruby-identifier">:use_full_path</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-keyword kw">false</span>, <span class="ruby-identifier">:locals</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">local_assigns</span>
14: <span class="ruby-identifier">extract_commands_from_partial</span> <span class="ruby-identifier">partial</span>
15: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,295 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Module: SeleniumOnRails::Paths</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Module</strong></td>
<td class="class-name-in-header">SeleniumOnRails::Paths</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../../files/lib/selenium_on_rails/paths_rb.html">
lib/selenium_on_rails/paths.rb
</a>
<br />
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000042">fixtures_path</a>&nbsp;&nbsp;
<a href="#M000041">layout_path</a>&nbsp;&nbsp;
<a href="#M000043">log_path</a>&nbsp;&nbsp;
<a href="#M000038">selenium_path</a>&nbsp;&nbsp;
<a href="#M000039">selenium_tests_path</a>&nbsp;&nbsp;
<a href="#M000044">skip_file?</a>&nbsp;&nbsp;
<a href="#M000040">view_path</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000042" class="method-detail">
<a name="M000042"></a>
<div class="method-heading">
<a href="#M000042" class="method-signature">
<span class="method-name">fixtures_path</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000042-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000042-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/paths.rb, line 25</span>
25: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">fixtures_path</span>
26: <span class="ruby-constant">File</span>.<span class="ruby-identifier">expand_path</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-constant">RAILS_ROOT</span>, <span class="ruby-value str">'test/fixtures'</span>)
27: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000041" class="method-detail">
<a name="M000041"></a>
<div class="method-heading">
<a href="#M000041" class="method-signature">
<span class="method-name">layout_path</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p>
Returns the path to the layout template. The path is relative in relation
to the app/views/ directory since Rails doesn&#8217;t support absolute
paths to layout templates.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000041-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000041-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/paths.rb, line 19</span>
19: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">layout_path</span>
20: <span class="ruby-identifier">rails_root</span> = <span class="ruby-constant">Pathname</span>.<span class="ruby-identifier">new</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">expand_path</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-constant">RAILS_ROOT</span>, <span class="ruby-value str">'app/views'</span>))
21: <span class="ruby-identifier">view_path</span> = <span class="ruby-constant">Pathname</span>.<span class="ruby-identifier">new</span> <span class="ruby-identifier">view_path</span>(<span class="ruby-value str">'layout'</span>)
22: <span class="ruby-identifier">view_path</span>.<span class="ruby-identifier">relative_path_from</span>(<span class="ruby-identifier">rails_root</span>).<span class="ruby-identifier">to_s</span>
23: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000043" class="method-detail">
<a name="M000043"></a>
<div class="method-heading">
<a href="#M000043" class="method-signature">
<span class="method-name">log_path</span><span class="method-args">(log_file)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000043-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000043-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/paths.rb, line 29</span>
29: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">log_path</span> <span class="ruby-identifier">log_file</span>
30: <span class="ruby-constant">File</span>.<span class="ruby-identifier">expand_path</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-keyword kw">__FILE__</span>) <span class="ruby-operator">+</span> <span class="ruby-value str">'/../../log/'</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">log_file</span>)
31: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000038" class="method-detail">
<a name="M000038"></a>
<div class="method-heading">
<a href="#M000038" class="method-signature">
<span class="method-name">selenium_path</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000038-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000038-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/paths.rb, line 3</span>
3: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">selenium_path</span>
4: <span class="ruby-ivar">@@selenium_path</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">find_selenium_path</span>
5: <span class="ruby-ivar">@@selenium_path</span>
6: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000039" class="method-detail">
<a name="M000039"></a>
<div class="method-heading">
<a href="#M000039" class="method-signature">
<span class="method-name">selenium_tests_path</span><span class="method-args">()</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000039-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000039-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/paths.rb, line 8</span>
8: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">selenium_tests_path</span>
9: <span class="ruby-constant">File</span>.<span class="ruby-identifier">expand_path</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-constant">RAILS_ROOT</span>, <span class="ruby-value str">'test/selenium'</span>))
10: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000044" class="method-detail">
<a name="M000044"></a>
<div class="method-heading">
<a href="#M000044" class="method-signature">
<span class="method-name">skip_file?</span><span class="method-args">(file)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000044-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000044-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/paths.rb, line 33</span>
33: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">skip_file?</span> <span class="ruby-identifier">file</span>
34: <span class="ruby-identifier">file</span>.<span class="ruby-identifier">split</span>(<span class="ruby-value str">'/'</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span>
35: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">true</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">upcase</span> <span class="ruby-operator">==</span> <span class="ruby-value str">'CVS'</span> <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">starts_with?</span>(<span class="ruby-value str">'.'</span>) <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">ends_with?</span>(<span class="ruby-value str">'~'</span>) <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">starts_with?</span>(<span class="ruby-value str">'_'</span>)
36: <span class="ruby-keyword kw">end</span>
37: <span class="ruby-keyword kw">false</span>
38: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000040" class="method-detail">
<a name="M000040"></a>
<div class="method-heading">
<a href="#M000040" class="method-signature">
<span class="method-name">view_path</span><span class="method-args">(view)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000040-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000040-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/paths.rb, line 12</span>
12: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">view_path</span> <span class="ruby-identifier">view</span>
13: <span class="ruby-constant">File</span>.<span class="ruby-identifier">expand_path</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-keyword kw">__FILE__</span>) <span class="ruby-operator">+</span> <span class="ruby-value str">'/../views/'</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">view</span>)
14: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,219 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Class: SeleniumOnRails::RSelenese</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Class</strong></td>
<td class="class-name-in-header">SeleniumOnRails::RSelenese</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../../files/lib/selenium_on_rails/rselenese_rb.html">
lib/selenium_on_rails/rselenese.rb
</a>
<br />
</td>
</tr>
<tr class="top-aligned-row">
<td><strong>Parent:</strong></td>
<td>
<a href="TestBuilder.html">
SeleniumOnRails::TestBuilder
</a>
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
<div id="description">
<p>
Renders Selenium test templates in a fashion analogous to <tt>rxml</tt> and
<tt>rjs</tt> templates.
</p>
<pre>
setup
open :controller =&gt; 'customer', :action =&gt; 'list'
assert_title 'Customers'
</pre>
<p>
See <a href="TestBuilder.html">SeleniumOnRails::TestBuilder</a> for a list
of available commands.
</p>
</div>
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000084">new</a>&nbsp;&nbsp;
<a href="#M000085">render</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="section">
<div id="attribute-list">
<h3 class="section-bar">Attributes</h3>
<div class="name-list">
<table>
<tr class="top-aligned-row context-row">
<td class="context-item-name">view</td>
<td class="context-item-value">&nbsp;[RW]&nbsp;</td>
<td class="context-item-desc"></td>
</tr>
</table>
</div>
</div>
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Class methods</h3>
<div id="method-M000084" class="method-detail">
<a name="M000084"></a>
<div class="method-heading">
<a href="#M000084" class="method-signature">
<span class="method-name">new</span><span class="method-args">(view)</span>
</a>
</div>
<div class="method-description">
<p>
Create a new <a href="RSelenese.html">RSelenese</a> renderer bound to
<em>view</em>.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000084-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000084-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/rselenese.rb, line 17</span>
17: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span> <span class="ruby-identifier">view</span>
18: <span class="ruby-keyword kw">super</span> <span class="ruby-identifier">view</span>
19: <span class="ruby-ivar">@view</span> = <span class="ruby-identifier">view</span>
20: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000085" class="method-detail">
<a name="M000085"></a>
<div class="method-heading">
<a href="#M000085" class="method-signature">
<span class="method-name">render</span><span class="method-args">(template, local_assigns)</span>
</a>
</div>
<div class="method-description">
<p>
Render <em>template</em> using <em>local_assigns</em>.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000085-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000085-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/rselenese.rb, line 23</span>
23: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">render</span> <span class="ruby-identifier">template</span>, <span class="ruby-identifier">local_assigns</span>
24: <span class="ruby-identifier">title</span> = (<span class="ruby-ivar">@view</span>.<span class="ruby-identifier">assigns</span>[<span class="ruby-value str">'page_title'</span>] <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">local_assigns</span>[<span class="ruby-value str">'page_title'</span>])
25: <span class="ruby-identifier">table</span>(<span class="ruby-identifier">title</span>) <span class="ruby-keyword kw">do</span>
26: <span class="ruby-identifier">test</span> = <span class="ruby-keyword kw">self</span> <span class="ruby-comment cmt">#to enable test.command</span>
27:
28: <span class="ruby-identifier">assign_locals_code</span> = <span class="ruby-value str">''</span>
29: <span class="ruby-identifier">local_assigns</span>.<span class="ruby-identifier">each_key</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">key</span><span class="ruby-operator">|</span> <span class="ruby-identifier">assign_locals_code</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot;#{key} = local_assigns[#{key.inspect}];&quot;</span>}
30:
31: <span class="ruby-identifier">eval</span> <span class="ruby-identifier">assign_locals_code</span> <span class="ruby-operator">+</span> <span class="ruby-value str">&quot;\n&quot;</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">template</span>
32: <span class="ruby-keyword kw">end</span>
33: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,156 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Module: SeleniumOnRails::Renderer</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Module</strong></td>
<td class="class-name-in-header">SeleniumOnRails::Renderer</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../../files/lib/selenium_on_rails/renderer_rb.html">
lib/selenium_on_rails/renderer.rb
</a>
<br />
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000037">render_test_case</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="includes">
<h3 class="section-bar">Included Modules</h3>
<div id="includes-list">
<span class="include-name"><a href="Paths.html">SeleniumOnRails::Paths</a></span>
<span class="include-name"><a href="../SeleniumHelper.html">SeleniumHelper</a></span>
</div>
</div>
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000037" class="method-detail">
<a name="M000037"></a>
<div class="method-heading">
<a href="#M000037" class="method-signature">
<span class="method-name">render_test_case</span><span class="method-args">(filename)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000037-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000037-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/renderer.rb, line 5</span>
5: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">render_test_case</span> <span class="ruby-identifier">filename</span>
6: <span class="ruby-ivar">@template</span>.<span class="ruby-identifier">extend</span> <span class="ruby-constant">SeleniumOnRails</span><span class="ruby-operator">::</span><span class="ruby-constant">PartialsSupport</span>
7: <span class="ruby-ivar">@page_title</span> = <span class="ruby-identifier">test_case_name</span> <span class="ruby-identifier">filename</span>
8: <span class="ruby-identifier">output</span> = <span class="ruby-identifier">render_to_string</span> <span class="ruby-identifier">:file</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">filename</span>
9: <span class="ruby-identifier">layout</span> = (<span class="ruby-identifier">output</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/&lt;html&gt;/i</span> <span class="ruby-operator">?</span> <span class="ruby-keyword kw">false</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">layout_path</span>)
10: <span class="ruby-identifier">render</span> <span class="ruby-identifier">:text</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">output</span>, <span class="ruby-identifier">:layout</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">layout</span>
11:
12: <span class="ruby-identifier">headers</span>[<span class="ruby-value str">'Cache-control'</span>] = <span class="ruby-value str">'no-cache'</span>
13: <span class="ruby-identifier">headers</span>[<span class="ruby-value str">'Pragma'</span>] = <span class="ruby-value str">'no-cache'</span>
14: <span class="ruby-identifier">headers</span>[<span class="ruby-value str">'Expires'</span>] = <span class="ruby-value str">'-1'</span>
15: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,179 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Class: SeleniumOnRails::Selenese</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Class</strong></td>
<td class="class-name-in-header">SeleniumOnRails::Selenese</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../../files/lib/selenium_on_rails/selenese_rb.html">
lib/selenium_on_rails/selenese.rb
</a>
<br />
</td>
</tr>
<tr class="top-aligned-row">
<td><strong>Parent:</strong></td>
<td>
Object
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000082">new</a>&nbsp;&nbsp;
<a href="#M000083">render</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Class methods</h3>
<div id="method-M000082" class="method-detail">
<a name="M000082"></a>
<div class="method-heading">
<a href="#M000082" class="method-signature">
<span class="method-name">new</span><span class="method-args">(view)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000082-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000082-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/selenese.rb, line 7</span>
7: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span> <span class="ruby-identifier">view</span>
8: <span class="ruby-ivar">@view</span> = <span class="ruby-identifier">view</span>
9: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000083" class="method-detail">
<a name="M000083"></a>
<div class="method-heading">
<a href="#M000083" class="method-signature">
<span class="method-name">render</span><span class="method-args">(template, local_assigns)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000083-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000083-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/selenese.rb, line 11</span>
11: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">render</span> <span class="ruby-identifier">template</span>, <span class="ruby-identifier">local_assigns</span>
12: <span class="ruby-identifier">name</span> = (<span class="ruby-ivar">@view</span>.<span class="ruby-identifier">assigns</span>[<span class="ruby-value str">'page_title'</span>] <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">local_assigns</span>[<span class="ruby-value str">'page_title'</span>])
13: <span class="ruby-identifier">lines</span> = <span class="ruby-identifier">template</span>.<span class="ruby-identifier">strip</span>.<span class="ruby-identifier">split</span> <span class="ruby-value str">&quot;\n&quot;</span>
14: <span class="ruby-identifier">html</span> = <span class="ruby-value str">''</span>
15: <span class="ruby-identifier">html</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">extract_comments</span>(<span class="ruby-identifier">lines</span>)
16: <span class="ruby-identifier">html</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">extract_commands</span>(<span class="ruby-identifier">lines</span>, <span class="ruby-identifier">name</span>)
17: <span class="ruby-identifier">html</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">extract_comments</span>(<span class="ruby-identifier">lines</span>)
18: <span class="ruby-identifier">raise</span> <span class="ruby-value str">'You cannot have comments in the middle of commands!'</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">next_line</span> <span class="ruby-identifier">lines</span>, <span class="ruby-identifier">:any</span>
19: <span class="ruby-identifier">html</span>
20: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,223 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Module: SeleniumOnRails::SuiteRenderer</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Module</strong></td>
<td class="class-name-in-header">SeleniumOnRails::SuiteRenderer</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../../files/lib/selenium_on_rails/suite_renderer_rb.html">
lib/selenium_on_rails/suite_renderer.rb
</a>
<br />
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000048">link_to_test_case</a>&nbsp;&nbsp;
<a href="#M000047">test_cases</a>&nbsp;&nbsp;
<a href="#M000045">test_suite_name</a>&nbsp;&nbsp;
<a href="#M000046">test_suites</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000048" class="method-detail">
<a name="M000048"></a>
<div class="method-heading">
<a href="#M000048" class="method-signature">
<span class="method-name">link_to_test_case</span><span class="method-args">(suite_name, filename)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000048-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000048-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/suite_renderer.rb, line 24</span>
24: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">link_to_test_case</span> <span class="ruby-identifier">suite_name</span>, <span class="ruby-identifier">filename</span>
25: <span class="ruby-identifier">name</span> = <span class="ruby-identifier">suite_name</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">test_case_name</span>(<span class="ruby-identifier">filename</span>)
26: <span class="ruby-identifier">link_to</span> <span class="ruby-identifier">name</span>, <span class="ruby-identifier">:action</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:test_file</span>, <span class="ruby-identifier">:testname</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">path_to_relative_url</span>(<span class="ruby-identifier">filename</span>).<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/^\//</span>,<span class="ruby-value str">''</span>)
27: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000047" class="method-detail">
<a name="M000047"></a>
<div class="method-heading">
<a href="#M000047" class="method-signature">
<span class="method-name">test_cases</span><span class="method-args">(path)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000047-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000047-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/suite_renderer.rb, line 18</span>
18: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">test_cases</span> <span class="ruby-identifier">path</span>
19: <span class="ruby-identifier">tests</span> = []
20: <span class="ruby-identifier">visit_all_tests</span> <span class="ruby-identifier">path</span>, <span class="ruby-value str">''</span>, <span class="ruby-keyword kw">nil</span>, <span class="ruby-constant">Proc</span>.<span class="ruby-identifier">new</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">n</span>, <span class="ruby-identifier">p</span><span class="ruby-operator">|</span> <span class="ruby-identifier">tests</span> <span class="ruby-operator">&lt;&lt;</span> [<span class="ruby-identifier">n</span>,<span class="ruby-identifier">p</span>]}
21: <span class="ruby-identifier">tests</span>
22: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000045" class="method-detail">
<a name="M000045"></a>
<div class="method-heading">
<a href="#M000045" class="method-signature">
<span class="method-name">test_suite_name</span><span class="method-args">(path)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000045-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000045-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/suite_renderer.rb, line 2</span>
2: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">test_suite_name</span> <span class="ruby-identifier">path</span>
3: <span class="ruby-keyword kw">return</span> <span class="ruby-value str">'All test cases'</span> <span class="ruby-keyword kw">if</span> [<span class="ruby-keyword kw">nil</span>, <span class="ruby-value str">'/'</span>].<span class="ruby-identifier">include?</span> <span class="ruby-identifier">path_to_relative_url</span>(<span class="ruby-identifier">path</span>)
4: <span class="ruby-constant">File</span>.<span class="ruby-identifier">split</span>(<span class="ruby-identifier">path</span>)[<span class="ruby-value">-1</span>].<span class="ruby-identifier">humanize</span>
5: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000046" class="method-detail">
<a name="M000046"></a>
<div class="method-heading">
<a href="#M000046" class="method-signature">
<span class="method-name">test_suites</span><span class="method-args">(path)</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000046-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000046-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/suite_renderer.rb, line 7</span>
7: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">test_suites</span> <span class="ruby-identifier">path</span>
8: <span class="ruby-identifier">suites</span> = []
9:
10: <span class="ruby-identifier">parent_path</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">split</span>(<span class="ruby-identifier">path</span>).<span class="ruby-identifier">slice</span>(<span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-value">-2</span>)) <span class="ruby-comment cmt">#all but last</span>
11: <span class="ruby-identifier">parent_path</span> = <span class="ruby-identifier">path_to_relative_url</span> <span class="ruby-identifier">parent_path</span>
12: <span class="ruby-identifier">suites</span> <span class="ruby-operator">&lt;&lt;</span> [<span class="ruby-value str">'..'</span>, <span class="ruby-identifier">parent_path</span>] <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">parent_path</span>.<span class="ruby-identifier">nil?</span>
13:
14: <span class="ruby-identifier">visit_all_tests</span> <span class="ruby-identifier">path</span>, <span class="ruby-value str">''</span>, <span class="ruby-constant">Proc</span>.<span class="ruby-identifier">new</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">n</span>, <span class="ruby-identifier">p</span><span class="ruby-operator">|</span> <span class="ruby-identifier">suites</span> <span class="ruby-operator">&lt;&lt;</span> [<span class="ruby-identifier">n</span>,<span class="ruby-identifier">path_to_relative_url</span>(<span class="ruby-identifier">p</span>)]}, <span class="ruby-keyword kw">nil</span>
15: <span class="ruby-identifier">suites</span>
16: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,372 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Class: SeleniumOnRails::TestBuilder</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Class</strong></td>
<td class="class-name-in-header">SeleniumOnRails::TestBuilder</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../../files/lib/selenium_on_rails/test_builder_rb.html">
lib/selenium_on_rails/test_builder.rb
</a>
<br />
</td>
</tr>
<tr class="top-aligned-row">
<td><strong>Parent:</strong></td>
<td>
Object
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
<div id="description">
<p>
Builds Selenium test table using a high-level Ruby interface. Normally
invoked through <a href="RSelenese.html">SeleniumOnRails::RSelenese</a>.
</p>
<p>
See <a
href="TestBuilderActions.html">SeleniumOnRails::TestBuilderActions</a> for
the available actions and <a
href="TestBuilderAccessors.html">SeleniumOnRails::TestBuilderAccessors</a>
for the available checks.
</p>
<p>
For more information on the commands supported by <a
href="TestBuilder.html">TestBuilder</a>, see the Selenium Commands
Documentation at <a
href="http://release.openqa.org/selenium-core/nightly/reference.html">release.openqa.org/selenium-core/nightly/reference.html</a>.
</p>
</div>
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000090">command</a>&nbsp;&nbsp;
<a href="#M000092">command_and_wait</a>&nbsp;&nbsp;
<a href="#M000091">command_verbatim</a>&nbsp;&nbsp;
<a href="#M000087">exactize</a>&nbsp;&nbsp;
<a href="#M000093">make_command_waiting</a>&nbsp;&nbsp;
<a href="#M000088">new</a>&nbsp;&nbsp;
<a href="#M000086">selenize</a>&nbsp;&nbsp;
<a href="#M000089">table</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="includes">
<h3 class="section-bar">Included Modules</h3>
<div id="includes-list">
<span class="include-name"><a href="TestBuilderActions.html">SeleniumOnRails::TestBuilderActions</a></span>
<span class="include-name"><a href="TestBuilderAccessors.html">SeleniumOnRails::TestBuilderAccessors</a></span>
</div>
</div>
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Class methods</h3>
<div id="method-M000088" class="method-detail">
<a name="M000088"></a>
<div class="method-heading">
<a href="#M000088" class="method-signature">
<span class="method-name">new</span><span class="method-args">(view)</span>
</a>
</div>
<div class="method-description">
<p>
Create a new <a href="TestBuilder.html">TestBuilder</a> for <em>view</em>.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000088-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000088-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/test_builder.rb, line 26</span>
26: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span> <span class="ruby-identifier">view</span>
27: <span class="ruby-ivar">@view</span> = <span class="ruby-identifier">view</span>
28: <span class="ruby-ivar">@output</span> = <span class="ruby-value str">''</span>
29: <span class="ruby-ivar">@xml</span> = <span class="ruby-constant">Builder</span><span class="ruby-operator">::</span><span class="ruby-constant">XmlMarkup</span>.<span class="ruby-identifier">new</span> <span class="ruby-identifier">:indent</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value">2</span>, <span class="ruby-identifier">:target</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-ivar">@output</span>
30: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000086" class="method-detail">
<a name="M000086"></a>
<div class="method-heading">
<a href="#M000086" class="method-signature">
<span class="method-name">selenize</span><span class="method-args">(str)</span>
</a>
</div>
<div class="method-description">
<p>
Convert <em>str</em> to a Selenium command name.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000086-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000086-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/test_builder.rb, line 15</span>
15: <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">selenize</span> <span class="ruby-identifier">str</span>
16: <span class="ruby-identifier">str</span>.<span class="ruby-identifier">camelize</span>.<span class="ruby-identifier">gsub</span>(<span class="ruby-regexp re">/^[A-Z]/</span>) {<span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">downcase</span> }
17: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<h3 class="section-bar">Public Instance methods</h3>
<div id="method-M000090" class="method-detail">
<a name="M000090"></a>
<div class="method-heading">
<a href="#M000090" class="method-signature">
<span class="method-name">command</span><span class="method-args">(cmd, target=nil, value=nil)</span>
</a>
</div>
<div class="method-description">
<p>
Add a new test command using <em>cmd</em>, <em>target</em> and
<em>value</em>.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000090-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000090-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/test_builder.rb, line 41</span>
41: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">command</span> <span class="ruby-identifier">cmd</span>, <span class="ruby-identifier">target</span>=<span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">value</span>=<span class="ruby-keyword kw">nil</span>
42: <span class="ruby-ivar">@xml</span>.<span class="ruby-identifier">tr</span> <span class="ruby-keyword kw">do</span>
43: <span class="ruby-identifier">_tdata</span> <span class="ruby-identifier">cmd</span>
44: <span class="ruby-identifier">_tdata</span> <span class="ruby-identifier">target</span>
45: <span class="ruby-identifier">_tdata</span> <span class="ruby-identifier">value</span>
46: <span class="ruby-keyword kw">end</span>
47: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000092" class="method-detail">
<a name="M000092"></a>
<div class="method-heading">
<a href="#M000092" class="method-signature">
<span class="method-name">command_and_wait</span><span class="method-args">(cmd, target=nil, value=nil)</span>
</a>
</div>
<div class="method-description">
<p>
Same as <em>command</em> but add <em>AndWait</em> to the name of
<em>cmd</em>.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000092-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000092-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/test_builder.rb, line 52</span>
52: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">command_and_wait</span> <span class="ruby-identifier">cmd</span>, <span class="ruby-identifier">target</span>=<span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">value</span>=<span class="ruby-keyword kw">nil</span>
53: <span class="ruby-identifier">command_verbatim</span> <span class="ruby-identifier">cmd</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">+</span> <span class="ruby-value str">'AndWait'</span>, <span class="ruby-identifier">target</span>, <span class="ruby-identifier">value</span>
54: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000091" class="method-detail">
<a name="M000091"></a>
<div class="method-heading">
<span class="method-name">command_verbatim</span><span class="method-args">(cmd, target=nil, value=nil)</span>
</div>
<div class="method-description">
<p>
Alias for <a href="TestBuilder.html#M000090">command</a>
</p>
</div>
</div>
<div id="method-M000087" class="method-detail">
<a name="M000087"></a>
<div class="method-heading">
<a href="#M000087" class="method-signature">
<span class="method-name">exactize</span><span class="method-args">(pattern)</span>
</a>
</div>
<div class="method-description">
<p>
Prepends <em>pattern</em> with &#8216;exact:&#8217; if it would be
considered containing string-match pattern otherwise.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000087-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000087-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/test_builder.rb, line 21</span>
21: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">exactize</span> <span class="ruby-identifier">pattern</span>
22: <span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-value str">':'</span>) <span class="ruby-operator">?</span> <span class="ruby-node">&quot;exact:#{pattern}&quot;</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">pattern</span>
23: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000093" class="method-detail">
<a name="M000093"></a>
<div class="method-heading">
<a href="#M000093" class="method-signature">
<span class="method-name">make_command_waiting</span><span class="method-args">() {|| ...}</span>
</a>
</div>
<div class="method-description">
<p>
Re routes commands in the provided block to <a
href="TestBuilder.html#M000092">command_and_wait</a> instead of <a
href="TestBuilder.html#M000090">command</a>.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000093-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000093-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/test_builder.rb, line 58</span>
58: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">make_command_waiting</span>
59: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">class</span>.<span class="ruby-identifier">send</span> <span class="ruby-identifier">:alias_method</span>, <span class="ruby-identifier">:command</span>, <span class="ruby-identifier">:command_and_wait</span>
60: <span class="ruby-keyword kw">yield</span>
61: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">class</span>.<span class="ruby-identifier">send</span> <span class="ruby-identifier">:alias_method</span>, <span class="ruby-identifier">:command</span>, <span class="ruby-identifier">:command_verbatim</span>
62: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
<div id="method-M000089" class="method-detail">
<a name="M000089"></a>
<div class="method-heading">
<a href="#M000089" class="method-signature">
<span class="method-name">table</span><span class="method-args">(title) {|self| ...}</span>
</a>
</div>
<div class="method-description">
<p>
Add a new table of tests, and return the HTML.
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000089-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000089-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails/test_builder.rb, line 33</span>
33: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">table</span> <span class="ruby-identifier">title</span>
34: <span class="ruby-ivar">@xml</span>.<span class="ruby-identifier">table</span> <span class="ruby-keyword kw">do</span>
35: <span class="ruby-ivar">@xml</span>.<span class="ruby-identifier">tr</span> <span class="ruby-keyword kw">do</span> <span class="ruby-ivar">@xml</span>.<span class="ruby-identifier">th</span>(<span class="ruby-identifier">title</span>, <span class="ruby-identifier">:colspan</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value">3</span>) <span class="ruby-keyword kw">end</span>
36: <span class="ruby-keyword kw">yield</span> <span class="ruby-keyword kw">self</span>
37: <span class="ruby-keyword kw">end</span>
38: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

View file

@ -1,150 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Class: SeleniumOnRailsConfig</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
<script type="text/javascript">
// <![CDATA[
function popupCode( url ) {
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
}
function toggleCode( id ) {
if ( document.getElementById )
elem = document.getElementById( id );
else if ( document.all )
elem = eval( "document.all." + id );
else
return false;
elemStyle = elem.style;
if ( elemStyle.display != "block" ) {
elemStyle.display = "block"
} else {
elemStyle.display = "none"
}
return true;
}
// Make codeblocks hidden by default
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
// ]]>
</script>
</head>
<body>
<div id="classHeader">
<table class="header-table">
<tr class="top-aligned-row">
<td><strong>Class</strong></td>
<td class="class-name-in-header">SeleniumOnRailsConfig</td>
</tr>
<tr class="top-aligned-row">
<td><strong>In:</strong></td>
<td>
<a href="../files/lib/selenium_on_rails_config_rb.html">
lib/selenium_on_rails_config.rb
</a>
<br />
</td>
</tr>
<tr class="top-aligned-row">
<td><strong>Parent:</strong></td>
<td>
Object
</td>
</tr>
</table>
</div>
<!-- banner header -->
<div id="bodyContent">
<div id="contextContent">
</div>
<div id="method-list">
<h3 class="section-bar">Methods</h3>
<div class="name-list">
<a href="#M000007">get</a>&nbsp;&nbsp;
</div>
</div>
</div>
<!-- if includes -->
<div id="section">
<!-- if method_list -->
<div id="methods">
<h3 class="section-bar">Public Class methods</h3>
<div id="method-M000007" class="method-detail">
<a name="M000007"></a>
<div class="method-heading">
<a href="#M000007" class="method-signature">
<span class="method-name">get</span><span class="method-args">(var, default = nil) {|if block_given?| ...}</span>
</a>
</div>
<div class="method-description">
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000007-source">
<pre>
<span class="ruby-comment cmt"># File lib/selenium_on_rails_config.rb, line 5</span>
5: <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">get</span> <span class="ruby-identifier">var</span>, <span class="ruby-identifier">default</span> = <span class="ruby-keyword kw">nil</span>
6: <span class="ruby-identifier">value</span> = <span class="ruby-identifier">configs</span>[<span class="ruby-identifier">var</span>.<span class="ruby-identifier">to_s</span>]
7: <span class="ruby-identifier">value</span> <span class="ruby-operator">||=</span> <span class="ruby-ivar">@@defaults</span>[<span class="ruby-identifier">var</span>]
8: <span class="ruby-identifier">value</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">default</span>
9: <span class="ruby-identifier">value</span> <span class="ruby-operator">||=</span> <span class="ruby-keyword kw">yield</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">block_given?</span>
10: <span class="ruby-identifier">value</span>
11: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more