diff options
author | Rodrigo Rosenfeld Rosas <rr.rosas@gmail.com> | 2011-05-16 16:34:26 (GMT) |
---|---|---|
committer | Rodrigo Rosenfeld Rosas <rr.rosas@gmail.com> | 2011-06-23 13:26:16 (GMT) |
commit | a595d36ce020e607bcd0df29e4b5a119fc001388 (patch) | |
tree | e5f5c6537a5a8c1e8ea70348c30d5a4feb0f4c30 /vendor | |
parent | 902eecfea929f86cc1c75e4b384cad07192c2f02 (diff) |
Remove vendored state-machine plugin as it was already included in Gemfile
Diffstat (limited to 'vendor')
57 files changed, 0 insertions, 13198 deletions
diff --git a/vendor/plugins/state_machine-0.6.3/CHANGELOG.rdoc b/vendor/plugins/state_machine-0.6.3/CHANGELOG.rdoc deleted file mode 100644 index ad5c2bf..0000000 --- a/vendor/plugins/state_machine-0.6.3/CHANGELOG.rdoc +++ /dev/null @@ -1,204 +0,0 @@ -== master - -== 0.6.3 / 2008-03-10 - -* Add support for customizing the graph's orientation -* Use the standard visualizations for initial (open arrow) and final (double circle) states -* Highlight final states in GraphViz drawings - -== 0.6.2 / 2009-03-08 - -* Make it easier to override generated instance / class methods - -== 0.6.1 / 2009-03-07 - -* Add i18n support for ActiveRecord validation errors -* Add a validation error when failing to transition for ActiveRecord / DataMapper / Sequel integrations - -== 0.6.0 / 2009-03-03 - -* Allow multiple conditions for callbacks / class behaviors -* Add support for state-driven class behavior with :if/:unless options -* Alias Machine#event as Machine#on -* Fix nil from/to states not being handled properly -* Simplify hooking callbacks into loopbacks -* Add simplified transition/callback requirement syntax - -== 0.5.2 / 2009-02-17 - -* Improve pretty-print of events -* Simplify state/event matching design, improving guard performance by 30% -* Add better error notification when conflicting guard options are defined -* Fix scope name pluralization not being applied correctly - -== 0.5.1 / 2009-02-11 - -* Allow states to be drawn as ellipses to accommodate long names -* Fix rake tasks not being registered in Rails/Merb applications -* Never automatically define machine attribute accessors when using an integration - -== 0.5.0 / 2009-01-11 - -* Add to_name and from_name to transition objects -* Add nicely formatted #inspect for transitions -* Fix ActiveRecord integrations failing when the database doesn't exist yet -* Fix states not being drawn in GraphViz graphs in the correct order -* Add nicely formatted #inspect for states and events -* Simplify machine context-switching -* Store events/states in enumerable node collections -* No longer allow subclasses to change the integration -* Move fire! action logic into the Event class (no longer calls fire action on the object) -* Allow states in subclasses to have different values -* Recommend that all states be referenced as symbols instead of strings -* All states must now be named (and can be associated with other value types) -* Add support for customizing the actual stored value for a state -* Add compatibility with Ruby 1.9+ - -== 0.4.3 / 2008-12-28 - -* Allow dm-observer integration to be optional -* Fix non-lambda callbacks not working for DataMapper/Sequel - -== 0.4.2 / 2008-12-28 - -* Fix graphs not being drawn the same way consistently -* Add support for sharing transitions across multiple events -* Add support for state-driven behavior -* Simplify initialize hooks, requiring super to be called instead -* Add :namespace option for generated state predicates / event methods - -== 0.4.1 / 2008-12-16 - -* Fix nil states not being handled properly in guards, known states, or visualizations -* Fix the same node being used for different dynamic states in GraphViz output -* Always include initial state in the list of known states even if it's dynamic -* Use consistent naming scheme for dynamic states in GraphViz output -* Allow blocks to be directly passed into machine class -* Fix attribute predicates not working on attributes that represent columns in ActiveRecord - -== 0.4.0 / 2008-12-14 - -* Remove the PluginAWeek namespace -* Add generic attribute predicate (e.g. "#{attribute}?(state_name)") and state predicates (e.g. "#{state}?") -* Add Sequel support -* Fix aliasing :initialize on ActiveRecord models causing warnings when the environment is reloaded -* Fix ActiveRecord state machines trying to query the database on unmigrated models -* Fix initial states not getting set when the current value is an empty string [Aaron Gibralter] -* Add rake tasks for generating graphviz files for state machines [Nate Murray] -* Fix initial state not being included in list of known states -* Add other_states directive for defining additional states not referenced in transitions or callbacks [Pete Forde] -* Add next_#{event}_transition for getting the next transition that would be performed if the event were invoked -* Add the ability to override the pluralized name of an attribute for creating scopes -* Add the ability to halt callback chains by: throw :halt -* Add support for dynamic to states in transitions (e.g. :to => lambda {Time.now}) -* Add support for using real blocks in before_transition/after_transition calls instead of using the :do option -* Add DataMapper support -* Include states referenced in transition callbacks in the list of a machine's known states -* Only generate the known states for a machine on demand, rather than calculating beforehand -* Add the ability to skip state change actions during a transition (e.g. vehicle.ignite(false)) -* Add the ability for the state change action (e.g. +save+ for ActiveRecord) to be configurable -* Allow state machines to be defined on *any* Ruby class, not just ActiveRecord (removes all external dependencies) -* Refactor transitions, guards, and callbacks for better organization/design -* Use a class containing the transition context in callbacks, rather than an ordered list of each individual attribute -* Add without_#{attribute} named scopes (opposite of the existing with_#{attribute} named scopes) [Sean O'Brien] - -== 0.3.1 / 2008-10-26 - -* Fix the initial state not getting set when the state attribute is mass-assigned but protected -* Change how the base module is included to prevent namespacing conflicts - -== 0.3.0 / 2008-09-07 - -* No longer allow additional arguments to be passed into event actions -* Add support for can_#{event}? for checking whether an event can be fired based on the current state of the record -* Don't use callbacks for performing transitions -* Fix state machines in subclasses not knowing what states/events/transitions were defined by superclasses -* Replace all before/after_exit/enter/loopback callback hooks and :before/:after options for events with before_transition/after_transition callbacks, e.g. - - before_transition :from => 'parked', :do => :lock_doors # was before_exit :parked, :lock_doors - after_transition :on => 'ignite', :do => :turn_on_radio # was event :ignite, :after => :turn_on_radio do - -* Always save when an event is fired even if it results in a loopback [Jürgen Strobel] -* Ensure initial state callbacks are invoked in the proper order when an event is fired on a new record -* Add before_loopback and after_loopback hooks [Jürgen Strobel] - -== 0.2.1 / 2008-07-05 - -* Add more descriptive exceptions -* Assume the default state attribute is "state" if one is not provided -* Add :except_from option for transitions if you want to blacklist states -* Add PluginAWeek::StateMachine::Machine#states -* Add PluginAWeek::StateMachine::Event#transitions -* Allow creating transitions with no from state (effectively allowing the transition for *any* from state) -* Reduce the number of objects created for each transition - -== 0.2.0 / 2008-06-29 - -* Add a non-bang version of events (e.g. park) that will return a boolean value for success -* Raise an exception if the bang version of events are used (e.g. park!) and no transition is successful -* Change callbacks to act a little more like ActiveRecord -* Avoid using string evaluation for dynamic methods - -== 0.1.1 / 2008-06-22 - -* Remove log files from gems - -== 0.1.0 / 2008-05-05 - -* Completely rewritten from scratch -* Renamed to state_machine -* Removed database dependencies -* Removed models in favor of an attribute-agnostic design -* Use ActiveSupport::Callbacks instead of eval_call -* Remove dry_transaction_rollbacks dependencies -* Added functional tests -* Updated documentation - -== 0.0.1 / 2007-09-26 - -* Add dependency on custom_callbacks -* Move test fixtures out of the test application root directory -* Improve documentation -* Remove the StateExtension module in favor of adding singleton methods to the stateful class -* Convert dos newlines to unix newlines -* Fix error message when a given event can't be found in the database -* Add before_#{action} and #{action} callbacks when an event is performed -* All state and event callbacks can now explicitly return false in order to cancel the action -* Refactor ActiveState callback creation -* Refactor unit tests so that they use mock classes instead of themselves -* Allow force_reload option to be set in the state association -* Don't save the entire model when updating the state_id -* Raise exception if a class tries to define a state more than once -* Add tests for PluginAWeek::Has::States::ActiveState -* Refactor active state/active event creation -* Fix owner_type not being set correctly in active states/events of subclasses -* Allow subclasses to override the initial state -* Fix problem with migrations using default null when column cannot be null -* Moved deadline support into a separate plugin (has_state_deadlines). -* Added many more unit tests. -* Simplified many of the interfaces for maintainability. -* Added support for turning off recording state changes. -* Removed the short_description and long_description columns, in favor of an optional human_name column. -* Fixed not overriding the correct equality methods in the StateTransition class. -* Added to_sym to State and Event. -* State#name and Event#name now return the string version of the name instead of the symbol version. -* Added State#human_name and Event#human_name to automatically figure out what the human name is if it isn't specified in the table. -* Updated manual rollbacks to use the new Rails edge api (ActiveRecord::Rollback exception). -* Moved StateExtension class into a separate file in order to help keep the has_state files clean. -* Renamed InvalidState and InvalidEvent exceptions to StateNotFound and EventNotFound in order to follow the ActiveRecord convention (i.e. RecordNotFound). -* Added StateNotActive and EventNotActive exceptions to help differentiate between states which don't exist and states which weren't defined in the class. -* Added support for defining callbacks like so: - - def before_exit_parked - end - - def after_enter_idling - end - -* Added support for defining callbacks using class methods: - - before_exit_parked :fasten_seatbelt - -* Added event callbacks after the transition has occurred (e.g. after_park) -* State callbacks no longer receive any of the arguments that were provided in the event action -* Updated license to include our names. diff --git a/vendor/plugins/state_machine-0.6.3/LICENSE b/vendor/plugins/state_machine-0.6.3/LICENSE deleted file mode 100644 index 2619831..0000000 --- a/vendor/plugins/state_machine-0.6.3/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2006-2009 Aaron Pfefier - -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. diff --git a/vendor/plugins/state_machine-0.6.3/README.rdoc b/vendor/plugins/state_machine-0.6.3/README.rdoc deleted file mode 100644 index 342d737..0000000 --- a/vendor/plugins/state_machine-0.6.3/README.rdoc +++ /dev/null @@ -1,454 +0,0 @@ -== state_machine - -+state_machine+ adds support for creating state machines for attributes on any -Ruby class. - -== Resources - -API - -* http://api.pluginaweek.org/state_machine - -Bugs - -* http://pluginaweek.lighthouseapp.com/projects/13288-state_machine - -Development - -* http://github.com/pluginaweek/state_machine - -Source - -* git://github.com/pluginaweek/state_machine.git - -== Description - -State machines make it dead-simple to manage the behavior of a class. Too often, -the state of an object is kept by creating multiple boolean attributes and -deciding how to behave based on the values. This can become cumbersome and -difficult to maintain when the complexity of your class starts to increase. - -+state_machine+ simplifies this design by introducing the various parts of a real -state machine, including states, events, transitions, and callbacks. However, -the api is designed to be so simple you don't even need to know what a -state machine is :) - -Some brief, high-level features include: -* Defining state machines on any Ruby class -* Multiple state machines on a single class -* Namespaced state machines -* before/after transition hooks with explicit transition requirements -* ActiveRecord integration -* DataMapper integration -* Sequel integration -* State predicates -* State-driven instance / class behavior -* State values of any data type -* Dynamically-generated state values -* Inheritance -* Internationalization -* GraphViz visualization creator - -Examples of the usage patterns for some of the above features are shown below. -You can find much more detailed documentation in the actual API. - -== Usage - -=== Example - -Below is an example of many of the features offered by this plugin, including: -* Initial states -* Namespaced states -* Transition callbacks -* Conditional transitions -* State-driven instance behavior -* Customized state values - -Class definition: - - class Vehicle - attr_accessor :seatbelt_on - - state_machine :state, :initial => :parked do - before_transition :parked => any - :parked, :do => :put_on_seatbelt - - after_transition :on => :crash, :do => :tow - after_transition :on => :repair, :do => :fix - after_transition any => :parked do |vehicle, transition| - vehicle.seatbelt_on = false - end - - event :park do - transition [:idling, :first_gear] => :parked - end - - event :ignite do - transition :stalled => same, :parked => :idling - end - - event :idle do - transition :first_gear => :idling - end - - event :shift_up do - transition :idling => :first_gear, :first_gear => :second_gear, :second_gear => :third_gear - end - - event :shift_down do - transition :third_gear => :second_gear, :second_gear => :first_gear - end - - event :crash do - transition all - [:parked, :stalled] => :stalled, :unless => :auto_shop_busy? - end - - event :repair do - transition :stalled => :parked, :if => :auto_shop_busy? - end - - state :parked do - def speed - 0 - end - end - - state :idling, :first_gear do - def speed - 10 - end - end - - state :second_gear do - def speed - 20 - end - end - end - - state_machine :hood_state, :initial => :closed, :namespace => 'hood' do - event :open do - transition all => :opened - end - - event :close do - transition all => :closed - end - - state :opened, :value => 1 - state :closed, :value => 0 - end - - def initialize - @seatbelt_on = false - super() # NOTE: This *must* be called, otherwise states won't get initialized - end - - def put_on_seatbelt - @seatbelt_on = true - end - - def auto_shop_busy? - false - end - - def tow - # tow the vehicle - end - - def fix - # get the vehicle fixed by a mechanic - end - end - -Using the above class as an example, you can interact with the state machine -like so: - - vehicle = Vehicle.new # => #<Vehicle:0xb7cf4eac @state="parked", @seatbelt_on=false> - vehicle.state # => "parked" - vehicle.state_name # => :parked - vehicle.parked? # => true - vehicle.can_ignite? # => true - vehicle.next_ignite_transition # => #<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling> - vehicle.speed # => 0 - - vehicle.ignite # => true - vehicle.parked? # => false - vehicle.idling? # => true - vehicle.speed # => 10 - vehicle # => #<Vehicle:0xb7cf4eac @state="idling", @seatbelt_on=true> - - vehicle.shift_up # => true - vehicle.speed # => 10 - vehicle # => #<Vehicle:0xb7cf4eac @state="first_gear", @seatbelt_on=true> - - vehicle.shift_up # => true - vehicle.speed # => 20 - vehicle # => #<Vehicle:0xb7cf4eac @state="second_gear", @seatbelt_on=true> - - # The bang (!) operator can raise exceptions if the event fails - vehicle.park! # => StateMachine::InvalidTransition: Cannot transition state via :park from :second_gear - - # Generic state predicates can raise exceptions if the value does not exist - vehicle.state?(:parked) # => true - vehicle.state?(:invalid) # => ArgumentError: :invalid is an invalid name - - # Namespaced machines have uniquely-generated methods - vehicle.hood_state # => 0 - vehicle.hood_state_name # => :closed - - vehicle.can_open_hood? # => true - vehicle.open_hood # => true - vehicle.hood_state # => 1 - vehicle.hood_state_name # => :opened - vehicle.can_close_hood? # => true - - vehicle.hood_opened? # => true - vehicle.hood_closed? # => false - -*Note* the comment made on the +initialize+ method in the class. In order for -state machine attributes to be properly initialized, <tt>super()</tt> must be called. -See StateMachine::MacroMethods for more information about this. - -== Integrations - -In addition to being able to define state machines on all Ruby classes, a set of -out-of-the-box integrations are available for some of the more popular Ruby -libraries. These integrations add library-specific behavior, allowing for state -machines to work more tightly with the conventions defined by those libraries. - -The integrations currently available include: -* ActiveRecord models -* DataMapper resources -* Sequel models - -A brief overview of these integrations is described below. - -=== ActiveRecord - -The ActiveRecord integration adds support for database transactions, automatically -saving the record, named scopes, validation errors, and observers. For example, - - class Vehicle < ActiveRecord::Base - state_machine :initial => :parked do - before_transition :parked => any - :parked, :do => :put_on_seatbelt - after_transition any => :parked do |vehicle, transition| - vehicle.seatbelt = 'off' - end - - event :ignite do - transition :parked => :idling - end - - state :first_gear, :second_gear do - validates_presence_of :seatbelt_on - end - end - - def put_on_seatbelt - ... - end - end - - class VehicleObserver < ActiveRecord::Observer - # Callback for :ignite event *before* the transition is performed - def before_ignite(vehicle, transition) - # log message - end - - # Generic transition callback *before* the transition is performed - def after_transition(vehicle, transition) - Audit.log(vehicle, transition) - end - end - -For more information about the various behaviors added for ActiveRecord state -machines, see StateMachine::Integrations::ActiveRecord. - -=== DataMapper - -Like the ActiveRecord integration, the DataMapper integration adds support for -database transactions, automatically saving the record, named scopes, Extlib-like -callbacks, validation errors, and observers. For example, - - class Vehicle - include DataMapper::Resource - - property :id, Serial - property :state, String - - state_machine :initial => :parked do - before_transition :parked => any - :parked, :do => :put_on_seatbelt - after_transition any => :parked do |transition| - self.seatbelt = 'off' # self is the record - end - - event :ignite do - transition :parked => :idling - end - - state :first_gear, :second_gear do - validates_present :seatbelt_on - end - end - - def put_on_seatbelt - ... - end - end - - class VehicleObserver - include DataMapper::Observer - - observe Vehicle - - # Callback for :ignite event *before* the transition is performed - before_transition :on => :ignite do |transition| - # log message (self is the record) - end - - # Generic transition callback *before* the transition is performed - after_transition do |transition, saved| - Audit.log(self, transition) if saved # self is the record - end - end - -*Note* that the DataMapper::Observer integration is optional and only available -when the dm-observer library is installed. - -For more information about the various behaviors added for DataMapper state -machines, see StateMachine::Integrations::DataMapper. - -=== Sequel - -Like the ActiveRecord integration, the Sequel integration adds support for -database transactions, automatically saving the record, named scopes, validation -errors and callbacks. For example, - - class Vehicle < Sequel::Model - state_machine :initial => :parked do - before_transition :parked => any - :parked, :do => :put_on_seatbelt - after_transition any => :parked do |transition| - self.seatbelt = 'off' # self is the record - end - - event :ignite do - transition :parked => :idling - end - - state :first_gear, :second_gear do - validates_presence_of :seatbelt_on - end - end - - def put_on_seatbelt - ... - end - end - -For more information about the various behaviors added for Sequel state -machines, see StateMachine::Integrations::Sequel. - -== Compatibility - -Although state_machine introduces a simplified syntax, it still remains -backwards compatible with previous versions and other state-related libraries. -For example, transitions and callbacks can continue to be defined like so: - - class Vehicle - state_machine :initial => :parked do - before_transition :from => :parked, :except_to => :parked, :do => :put_on_seatbelt - after_transition :to => :parked do |transition| - self.seatbelt = 'off' # self is the record - end - - event :ignite do - transition :from => :parked, :to => :idling - end - end - end - -Although this verbose syntax will most likely always be supported, it is -recommended that any state machines eventually migrate to the syntax introduced -in version 0.6.0. - -== Tools - -=== Generating graphs - -This library comes with built-in support for generating di-graphs based on the -events, states, and transitions defined for a state machine using GraphViz[http://www.graphviz.org]. -This requires that both the <tt>ruby-graphviz</tt> gem and graphviz library be -installed on the system. - -==== Examples - -To generate a graph for a specific file / class: - - rake state_machine:draw FILE=vehicle.rb CLASS=Vehicle - -To save files to a specific path: - - rake state_machine:draw FILE=vehicle.rb CLASS=Vehicle TARGET=files - -To customize the image format / orientation: - - rake state_machine:draw FILE=vehicle.rb CLASS=Vehicle FORMAT=jpg ORIENTATION=landscape - -To generate multiple state machine graphs: - - rake state_machine:draw FILE=vehicle.rb,car.rb CLASS=Vehicle,Car - -*Note* that this will generate a different file for every state machine defined -in the class. The generated files will use an output filename of the format -#{class_name}_#{attribute}.#{format}. - -For examples of actual images generated using this task, see those under the -examples folder. - -==== Ruby on Rails Integration - -There is a special integration Rake task for generating state machines for -classes used in a Ruby on Rails application. This task will load the application -environment, meaning that it's unnecessary to specify the actual file to load. - -For example, - - rake state_machine:draw:rails CLASS=Vehicle - -==== Merb Integration - -Like Ruby on Rails, there is a special integration Rake task for generating -state machines for classes used in a Merb application. This task will load the -application environment, meaning that it's unnecessary to specify the actual -files to load. - -For example, - - rake state_machine:draw:merb CLASS=Vehicle - -=== Interactive graphs - -Jean Bovet - {Visual Automata Simulator}[http://www.cs.usfca.edu/~jbovet/vas.html]. -This is a great tool for "simulating, visualizing and transforming finite state -automata and Turing Machines". This tool can help in the creation of states and -events for your models. It is cross-platform, written in Java. - -== Testing - -To run the entire test suite (will test ActiveRecord, DataMapper, and Sequel -integrations if the proper dependencies are available): - - rake test - -Target specific versions of integrations like so: - - rake test AR_VERSION=2.1.0 DM_VERSION=0.9.0 SEQUEL_VERSION=2.8.0 - -== Dependencies - -By default, there are no dependencies. If using specific integrations, those -dependencies are listed below. - -* ActiveRecord[http://rubyonrails.org] integration: 2.1.0 or later -* DataMapper[http://datamapper.org] integration: 0.9.0 or later -* Sequel[http://sequel.rubyforge.org] integration: 2.8.0 or later diff --git a/vendor/plugins/state_machine-0.6.3/Rakefile b/vendor/plugins/state_machine-0.6.3/Rakefile deleted file mode 100644 index be95d1b..0000000 --- a/vendor/plugins/state_machine-0.6.3/Rakefile +++ /dev/null @@ -1,90 +0,0 @@ -require 'rake/testtask' -require 'rake/rdoctask' -require 'rake/gempackagetask' -require 'rake/contrib/sshpublisher' - -spec = Gem::Specification.new do |s| - s.name = 'state_machine' - s.version = '0.6.3' - s.platform = Gem::Platform::RUBY - s.summary = 'Adds support for creating state machines for attributes on any Ruby class' - - s.files = FileList['{examples,lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}'] - s.require_path = 'lib' - s.has_rdoc = true - s.test_files = Dir['test/**/*_test.rb'] - - s.author = 'Aaron Pfeifer' - s.email = 'aaron@pluginaweek.org' - s.homepage = 'http://www.pluginaweek.org' - s.rubyforge_project = 'pluginaweek' -end - -desc 'Default: run all tests.' -task :default => :test - -desc "Test the #{spec.name} plugin." -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.test_files = spec.test_files - t.verbose = true -end - -begin - require 'rcov/rcovtask' - namespace :test do - desc "Test the #{spec.name} plugin with Rcov." - Rcov::RcovTask.new(:rcov) do |t| - t.libs << 'lib' - t.test_files = spec.test_files - t.rcov_opts << '--exclude="^(?!lib/)"' - t.verbose = true - end - end -rescue LoadError -end - -desc "Generate documentation for the #{spec.name} plugin." -Rake::RDocTask.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = spec.name - rdoc.template = '../rdoc_template.rb' - rdoc.options << '--line-numbers' << '--inline-source' - rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb') -end - -Rake::GemPackageTask.new(spec) do |p| - p.gem_spec = spec - p.need_tar = true - p.need_zip = true -end - -desc 'Publish the beta gem.' -task :pgem => [:package] do - Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload -end - -desc 'Publish the API documentation.' -task :pdoc => [:rdoc] do - Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload -end - -desc 'Publish the API docs and gem' -task :publish => [:pgem, :pdoc, :release] - -desc 'Publish the release files to RubyForge.' -task :release => [:gem, :package] do - require 'rubyforge' - - ruby_forge = RubyForge.new.configure - ruby_forge.login - - %w(gem tgz zip).each do |ext| - file = "pkg/#{spec.name}-#{spec.version}.#{ext}" - puts "Releasing #{File.basename(file)}..." - - ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file) - end -end - -Dir['tasks/**/*.rake'].each {|rake| load rake} diff --git a/vendor/plugins/state_machine-0.6.3/examples/AutoShop_state.png b/vendor/plugins/state_machine-0.6.3/examples/AutoShop_state.png Binary files differdeleted file mode 100644 index 5ab016e..0000000 --- a/vendor/plugins/state_machine-0.6.3/examples/AutoShop_state.png +++ /dev/null diff --git a/vendor/plugins/state_machine-0.6.3/examples/Car_state.png b/vendor/plugins/state_machine-0.6.3/examples/Car_state.png Binary files differdeleted file mode 100644 index 64be7de..0000000 --- a/vendor/plugins/state_machine-0.6.3/examples/Car_state.png +++ /dev/null diff --git a/vendor/plugins/state_machine-0.6.3/examples/TrafficLight_state.png b/vendor/plugins/state_machine-0.6.3/examples/TrafficLight_state.png Binary files differdeleted file mode 100644 index 3b32ac4..0000000 --- a/vendor/plugins/state_machine-0.6.3/examples/TrafficLight_state.png +++ /dev/null diff --git a/vendor/plugins/state_machine-0.6.3/examples/Vehicle_state.png b/vendor/plugins/state_machine-0.6.3/examples/Vehicle_state.png Binary files differdeleted file mode 100644 index ab36b64..0000000 --- a/vendor/plugins/state_machine-0.6.3/examples/Vehicle_state.png +++ /dev/null diff --git a/vendor/plugins/state_machine-0.6.3/examples/auto_shop.rb b/vendor/plugins/state_machine-0.6.3/examples/auto_shop.rb deleted file mode 100644 index c369f56..0000000 --- a/vendor/plugins/state_machine-0.6.3/examples/auto_shop.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AutoShop - state_machine :initial => :available do - event :tow_vehicle do - transition :available => :busy - end - - event :fix_vehicle do - transition :busy => :available - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/examples/car.rb b/vendor/plugins/state_machine-0.6.3/examples/car.rb deleted file mode 100644 index 948c7ec..0000000 --- a/vendor/plugins/state_machine-0.6.3/examples/car.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Car < Vehicle - state_machine do - event :reverse do - transition [:parked, :idling, :first_gear] => :backing_up - end - - event :park do - transition :backing_up => :parked - end - - event :idle do - transition :backing_up => :idling - end - - event :shift_up do - transition :backing_up => :first_gear - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/examples/traffic_light.rb b/vendor/plugins/state_machine-0.6.3/examples/traffic_light.rb deleted file mode 100644 index febb9ab..0000000 --- a/vendor/plugins/state_machine-0.6.3/examples/traffic_light.rb +++ /dev/null @@ -1,7 +0,0 @@ -class TrafficLight - state_machine :initial => :stop do - event :cycle do - transition :stop => :proceed, :proceed => :caution, :caution => :stop - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/examples/vehicle.rb b/vendor/plugins/state_machine-0.6.3/examples/vehicle.rb deleted file mode 100644 index 4dff67e..0000000 --- a/vendor/plugins/state_machine-0.6.3/examples/vehicle.rb +++ /dev/null @@ -1,31 +0,0 @@ -class Vehicle - state_machine :initial => :parked do - event :park do - transition [:idling, :first_gear] => :parked - end - - event :ignite do - transition :stalled => same, :parked => :idling - end - - event :idle do - transition :first_gear => :idling - end - - event :shift_up do - transition :idling => :first_gear, :first_gear => :second_gear, :second_gear => :third_gear - end - - event :shift_down do - transition :third_gear => :second_gear, :second_gear => :first_gear - end - - event :crash do - transition [:first_gear, :second_gear, :third_gear] => :stalled - end - - event :repair do - transition :stalled => :parked - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/init.rb b/vendor/plugins/state_machine-0.6.3/init.rb deleted file mode 100644 index 5b3ef9c..0000000 --- a/vendor/plugins/state_machine-0.6.3/init.rb +++ /dev/null @@ -1 +0,0 @@ -require 'state_machine' diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine.rb deleted file mode 100644 index 3fbee12..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine.rb +++ /dev/null @@ -1,319 +0,0 @@ -require 'state_machine/machine' - -# A state machine is a model of behavior composed of states, events, and -# transitions. This helper adds support for defining this type of -# functionality on any Ruby class. -module StateMachine - module MacroMethods - # Creates a new state machine for the given attribute. The default - # attribute, if not specified, is <tt>:state</tt>. - # - # Configuration options: - # * <tt>:initial</tt> - The initial state of the attribute. This can be a - # static state or a lambda block which will be evaluated at runtime - # (e.g. lambda {|vehicle| vehicle.speed == 0 ? :parked : :idling}). - # Default is nil. - # * <tt>:action</tt> - The action to invoke when an object transitions. - # Default is nil unless otherwise specified by the configured integration. - # * <tt>:plural</tt> - The pluralized name of the attribute. By default, - # this will attempt to call +pluralize+ on the attribute, otherwise - # an "s" is appended. This is used for generating scopes. - # * <tt>:namespace</tt> - The name to use for namespacing all generated - # instance methods (e.g. "heater" would generate :turn_on_heater and - # :turn_off_header for the :turn_on/:turn_off events). Default is nil. - # * <tt>:integration</tt> - The name of the integration to use for adding - # library-specific behavior to the machine. Built-in integrations include - # :data_mapper, :active_record, and :sequel. By default, this is - # determined automatically. - # - # This also expects a block which will be used to actually configure the - # states, events and transitions for the state machine. *Note* that this - # block will be executed within the context of the state machine. As a - # result, you will not be able to access any class methods unless you refer - # to them directly (i.e. specifying the class name). - # - # For examples on the types of configured state machines and blocks, see - # the section below. - # - # == Examples - # - # With the default attribute and no configuration: - # - # class Vehicle - # state_machine do - # event :park do - # ... - # end - # end - # end - # - # The above example will define a state machine for the +state+ attribute - # on the class. Every vehicle will start without an initial state. - # - # With a custom attribute: - # - # class Vehicle - # state_machine :status do - # ... - # end - # end - # - # With a static initial state: - # - # class Vehicle - # state_machine :status, :initial => :parked do - # ... - # end - # end - # - # With a dynamic initial state: - # - # class Vehicle - # state_machine :status, :initial => lambda {|vehicle| vehicle.speed == 0 ? :parked : :idling} do - # ... - # end - # end - # - # == Attribute accessor - # - # The attribute for each machine stores the value for the current state - # of the machine. In order to access this value and modify it during - # transitions, a reader/writer must be available. The following methods - # will be automatically generated if they are not already defined - # (assuming the attribute is called +state+): - # * <tt>state</tt> - Gets the current value for the attribute - # * <tt>state=(value)</tt> - Sets the current value for the attribute - # * <tt>state?(name)</tt> - Checks the given state name against the current - # state. If the name is not a known state, then an ArgumentError is raised. - # * <tt>state_name</tt> - Gets the name of the state for the current value - # - # For example, the following machine definition will not generate the reader - # or writer methods since the class has already defined an attribute - # accessor: - # - # class Vehicle - # attr_accessor :state - # - # state_machine do - # ... - # end - # end - # - # On the other hand, the following state machine will define *both* a - # reader and writer method, which is functionally equivalent to the - # example above: - # - # class Vehicle - # state_machine do - # ... - # end - # end - # - # == Attribute initialization - # - # For most classes, the initial values for state machine attributes are - # automatically assigned when a new object is created. However, this - # behavior will *not* work if the class defines an +initialize+ method - # without properly calling +super+. - # - # For example, - # - # class Vehicle - # state_machine :state, :initial => :parked do - # ... - # end - # end - # - # vehicle = Vehicle.new # => #<Vehicle:0xb7c8dbf8 @state="parked"> - # vehicle.state # => "parked" - # - # In the above example, no +initialize+ method is defined. As a result, - # the default behavior of initializing the state machine attributes is used. - # - # In the following example, a custom +initialize+ method is defined: - # - # class Vehicle - # state_machine :state, :initial => :parked do - # ... - # end - # - # def initialize - # end - # end - # - # vehicle = Vehicle.new # => #<Vehicle:0xb7c77678> - # vehicle.state # => nil - # - # Since the +initialize+ method is defined, the state machine attributes - # never get initialized. In order to ensure that all initialization hooks - # are called, the custom method *must* call +super+ without any arguments - # like so: - # - # class Vehicle - # state_machine :state, :initial => :parked do - # ... - # end - # - # def initialize(attributes = {}) - # ... - # super() - # end - # end - # - # vehicle = Vehicle.new # => #<Vehicle:0xb7c8dbf8 @state="parked"> - # vehicle.state # => "parked" - # - # Because of the way the inclusion of modules works in Ruby, calling - # <tt>super()</tt> will not only call the superclass's +initialize+, but - # also +initialize+ on all included modules. This allows the original state - # machine hook to get called properly. - # - # If you want to avoid calling the superclass's constructor, but still want - # to initialize the state machine attributes: - # - # class Vehicle - # state_machine :state, :initial => :parked do - # ... - # end - # - # def initialize(attributes = {}) - # ... - # initialize_state_machines - # end - # end - # - # vehicle = Vehicle.new # => #<Vehicle:0xb7c8dbf8 @state="parked"> - # vehicle.state # => "parked" - # - # == States - # - # All of the valid states for the machine are automatically tracked based - # on the events, transitions, and callbacks defined for the machine. If - # there are additional states that are never referenced, these should be - # explicitly added using the StateMachine::Machine#state or - # StateMachine::Machine#other_states helpers. - # - # When a new state is defined, a predicate method for that state is - # generated on the class. For example, - # - # class Vehicle - # state_machine :initial => :parked do - # event :ignite do - # transition all => :idling - # end - # end - # end - # - # ...will generate the following instance methods (assuming they're not - # already defined in the class): - # * <tt>parked?</tt> - # * <tt>idling?</tt> - # - # Each predicate method will return true if it matches the object's - # current state. Otherwise, it will return false. - # - # When a namespace is configured for a state machine, the name will be - # prepended to each state predicate like so: - # * <tt>car_parked?</tt> - # * <tt>car_idling?</tt> - # - # == Events and Transitions - # - # For more information about how to configure an event and its associated - # transitions, see StateMachine::Machine#event. - # - # == Defining callbacks - # - # Within the +state_machine+ block, you can also define callbacks for - # transitions. For more information about defining these callbacks, - # see StateMachine::Machine#before_transition and - # StateMachine::Machine#after_transition. - # - # == Namespaces - # - # When a namespace is configured for a state machine, the name provided will - # be used in generating the instance methods for interacting with - # events/states in the machine. This is particularly useful when a class - # has multiple state machines and it would be difficult to differentiate - # between the various states / events. - # - # For example, - # - # class Vehicle - # state_machine :heater_state, :initial => :off :namespace => 'heater' do - # event :turn_on do - # transition all => :on - # end - # - # event :turn_off do - # transition all => :off - # end - # end - # - # state_machine :hood_state, :initial => :closed, :namespace => 'hood' do - # event :open do - # transition all => :opened - # end - # - # event :close do - # transition all => :closed - # end - # end - # end - # - # The above class defines two state machines: +heater_state+ and +hood_state+. - # For the +heater_state+ machine, the following methods are generated since - # it's namespaced by "heater": - # * <tt>can_turn_on_heater?</tt> - # * <tt>turn_on_heater</tt> - # * ... - # * <tt>can_turn_off_heater?</tt> - # * <tt>turn_off_heater</tt> - # * .. - # * <tt>heater_off?</tt> - # * <tt>heater_on?</tt> - # - # As shown, each method is unique to the state machine so that the states - # and events don't conflict. The same goes for the +hood_state+ machine: - # * <tt>can_open_hood?</tt> - # * <tt>open_hood</tt> - # * ... - # * <tt>can_close_hood?</tt> - # * <tt>close_hood</tt> - # * .. - # * <tt>hood_open?</tt> - # * <tt>hood_closed?</tt> - # - # == Scopes - # - # For integrations that support it, a group of default scope filters will - # be automatically created for assisting in finding objects that have the - # attribute set to the value for a given set of states. - # - # For example, - # - # Vehicle.with_state(:parked) # => Finds all vehicles where the state is parked - # Vehicle.with_states(:parked, :idling) # => Finds all vehicles where the state is either parked or idling - # - # Vehicle.without_state(:parked) # => Finds all vehicles where the state is *not* parked - # Vehicle.without_states(:parked, :idling) # => Finds all vehicles where the state is *not* parked or idling - # - # *Note* that if class methods already exist with those names (i.e. - # :with_state, :with_states, :without_state, or :without_states), then a - # scope will not be defined for that name. - # - # See StateMachine::Machine for more information about using - # integrations and the individual integration docs for information about - # the actual scopes that are generated. - def state_machine(*args, &block) - StateMachine::Machine.find_or_create(self, *args, &block) - end - end -end - -Class.class_eval do - include StateMachine::MacroMethods -end - -# Register rake tasks for supported libraries -Merb::Plugins.add_rakefiles("#{File.dirname(__FILE__)}/../tasks/state_machine") if defined?(Merb::Plugins) diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/assertions.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/assertions.rb deleted file mode 100644 index 9a95a96..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/assertions.rb +++ /dev/null @@ -1,37 +0,0 @@ -module StateMachine - # Provides a set of helper methods for making assertions about the content of - # various objects - module Assertions - # Validates that all keys in the given hash *only* includes the specified - # valid keys. If any invalid keys are found, an ArgumentError will be - # raised. - # - # == Examples - # - # options = {:name => 'John Smith', :age => 30} - # - # assert_valid_keys(options, :name) # => ArgumentError: Invalid key(s): age - # assert_valid_keys(options, 'name', 'age') # => ArgumentError: Invalid key(s): age, name - # assert_valid_keys(options, :name, :age) # => nil - def assert_valid_keys(hash, *valid_keys) - invalid_keys = hash.keys - valid_keys - raise ArgumentError, "Invalid key(s): #{invalid_keys.join(', ')}" unless invalid_keys.empty? - end - - # Validates that at *most* one of a set of exclusive keys is included in - # the given hash. If more than one key is found, an ArgumentError will be - # raised. - # - # == Examples - # - # options = {:only => :on, :except => :off} - # assert_exclusive_keys(options, :only) # => nil - # assert_exclusive_keys(options, :except) # => nil - # assert_exclusive_keys(options, :only, :except) # => ArgumentError: Conflicting keys: only, except - # assert_exclusive_keys(options, :only, :except, :with) # => ArgumentError: Conflicting keys: only, except - def assert_exclusive_keys(hash, *exclusive_keys) - conflicting_keys = exclusive_keys & hash.keys - raise ArgumentError, "Conflicting keys: #{conflicting_keys.join(', ')}" unless conflicting_keys.length <= 1 - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/callback.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/callback.rb deleted file mode 100644 index 3af4413..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/callback.rb +++ /dev/null @@ -1,175 +0,0 @@ -require 'state_machine/guard' -require 'state_machine/eval_helpers' - -module StateMachine - # Callbacks represent hooks into objects that allow you to trigger logic - # before or after a specific transition occurs. - class Callback - include EvalHelpers - - class << self - # Determines whether to automatically bind the callback to the object being - # transitioned. This only applies to callbacks that are defined as - # lambda blocks (or Procs). Some integrations, such as DataMapper, handle - # callbacks by executing them bound to the object involved, while other - # integrations, such as ActiveRecord, pass the object as an argument to - # the callback. This can be configured on an application-wide basis by - # setting this configuration to +true+ or +false+. The default value - # is +false+. - # - # *Note* that the DataMapper and Sequel integrations automatically - # configure this value on a per-callback basis, so it does not have to - # be enabled application-wide. - # - # == Examples - # - # When not bound to the object: - # - # class Vehicle - # state_machine do - # before_transition do |vehicle| - # vehicle.set_alarm - # end - # end - # - # def set_alarm - # ... - # end - # end - # - # When bound to the object: - # - # StateMachine::Callback.bind_to_object = true - # - # class Vehicle - # state_machine do - # before_transition do - # self.set_alarm - # end - # end - # - # def set_alarm - # ... - # end - # end - attr_accessor :bind_to_object - end - - # An optional block for determining whether to cancel the callback chain - # based on the return value of the callback. By default, the callback - # chain never cancels based on the return value (i.e. there is no implicit - # terminator). Certain integrations, such as ActiveRecord and Sequel, - # change this default value. - # - # == Examples - # - # Canceling the callback chain without a terminator: - # - # class Vehicle - # state_machine do - # before_transition do |vehicle| - # throw :halt - # end - # end - # end - # - # Canceling the callback chain with a terminator value of +false+: - # - # class Vehicle - # state_machine do - # before_transition do |vehicle| - # false - # end - # end - # end - attr_reader :terminator - - # The guard that determines whether or not this callback can be invoked - # based on the context of the transition. The event, from state, and - # to state must all match in order for the guard to pass. - # - # See StateMachine::Guard for more information. - attr_reader :guard - - # Creates a new callback that can get called based on the configured - # options. - # - # In addition to the possible configuration options for guards, the - # following options can be configured: - # * <tt>:bind_to_object</tt> - Whether to bind the callback to the object involved. - # If set to false, the object will be passed as a parameter instead. - # Default is integration-specific or set to the application default. - # * <tt>:terminator</tt> - A block/proc that determines what callback results - # should cause the callback chain to halt (if not using the default - # <tt>throw :halt</tt> technique). - # - # More information about how those options affect the behavior of the - # callback can be found in their attribute definitions. - def initialize(options = {}, &block) - if options.is_a?(Hash) - @method = options.delete(:do) || block - else - # Only the callback was configured - @method = options - options = {} - end - - # The actual method to invoke must be defined - raise ArgumentError, ':do callback must be specified' unless @method - - # Proxy the method so that it's bound to the object. Note that this only - # applies to lambda callbacks. All other callbacks ignore this option. - bind_to_object = !options.include?(:bind_to_object) && self.class.bind_to_object || options.delete(:bind_to_object) - @method = bound_method(@method) if @method.is_a?(Proc) && bind_to_object - @terminator = options.delete(:terminator) - - @guard = Guard.new(options) - end - - # Gets a list of the states known to this callback by looking at the - # guard's known states - def known_states - guard.known_states - end - - # Runs the callback as long as the transition context matches the guard - # requirements configured for this callback. - def call(object, context = {}, *args) - # Only evaluate the method if the guard passes - if @guard.matches?(object, context) - result = evaluate_method(object, @method, *args) - - # If a terminator has been configured and it matches the result from - # the evaluated method, then the callback chain should be halted - if @terminator && @terminator.call(result) - throw :halt - else - result - end - end - end - - private - # Generates a method that can be bound to the object being transitioned - # when the callback is invoked - def bound_method(block) - # Generate a thread-safe unbound method that can be used on any object - # This is essentially a workaround for not having Ruby 1.9's instance_exec - unbound_method = Object.class_eval do - time = Time.now - method_name = "__bind_#{time.to_i}_#{time.usec}" - define_method(method_name, &block) - method = instance_method(method_name) - remove_method(method_name) - method - end - arity = unbound_method.arity - - # Proxy calls to the method so that the method can be bound *and* - # the arguments are adjusted - lambda do |object, *args| - unbound_method.bind(object).call(*(arity == 0 ? [] : args)) - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/condition_proxy.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/condition_proxy.rb deleted file mode 100644 index 3f00671..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/condition_proxy.rb +++ /dev/null @@ -1,94 +0,0 @@ -require 'state_machine/eval_helpers' - -module StateMachine - # Represents a type of module in which class-level methods are proxied to - # another class, injecting a custom :if condition along with method. - # - # This is used for being able to automatically include conditionals which - # check the current state in class-level methods that have configuration - # options. - # - # == Examples - # - # class Vehicle - # class << self - # attr_accessor :validations - # - # def validate(options, &block) - # validations << options - # end - # end - # - # self.validations = [] - # attr_accessor :state, :simulate - # - # def moving? - # self.class.validations.all? {|validation| validation[:if].call(self)} - # end - # end - # - # In the above class, a simple set of validation behaviors have been defined. - # Each validation consists of a configuration like so: - # - # Vehicle.validate :unless => :simulate - # Vehicle.validate :if => lambda {|vehicle| ...} - # - # In order to scope conditions, a condition proxy can be created to the - # Vehicle class. For example, - # - # proxy = StateMachine::ConditionProxy.new(Vehicle, lambda {|vehicle| vehicle.state == 'first_gear'}) - # proxy.validate(:unless => :simulate) - # - # vehicle = Vehicle.new # => #<Vehicle:0xb7ce491c @simulate=nil, @state=nil> - # vehicle.moving? # => false - # - # vehicle.state = 'first_gear' - # vehicle.moving? # => true - # - # vehicle.simulate = true - # vehicle.moving? # => false - class ConditionProxy < Module - include EvalHelpers - - # Creates a new proxy to the given class, merging in the given condition - def initialize(klass, condition) - @klass = klass - @condition = condition - end - - # Hooks in condition merging to methods that don't exist in this module - def method_missing(*args, &block) - # Get the configuration - if args.last.is_a?(Hash) - options = args.last - else - args << options = {} - end - - # Get any existing condition that may need to be merged - if_condition = options.delete(:if) - unless_condition = options.delete(:unless) - - # Provide scope access to configuration in case the block is evaluated - # within the object instance - proxy = self - proxy_condition = @condition - - # Replace the configuration condition with the one configured for this - # proxy, merging together any existing conditions - options[:if] = lambda do |*args| - # Block may be executed within the context of the actual object, so it'll - # either be the first argument or the executing context - object = args.first || self - - proxy.evaluate_method(object, proxy_condition) && - Array(if_condition).all? {|condition| proxy.evaluate_method(object, condition)} && - !Array(unless_condition).any? {|condition| proxy.evaluate_method(object, condition)} - end - - # Evaluate the method on the original class with the condition proxied - # through - @klass.send(*args, &block) - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/eval_helpers.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/eval_helpers.rb deleted file mode 100644 index 2ddb6bd..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/eval_helpers.rb +++ /dev/null @@ -1,68 +0,0 @@ -module StateMachine - # Provides a set of helper methods for evaluating methods within the context - # of an object. - module EvalHelpers - # Evaluates one of several different types of methods within the context - # of the given object. Methods can be one of the following types: - # * Symbol - # * Method / Proc - # * String - # - # == Examples - # - # Below are examples of the various ways that a method can be evaluated - # on an object: - # - # class Person - # def initialize(name) - # @name = name - # end - # - # def name - # @name - # end - # end - # - # class PersonCallback - # def self.run(person) - # person.name - # end - # end - # - # person = Person.new('John Smith') - # - # evaluate_method(person, :name) # => "John Smith" - # evaluate_method(person, PersonCallback.method(:run)) # => "John Smith" - # evaluate_method(person, Proc.new {|person| person.name}) # => "John Smith" - # evaluate_method(person, lambda {|person| person.name}) # => "John Smith" - # evaluate_method(person, '@name') # => "John Smith" - # - # == Additional arguments - # - # Additional arguments can be passed to the methods being evaluated. If - # the method defines additional arguments other than the object context, - # then all arguments are required. - # - # For example, - # - # person = Person.new('John Smith') - # - # evaluate_method(person, lambda {|person| person.name}, 21) # => "John Smith" - # evaluate_method(person, lambda {|person, age| "#{person.name} is #{age}"}, 21) # => "John Smith is 21" - # evaluate_method(person, lambda {|person, age| "#{person.name} is #{age}"}, 21, 'male') # => ArgumentError: wrong number of arguments (3 for 2) - def evaluate_method(object, method, *args) - case method - when Symbol - method = object.method(method) - method.arity == 0 ? method.call : method.call(*args) - when Proc, Method - args.unshift(object) - [0, 1].include?(method.arity) ? method.call(*args.slice(0, method.arity)) : method.call(*args) - when String - eval(method, object.instance_eval {binding}) - else - raise ArgumentError, 'Methods must be a symbol denoting the method to call, a block to be invoked, or a string to be evaluated' - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/event.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/event.rb deleted file mode 100644 index a1e1109..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/event.rb +++ /dev/null @@ -1,253 +0,0 @@ -require 'state_machine/transition' -require 'state_machine/guard' -require 'state_machine/assertions' -require 'state_machine/matcher_helpers' - -module StateMachine - # An event defines an action that transitions an attribute from one state to - # another. The state that an attribute is transitioned to depends on the - # guards configured for the event. - class Event - include Assertions - include MatcherHelpers - - # The state machine for which this event is defined - attr_accessor :machine - - # The name of the action that fires the event - attr_reader :name - - # The list of guards that determine what state this event transitions - # objects to when fired - attr_reader :guards - - # A list of all of the states known to this event using the configured - # guards/transitions as the source - attr_reader :known_states - - # Creates a new event within the context of the given machine - def initialize(machine, name) #:nodoc: - @machine = machine - @name = name - @guards = [] - @known_states = [] - - add_actions - end - - # Creates a copy of this event in addition to the list of associated - # guards to prevent conflicts across events within a class hierarchy. - def initialize_copy(orig) #:nodoc: - super - @guards = @guards.dup - @known_states = @known_states.dup - end - - # Creates a new transition that determines what to change the current state - # to when this event fires. - # - # == Defining transitions - # - # The options for a new transition uses the Hash syntax to map beginning - # states to ending states. For example, - # - # transition :parked => :idling, :idling => :first_gear - # - # In this case, when the event is fired, this transition will cause the - # state to be +idling+ if it's current state is +parked+ or +first_gear+ if - # it's current state is +idling+. - # - # To help defining these implicit transitions, a set of helpers are available - # for defining slightly more complex matching: - # * <tt>all</tt> - Matches every state in the machine - # * <tt>all - [:parked, :idling, ...]</tt> - Matches every state except those specified - # * <tt>any</tt> - An alias for +all+ (matches every state in the machine) - # * <tt>same</tt> - Matches the same state being transitioned from - # - # See StateMachine::MatcherHelpers for more information. - # - # Examples: - # - # transition all => nil # Transitions to nil regardless of the current state - # transition all => :idling # Transitions to :idling regardless of the current state - # transition all - [:idling, :first_gear] => :idling # Transitions every state but :idling and :first_gear to :idling - # transition nil => :idling # Transitions to :idling from the nil state - # transition :parked => :idling # Transitions to :idling if :parked - # transition [:parked, :stalled] => :idling # Transitions to :idling if :parked or :stalled - # - # transition :parked => same # Loops :parked back to :parked - # transition [:parked, :stalled] => same # Loops either :parked or :stalled back to the same state - # transition all - :parked => same # Loops every state but :parked back to the same state - # - # == Verbose transitions - # - # Transitions can also be defined use an explicit set of deprecated - # configuration options: - # * <tt>:from</tt> - A state or array of states that can be transitioned from. - # If not specified, then the transition can occur for *any* state. - # * <tt>:to</tt> - The state that's being transitioned to. If not specified, - # then the transition will simply loop back (i.e. the state will not change). - # * <tt>:except_from</tt> - A state or array of states that *cannot* be - # transitioned from. - # - # Examples: - # - # transition :to => nil - # transition :to => :idling - # transition :except_from => [:idling, :first_gear], :to => :idling - # transition :from => nil, :to => :idling - # transition :from => [:parked, :stalled], :to => :idling - # - # transition :from => :parked - # transition :from => [:parked, :stalled] - # transition :except_from => :parked - # - # Notice that the above examples are the verbose equivalent of the examples - # described initially. - # - # == Conditions - # - # In addition to the state requirements for each transition, a condition - # can also be defined to help determine whether that transition is - # available. These options will work on both the normal and verbose syntax. - # - # Configuration options: - # * <tt>:if</tt> - A method, proc or string to call to determine if the - # transition should occur (e.g. :if => :moving?, or :if => lambda {|vehicle| vehicle.speed > 60}). - # The condition should return or evaluate to true or false. - # * <tt>:unless</tt> - A method, proc or string to call to determine if the - # transition should not occur (e.g. :unless => :stopped?, or :unless => lambda {|vehicle| vehicle.speed <= 60}). - # The condition should return or evaluate to true or false. - # - # Examples: - # - # transition :parked => :idling, :if => :moving? - # transition :parked => :idling, :unless => :stopped? - # - # transition :from => :parked, :to => :idling, :if => :moving? - # transition :from => :parked, :to => :idling, :unless => :stopped? - # - # == Order of operations - # - # Transitions are evaluated in the order in which they're defined. As a - # result, if more than one transition applies to a given object, then the - # first transition that matches will be performed. - def transition(options) - raise ArgumentError, 'Must specify as least one transition requirement' if options.empty? - - # Only a certain subset of explicit options are allowed for transition - # requirements - assert_valid_keys(options, :from, :to, :except_from, :if, :unless) if (options.keys - [:from, :to, :on, :except_from, :except_to, :except_on, :if, :unless]).empty? - - guards << guard = Guard.new(options) - @known_states |= guard.known_states - guard - end - - # Determines whether any transitions can be performed for this event based - # on the current state of the given object. - # - # If the event can't be fired, then this will return false, otherwise true. - def can_fire?(object) - !next_transition(object).nil? - end - - # Finds and builds the next transition that can be performed on the given - # object. If no transitions can be made, then this will return nil. - def next_transition(object) - from = machine.state_for(object).name - - guards.each do |guard| - if match = guard.match(object, :from => from) - # Guard allows for the transition to occur - to = match[:to].values.empty? ? from : match[:to].values.first - - return Transition.new(object, machine, name, from, to) - end - end - - # No transition matched - nil - end - - # Attempts to perform the next available transition on the given object. - # If no transitions can be made, then this will return false, otherwise - # true. - # - # Any additional arguments are passed to the StateMachine::Transition#perform - # instance method. - def fire(object, *args) - machine.reset(object) - - if transition = next_transition(object) - transition.perform(*args) - else - machine.invalidate(object, self) - false - end - end - - # Attempts to perform the next available transition on the given object. - # If no transitions can be made, then a StateMachine::InvalidTransition - # exception will be raised, otherwise true will be returned. - def fire!(object, *args) - fire(object, *args) || raise(StateMachine::InvalidTransition, "Cannot transition #{machine.attribute} via :#{name} from #{machine.state_for(object).name.inspect}") - end - - # Draws a representation of this event on the given graph. This will - # create 1 or more edges on the graph for each guard (i.e. transition) - # configured. - # - # A collection of the generated edges will be returned. - def draw(graph) - valid_states = machine.states.by_priority.map {|state| state.name} - guards.collect {|guard| guard.draw(graph, name, valid_states)}.flatten - end - - # Generates a nicely formatted description of this events's contents. - # - # For example, - # - # event = StateMachine::Event.new(machine, :park) - # event.transition all - :idling => :parked, :idling => same - # event # => #<StateMachine::Event name=:park transitions=[all - :idling => :parked, :idling => same]> - def inspect - transitions = guards.map do |guard| - guard.state_requirements.map do |state_requirement| - "#{state_requirement[:from].description} => #{state_requirement[:to].description}" - end * ', ' - end - - "#<#{self.class} name=#{name.inspect} transitions=[#{transitions * ', '}]>" - end - - protected - # Add the various instance methods that can transition the object using - # the current event - def add_actions - qualified_name = name = self.name - qualified_name = "#{name}_#{machine.namespace}" if machine.namespace - - # Checks whether the event can be fired on the current object - machine.define_instance_method("can_#{qualified_name}?") do |machine, object| - machine.event(name).can_fire?(object) - end - - # Gets the next transition that would be performed if the event were - # fired now - machine.define_instance_method("next_#{qualified_name}_transition") do |machine, object| - machine.event(name).next_transition(object) - end - - # Fires the event - machine.define_instance_method(qualified_name) do |machine, object, *args| - machine.event(name).fire(object, *args) - end - - # Fires the event, raising an exception if it fails - machine.define_instance_method("#{qualified_name}!") do |machine, object, *args| - machine.event(name).fire!(object, *args) - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/extensions.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/extensions.rb deleted file mode 100644 index b2f8040..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/extensions.rb +++ /dev/null @@ -1,42 +0,0 @@ -module StateMachine - module ClassMethods - def self.extended(base) #:nodoc: - base.class_eval do - @state_machines = {} - end - end - - # Gets the current list of state machines defined for this class. This - # class-level attribute acts like an inheritable attribute. The attribute - # is available to each subclass, each subclass having a copy of its - # superclass's attribute. - # - # The hash of state machines maps +attribute+ => +machine+, e.g. - # - # Vehicle.state_machines # => {:state => #<StateMachine::Machine:0xb6f6e4a4 ...> - def state_machines - @state_machines ||= superclass.state_machines.dup - end - end - - module InstanceMethods - # Defines the initial values for state machine attributes. The values - # will be set *after* the original initialize method is invoked. This is - # necessary in order to ensure that the object is initialized before - # dynamic initial attributes are evaluated. - def initialize(*args, &block) - super - initialize_state_machines - end - - protected - def initialize_state_machines #:nodoc: - self.class.state_machines.each do |attribute, machine| - # Set the initial value of the machine's attribute unless it already - # exists (which must mean the defaults are being skipped) - value = send(attribute) - send("#{attribute}=", machine.initial_state(self).value) if value.nil? || value.respond_to?(:empty?) && value.empty? - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/guard.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/guard.rb deleted file mode 100644 index 04f6a45..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/guard.rb +++ /dev/null @@ -1,219 +0,0 @@ -require 'state_machine/matcher' -require 'state_machine/eval_helpers' -require 'state_machine/assertions' - -module StateMachine - # Represents a set of requirements that must be met in order for a transition - # or callback to occur. Guards verify that the event, from state, and to - # state of the transition match, in addition to if/unless conditionals for - # an object's state. - class Guard - include Assertions - include EvalHelpers - - # The condition that must be met on an object - attr_reader :if_condition - - # The condition that must *not* be met on an object - attr_reader :unless_condition - - # The requirement for verifying the event being guarded - attr_reader :event_requirement - - # One or more requrirements for verifying the states being guarded. All - # requirements contain a mapping of {:from => matcher, :to => matcher}. - attr_reader :state_requirements - - # A list of all of the states known to this guard. This will pull states - # from the following options (in the same order): - # * +from+ / +except_from+ - # * +to+ / +except_to+ - attr_reader :known_states - - # Creates a new guard - def initialize(options = {}) #:nodoc: - # Build conditionals - @if_condition = options.delete(:if) - @unless_condition = options.delete(:unless) - - # Build event requirement - @event_requirement = build_matcher(options, :on, :except_on) - - if (options.keys - [:from, :to, :on, :except_from, :except_to, :except_on]).empty? - # Explicit from/to requirements specified - @state_requirements = [{:from => build_matcher(options, :from, :except_from), :to => build_matcher(options, :to, :except_to)}] - else - # Separate out the event requirement - options.delete(:on) - options.delete(:except_on) - - # Implicit from/to requirements specified - @state_requirements = options.collect do |from, to| - from = WhitelistMatcher.new(from) unless from.is_a?(Matcher) - to = WhitelistMatcher.new(to) unless to.is_a?(Matcher) - {:from => from, :to => to} - end - end - - # Track known states. The order that requirements are iterated is based - # on the priority in which tracked states should be added. - @known_states = [] - @state_requirements.each do |state_requirement| - [:from, :to].each {|option| @known_states |= state_requirement[option].values} - end - end - - # Determines whether the given object / query matches the requirements - # configured for this guard. In addition to matching the event, from state, - # and to state, this will also check whether the configured :if/:unless - # conditions pass on the given object. - # - # == Examples - # - # guard = StateMachine::Guard.new(:parked => :idling, :on => :ignite) - # - # # Successful - # guard.matches?(object, :on => :ignite) # => true - # guard.matches?(object, :from => nil) # => true - # guard.matches?(object, :from => :parked) # => true - # guard.matches?(object, :to => :idling) # => true - # guard.matches?(object, :from => :parked, :to => :idling) # => true - # guard.matches?(object, :on => :ignite, :from => :parked, :to => :idling) # => true - # - # # Unsuccessful - # guard.matches?(object, :on => :park) # => false - # guard.matches?(object, :from => :idling) # => false - # guard.matches?(object, :to => :first_gear) # => false - # guard.matches?(object, :from => :parked, :to => :first_gear) # => false - # guard.matches?(object, :on => :park, :from => :parked, :to => :idling) # => false - def matches?(object, query = {}) - !match(object, query).nil? - end - - # Attempts to match the given object / query against the set of requirements - # configured for this guard. In addition to matching the event, from state, - # and to state, this will also check whether the configured :if/:unless - # conditions pass on the given object. - # - # If a match is found, then the event/state requirements that the query - # passed successfully will be returned. Otherwise, nil is returned if there - # was no match. - # - # Query options: - # * <tt>:from</tt> - One or more states being transitioned from. If none - # are specified, then this will always match. - # * <tt>:to</tt> - One or more states being transitioned to. If none are - # specified, then this will always match. - # * <tt>:on</tt> - One or more events that fired the transition. If none - # are specified, then this will always match. - # - # == Examples - # - # guard = StateMachine::Guard.new(:parked => :idling, :on => :ignite) - # - # guard.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...} - # guard.match(object, :on => :park) # => nil - def match(object, query = {}) - if (match = match_query(query)) && matches_conditions?(object) - match - end - end - - # Draws a representation of this guard on the given graph. This will draw - # an edge between every state this guard matches *from* to either the - # configured to state or, if none specified, then a loopback to the from - # state. - # - # For example, if the following from states are configured: - # * +idling+ - # * +first_gear+ - # * +backing_up+ - # - # ...and the to state is +parked+, then the following edges will be created: - # * +idling+ -> +parked+ - # * +first_gear+ -> +parked+ - # * +backing_up+ -> +parked+ - # - # Each edge will be labeled with the name of the event that would cause the - # transition. - # - # The collection of edges generated on the graph will be returned. - def draw(graph, event, valid_states) - state_requirements.inject([]) do |edges, state_requirement| - # From states determined based on the known valid states - from_states = state_requirement[:from].filter(valid_states) - - # If a to state is not specified, then it's a loopback and each from - # state maps back to itself - if state_requirement[:to].values.empty? - loopback = true - else - to_state = state_requirement[:to].values.first - to_state = to_state ? to_state.to_s : 'nil' - loopback = false - end - - # Generate an edge between each from and to state - from_states.each do |from_state| - from_state = from_state ? from_state.to_s : 'nil' - edges << graph.add_edge(from_state, loopback ? from_state : to_state, :label => event.to_s) - end - - edges - end - end - - protected - # Builds a matcher strategy to use for the given options. If neither a - # whitelist nor a blacklist option is specified, then an AllMatcher is - # built. - def build_matcher(options, whitelist_option, blacklist_option) - assert_exclusive_keys(options, whitelist_option, blacklist_option) - - if options.include?(whitelist_option) - WhitelistMatcher.new(options[whitelist_option]) - elsif options.include?(blacklist_option) - BlacklistMatcher.new(options[blacklist_option]) - else - AllMatcher.instance - end - end - - # Verifies that all configured requirements (event and state) match the - # given query. If a match is found, then a hash containing the - # event/state requirements that passed will be returned; otherwise, nil. - def match_query(query) - query ||= {} - - if match_event(query) && (state_requirement = match_states(query)) - state_requirement.merge(:on => event_requirement) - end - end - - # Verifies that the event requirement matches the given query - def match_event(query) - matches_requirement?(query, :on, event_requirement) - end - - # Verifies that the state requirements match the given query. If a - # matching requirement is found, then it is returned. - def match_states(query) - state_requirements.detect do |state_requirement| - [:from, :to].all? {|option| matches_requirement?(query, option, state_requirement[option])} - end - end - - # Verifies that an option in the given query matches the values required - # for that option - def matches_requirement?(query, option, requirement) - !query.include?(option) || requirement.matches?(query[option], query) - end - - # Verifies that the conditionals for this guard evaluate to true for the - # given object - def matches_conditions?(object) - Array(if_condition).all? {|condition| evaluate_method(object, condition)} && - !Array(unless_condition).any? {|condition| evaluate_method(object, condition)} - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations.rb deleted file mode 100644 index f9a94e4..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations.rb +++ /dev/null @@ -1,68 +0,0 @@ -# Load each available integration -Dir["#{File.dirname(__FILE__)}/integrations/*.rb"].sort.each do |path| - require "state_machine/integrations/#{File.basename(path)}" -end - -module StateMachine - # Integrations allow state machines to take advantage of features within the - # context of a particular library. This is currently most useful with - # database libraries. For example, the various database integrations allow - # state machines to hook into features like: - # * Saving - # * Transactions - # * Observers - # * Scopes - # * Callbacks - # * Validation errors - # - # This type of integration allows the user to work with state machines in a - # fashion similar to other object models in their application. - # - # The integration interface is loosely defined by various unimplemented - # methods in the StateMachine::Machine class. See that class or the various - # built-in integrations for more information about how to define additional - # integrations. - module Integrations - # Attempts to find an integration that matches the given class. This will - # look through all of the built-in integrations under the StateMachine::Integrations - # namespace and find one that successfully matches the class. - # - # == Examples - # - # class Vehicle - # end - # - # class ARVehicle < ActiveRecord::Base - # end - # - # class DMVehicle - # include DataMapper::Resource - # end - # - # class SequelVehicle < Sequel::Model - # end - # - # StateMachine::Integrations.match(Vehicle) # => nil - # StateMachine::Integrations.match(ARVehicle) # => StateMachine::Integrations::ActiveRecord - # StateMachine::Integrations.match(DMVehicle) # => StateMachine::Integrations::DataMapper - # StateMachine::Integrations.match(SequelVehicle) # => StateMachine::Integrations::Sequel - def self.match(klass) - if integration = constants.find {|name| const_get(name).matches?(klass)} - find(integration) - end - end - - # Finds an integration with the given name. If the integration cannot be - # found, then a NameError exception will be raised. - # - # == Examples - # - # StateMachine::Integrations.find(:active_record) # => StateMachine::Integrations::ActiveRecord - # StateMachine::Integrations.find(:data_mapper) # => StateMachine::Integrations::DataMapper - # StateMachine::Integrations.find(:sequel) # => StateMachine::Integrations::Sequel - # StateMachine::Integrations.find(:invalid) # => NameError: wrong constant name Invalid - def self.find(name) - const_get(name.to_s.gsub(/(?:^|_)(.)/) {$1.upcase}) - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record.rb deleted file mode 100644 index 7323a5a..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record.rb +++ /dev/null @@ -1,319 +0,0 @@ -module StateMachine - module Integrations #:nodoc: - # Adds support for integrating state machines with ActiveRecord models. - # - # == Examples - # - # Below is an example of a simple state machine defined within an - # ActiveRecord model: - # - # class Vehicle < ActiveRecord::Base - # state_machine :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # end - # end - # - # The examples in the sections below will use the above class as a - # reference. - # - # == Actions - # - # By default, the action that will be invoked when a state is transitioned - # is the +save+ action. This will cause the record to save the changes - # made to the state machine's attribute. *Note* that if any other changes - # were made to the record prior to transition, then those changes will - # be saved as well. - # - # For example, - # - # vehicle = Vehicle.create # => #<Vehicle id: 1, name: nil, state: "parked"> - # vehicle.name = 'Ford Explorer' - # vehicle.ignite # => true - # vehicle.reload # => #<Vehicle id: 1, name: "Ford Explorer", state: "idling"> - # - # == Transactions - # - # In order to ensure that any changes made during transition callbacks - # are rolled back during a failed attempt, every transition is wrapped - # within a transaction. - # - # For example, - # - # class Message < ActiveRecord::Base - # end - # - # Vehicle.state_machine do - # before_transition do |vehicle, transition| - # Message.create(:content => transition.inspect) - # false - # end - # end - # - # vehicle = Vehicle.create # => #<Vehicle id: 1, name: nil, state: "parked"> - # vehicle.ignite # => false - # Message.count # => 0 - # - # *Note* that only before callbacks that halt the callback chain and - # failed attempts to save the record will result in the transaction being - # rolled back. If an after callback halts the chain, the previous result - # still applies and the transaction is *not* rolled back. - # - # == Validation errors - # - # If an event fails to successfully fire because there are no matching - # transitions for the current record, a validation error is added to the - # record's state attribute to help in determining why it failed and for - # reporting via the UI. - # - # For example, - # - # vehicle = Vehicle.create(:state => 'idling') # => #<Vehicle id: 1, name: nil, state: "idling"> - # vehicle.ignite # => false - # vehicle.errors.full_messages # => ["State cannot be transitioned via :ignite from :idling"] - # - # If an event fails to fire because of a validation error on the record and - # *not* because a matching transition was not available, no error messages - # will be added to the state attribute. - # - # == Scopes - # - # To assist in filtering models with specific states, a series of named - # scopes are defined on the model for finding records with or without a - # particular set of states. - # - # These named scopes are essentially the functional equivalent of the - # following definitions: - # - # class Vehicle < ActiveRecord::Base - # named_scope :with_states, lambda {|*states| {:conditions => {:state => states}}} - # # with_states also aliased to with_state - # - # named_scope :without_states, lambda {|*states| {:conditions => ['state NOT IN (?)', states]}} - # # without_states also aliased to without_state - # end - # - # *Note*, however, that the states are converted to their stored values - # before being passed into the query. - # - # Because of the way named scopes work in ActiveRecord, they can be - # chained like so: - # - # Vehicle.with_state(:parked).all(:order => 'id DESC') - # - # == Callbacks - # - # All before/after transition callbacks defined for ActiveRecord models - # behave in the same way that other ActiveRecord callbacks behave. The - # object involved in the transition is passed in as an argument. - # - # For example, - # - # class Vehicle < ActiveRecord::Base - # state_machine :initial => :parked do - # before_transition any => :idling do |vehicle| - # vehicle.put_on_seatbelt - # end - # - # before_transition do |vehicle, transition| - # # log message - # end - # - # event :ignite do - # transition :parked => :idling - # end - # end - # - # def put_on_seatbelt - # ... - # end - # end - # - # Note, also, that the transition can be accessed by simply defining - # additional arguments in the callback block. - # - # == Observers - # - # In addition to support for ActiveRecord-like hooks, there is additional - # support for ActiveRecord observers. Because of the way ActiveRecord - # observers are designed, there is less flexibility around the specific - # transitions that can be hooked in. As a result, observers can only - # hook into before/after callbacks for events and generic transitions - # like so: - # - # class VehicleObserver < ActiveRecord::Observer - # def before_save(vehicle) - # # log message - # end - # - # # Callback for :ignite event *before* the transition is performed - # def before_ignite(vehicle, transition) - # # log message - # end - # - # # Callback for :ignite event *after* the transition has been performed - # def after_ignite(vehicle, transition) - # # put on seatbelt - # end - # - # # Generic transition callback *before* the transition is performed - # def after_transition(vehicle, transition) - # Audit.log(vehicle, transition) - # end - # end - # - # More flexible transition callbacks can be defined directly within the - # model as described in StateMachine::Machine#before_transition - # and StateMachine::Machine#after_transition. - # - # To define a single observer for multiple state machines: - # - # class StateMachineObserver < ActiveRecord::Observer - # observe Vehicle, Switch, Project - # - # def after_transition(record, transition) - # Audit.log(record, transition) - # end - # end - module ActiveRecord - # Should this integration be used for state machines in the given class? - # Classes that inherit from ActiveRecord::Base will automatically use - # the ActiveRecord integration. - def self.matches?(klass) - defined?(::ActiveRecord::Base) && klass <= ::ActiveRecord::Base - end - - # Loads additional files specific to ActiveRecord - def self.extended(base) #:nodoc: - require 'state_machine/integrations/active_record/observer' - I18n.load_path << "#{File.dirname(__FILE__)}/active_record/locale.rb" if Object.const_defined?(:I18n) - end - - # Adds a validation error to the given object after failing to fire a - # specific event - def invalidate(object, event) - if Object.const_defined?(:I18n) - object.errors.add(attribute, :invalid_transition, - :event => event.name, - :value => state_for(object).name, - :default => @invalid_message - ) - else - object.errors.add(attribute, invalid_message(object, event)) - end - end - - # Resets an errors previously added when invalidating the given object - def reset(object) - object.errors.clear - end - - # Runs a new database transaction, rolling back any changes by raising - # an ActiveRecord::Rollback exception if the yielded block fails - # (i.e. returns false). - def within_transaction(object) - object.class.transaction {raise ::ActiveRecord::Rollback unless yield} - end - - protected - # Adds the default callbacks for notifying ActiveRecord observers - # before/after a transition has been performed. - def after_initialize - # Observer callbacks never halt the chain; result is ignored - callbacks[:before] << Callback.new {|object, transition| notify(:before, object, transition)} - callbacks[:after] << Callback.new {|object, transition, result| notify(:after, object, transition)} - end - - # Sets the default action for all ActiveRecord state machines to +save+ - def default_action - :save - end - - # Skips defining reader/writer methods since this is done automatically - def define_attribute_accessor - end - - # Adds support for defining the attribute predicate, while providing - # compatibility with the default predicate which determines whether - # *anything* is set for the attribute's value - def define_attribute_predicate - attribute = self.attribute - - # Still use class_eval here instance of define_instance_method since - # we need to directly override the method defined in the model - owner_class.class_eval do - define_method("#{attribute}?") do |*args| - args.empty? ? super(*args) : self.class.state_machines[attribute].state?(self, *args) - end - end - end - - # Creates a scope for finding records *with* a particular state or - # states for the attribute - def create_with_scope(name) - attribute = self.attribute - define_scope(name, lambda {|values| {:conditions => {attribute => values}}}) - end - - # Creates a scope for finding records *without* a particular state or - # states for the attribute - def create_without_scope(name) - attribute = self.attribute - define_scope(name, lambda {|values| {:conditions => ["#{attribute} NOT IN (?)", values]}}) - end - - # Creates a new callback in the callback chain, always inserting it - # before the default Observer callbacks that were created after - # initialization. - def add_callback(type, options, &block) - options[:terminator] = @terminator ||= lambda {|result| result == false} - @callbacks[type].insert(-2, callback = Callback.new(options, &block)) - add_states(callback.known_states) - - callback - end - - private - # Defines a new named scope with the given name. Since ActiveRecord - # does not allow direct access to the model being used within the - # evaluation of a dynamic named scope, the scope must be generated - # manually. It's necessary to have access to the model so that the - # state names can be translated to their associated values and so that - # inheritance is respected properly. - def define_scope(name, scope) - name = name.to_sym - attribute = self.attribute - - # Created the scope and then override it with state translation - owner_class.named_scope(name) - owner_class.scopes[name] = lambda do |klass, *states| - machine_states = klass.state_machines[attribute].states - values = states.flatten.map {|state| machine_states.fetch(state).value} - - ::ActiveRecord::NamedScope::Scope.new(klass, scope.call(values)) - end - - false - end - - # Notifies observers on the given object that a callback occurred - # involving the given transition. This will attempt to call the - # following methods on observers: - # * #{type}_#{event} - # * #{type}_transition - # - # This will always return true regardless of the results of the - # callbacks. - def notify(type, object, transition) - qualified_event = namespace ? "#{transition.event}_#{namespace}" : transition.event - ["#{type}_#{qualified_event}", "#{type}_transition"].each do |method| - object.class.changed - object.class.notify_observers(method, object, transition) - end - - true - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record/locale.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record/locale.rb deleted file mode 100644 index dbb1660..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record/locale.rb +++ /dev/null @@ -1,9 +0,0 @@ -{:en => { - :activerecord => { - :errors => { - :messages => { - :invalid_transition => StateMachine::Machine.default_invalid_message % ['{{event}}', '{{value}}'] - } - } - } -}} diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record/observer.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record/observer.rb deleted file mode 100644 index d1a8b32..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/active_record/observer.rb +++ /dev/null @@ -1,41 +0,0 @@ -module StateMachine - module Integrations #:nodoc: - module ActiveRecord - # Adds support for invoking callbacks on ActiveRecord observers with more - # than one argument (e.g. the record *and* the state transition). By - # default, ActiveRecord only supports passing the record into the - # callbacks. - # - # For example: - # - # class VehicleObserver < ActiveRecord::Observer - # # The default behavior: only pass in the record - # def after_save(vehicle) - # end - # - # # Custom behavior: allow the transition to be passed in as well - # def after_transition(vehicle, transition) - # Audit.log(vehicle, transition) - # end - # end - module Observer - def self.included(base) #:nodoc: - base.class_eval do - alias_method :update_without_multiple_args, :update - alias_method :update, :update_with_multiple_args - end - end - - # Allows additional arguments other than the object to be passed to the - # observed methods - def update_with_multiple_args(observed_method, object, *args) #:nodoc: - send(observed_method, object, *args) if respond_to?(observed_method) - end - end - end - end -end - -ActiveRecord::Observer.class_eval do - include StateMachine::Integrations::ActiveRecord::Observer -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/data_mapper.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/data_mapper.rb deleted file mode 100644 index b19b13d..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/data_mapper.rb +++ /dev/null @@ -1,229 +0,0 @@ -module StateMachine - module Integrations #:nodoc: - # Adds support for integrating state machines with DataMapper resources. - # - # == Examples - # - # Below is an example of a simple state machine defined within a - # DataMapper resource: - # - # class Vehicle - # include DataMapper::Resource - # - # property :id, Serial - # property :name, String - # property :state, String - # - # state_machine :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # end - # end - # - # The examples in the sections below will use the above class as a - # reference. - # - # == Actions - # - # By default, the action that will be invoked when a state is transitioned - # is the +save+ action. This will cause the resource to save the changes - # made to the state machine's attribute. *Note* that if any other changes - # were made to the resource prior to transition, then those changes will - # be saved as well. - # - # For example, - # - # vehicle = Vehicle.create # => #<Vehicle id=1 name=nil state="parked"> - # vehicle.name = 'Ford Explorer' - # vehicle.ignite # => true - # vehicle.reload # => #<Vehicle id=1 name="Ford Explorer" state="idling"> - # - # == Transactions - # - # In order to ensure that any changes made during transition callbacks - # are rolled back during a failed attempt, every transition is wrapped - # within a transaction. - # - # For example, - # - # class Message - # include DataMapper::Resource - # - # property :id, Serial - # property :content, String - # end - # - # Vehicle.state_machine do - # before_transition do |transition| - # Message.create(:content => transition.inspect) - # throw :halt - # end - # end - # - # vehicle = Vehicle.create # => #<Vehicle id=1 name=nil state="parked"> - # vehicle.ignite # => false - # Message.all.count # => 0 - # - # *Note* that only before callbacks that halt the callback chain and - # failed attempts to save the record will result in the transaction being - # rolled back. If an after callback halts the chain, the previous result - # still applies and the transaction is *not* rolled back. - # - # == Validation errors - # - # If an event fails to successfully fire because there are no matching - # transitions for the current record, a validation error is added to the - # record's state attribute to help in determining why it failed and for - # reporting via the UI. - # - # For example, - # - # vehicle = Vehicle.create(:state => 'idling') # => #<Vehicle id=1 name=nil state="idling"> - # vehicle.ignite # => false - # vehicle.errors.full_messages # => ["cannot be transitioned via :ignite from :idling"] - # - # If an event fails to fire because of a validation error on the record and - # *not* because a matching transition was not available, no error messages - # will be added to the state attribute. - # - # == Scopes - # - # To assist in filtering models with specific states, a series of class - # methods are defined on the model for finding records with or without a - # particular set of states. - # - # These named scopes are the functional equivalent of the following - # definitions: - # - # class Vehicle - # include DataMapper::Resource - # - # property :id, Serial - # property :state, String - # - # class << self - # def with_states(*states) - # all(:state => states.flatten) - # end - # alias_method :with_state, :with_states - # - # def without_states(*states) - # all(:state.not => states.flatten) - # end - # alias_method :without_state, :without_states - # end - # end - # - # *Note*, however, that the states are converted to their stored values - # before being passed into the query. - # - # Because of the way scopes work in DataMapper, they can be chained like - # so: - # - # Vehicle.with_state(:parked).all(:order => [:id.desc]) - # - # == Callbacks / Observers - # - # All before/after transition callbacks defined for DataMapper resources - # behave in the same way that other DataMapper hooks behave. Rather than - # passing in the record as an argument to the callback, the callback is - # instead bound to the object and evaluated within its context. - # - # For example, - # - # class Vehicle - # include DataMapper::Resource - # - # property :id, Serial - # property :state, String - # - # state_machine :initial => :parked do - # before_transition any => :idling do - # put_on_seatbelt - # end - # - # before_transition do |transition| - # # log message - # end - # - # event :ignite do - # transition :parked => :idling - # end - # end - # - # def put_on_seatbelt - # ... - # end - # end - # - # Note, also, that the transition can be accessed by simply defining - # additional arguments in the callback block. - # - # In addition to support for DataMapper-like hooks, there is additional - # support for DataMapper observers. See StateMachine::Integrations::DataMapper::Observer - # for more information. - module DataMapper - # Should this integration be used for state machines in the given class? - # Classes that include DataMapper::Resource will automatically use the - # DataMapper integration. - def self.matches?(klass) - defined?(::DataMapper::Resource) && klass <= ::DataMapper::Resource - end - - # Loads additional files specific to DataMapper - def self.extended(base) #:nodoc: - require 'state_machine/integrations/data_mapper/observer' if ::DataMapper.const_defined?('Observer') - end - - # Adds a validation error to the given object after failing to fire a - # specific event - def invalidate(object, event) - object.errors.add(attribute, invalid_message(object, event)) if object.respond_to?(:errors) - end - - # Resets an errors previously added when invalidating the given object - def reset(object) - object.errors.clear - end - - # Runs a new database transaction, rolling back any changes if the - # yielded block fails (i.e. returns false). - def within_transaction(object) - object.class.transaction {|t| t.rollback unless yield} - end - - protected - # Sets the default action for all DataMapper state machines to +save+ - def default_action - :save - end - - # Skips defining reader/writer methods since this is done automatically - def define_attribute_accessor - end - - # Creates a scope for finding records *with* a particular state or - # states for the attribute - def create_with_scope(name) - attribute = self.attribute - lambda {|resource, values| resource.all(attribute => values)} - end - - # Creates a scope for finding records *without* a particular state or - # states for the attribute - def create_without_scope(name) - attribute = self.attribute - lambda {|resource, values| resource.all(attribute.to_sym.not => values)} - end - - # Creates a new callback in the callback chain, always ensuring that - # it's configured to bind to the object as this is the convention for - # DataMapper/Extlib callbacks - def add_callback(type, options, &block) - options[:bind_to_object] = true - super - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/data_mapper/observer.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/data_mapper/observer.rb deleted file mode 100644 index c889919..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/data_mapper/observer.rb +++ /dev/null @@ -1,183 +0,0 @@ -module StateMachine - module Integrations #:nodoc: - module DataMapper - # Adds support for creating before/after transition callbacks within a - # DataMapper observer. These callbacks behave very similarly to - # before/after hooks during save/update/destroy/etc., but with the - # following modifications: - # * Each callback can define a set of transition conditions (i.e. guards) - # that must be met in order for the callback to get invoked. - # * An additional transition parameter is available that provides - # contextual information about the event (see StateMachine::Transition - # for more information) - # - # To define a single observer for multiple state machines: - # - # class StateMachineObserver - # include DataMapper::Observer - # - # observe Vehicle, Switch, Project - # - # after_transition do |transition, saved| - # Audit.log(self, transition) if saved - # end - # end - # - # == Requirements - # - # To use this feature of the DataMapper integration, the dm-observer library - # must be available. This can be installed either directly or indirectly - # through dm-more. When loading DataMapper, be sure to load the dm-observer - # library as well like so: - # - # require 'rubygems' - # require 'dm-core' - # require 'dm-observer' - # - # If dm-observer is not available, then this feature will be skipped. - # - module Observer - include MatcherHelpers - - # Creates a callback that will be invoked *before* a transition is - # performed, so long as the given configuration options match the - # transition. Each part of the transition (event, to state, from state) - # must match in order for the callback to get invoked. - # - # See StateMachine::Machine#before_transition for more - # information about the various configuration options available. - # - # == Examples - # - # class Vehicle - # include DataMapper::Resource - # - # property :id, Serial - # property :state, :String - # - # state_machine :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # end - # end - # - # class VehicleObserver - # include DataMapper::Observer - # - # observe Vehicle - # - # before :save do - # # log message - # end - # - # # Target all state machines - # before_transition :parked => :idling, :on => :ignite do - # # put on seatbelt - # end - # - # # Target a specific state machine - # before_transition :state, any => :idling do - # # put on seatbelt - # end - # - # # Target all state machines without requirements - # before_transition do |transition| - # # log message - # end - # end - # - # *Note* that in each of the above +before_transition+ callbacks, the - # callback is executed within the context of the object (i.e. the - # Vehicle instance being transition). This means that +self+ refers - # to the vehicle record within each callback block. - def before_transition(*args, &block) - add_transition_callback(:before, *args, &block) - end - - # Creates a callback that will be invoked *after* a transition is - # performed, so long as the given configuration options match the - # transition. Each part of the transition (event, to state, from state) - # must match in order for the callback to get invoked. - # - # See StateMachine::Machine#after_transition for more - # information about the various configuration options available. - # - # == Examples - # - # class Vehicle - # include DataMapper::Resource - # - # property :id, Serial - # property :state, :String - # - # state_machine :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # end - # end - # - # class VehicleObserver - # include DataMapper::Observer - # - # observe Vehicle - # - # after :save do |saved| - # # log message - # end - # - # # Target all state machines - # after_transition :parked => :idling, :on => :ignite do - # # put on seatbelt - # end - # - # # Target a specific state machine - # after_transition :state, any => :idling do - # # put on seatbelt - # end - # - # # Target all state machines without requirements - # after_transition do |transition, saved| - # if saved - # # log message - # end - # end - # end - # - # *Note* that in each of the above +before_transition+ callbacks, the - # callback is executed within the context of the object (i.e. the - # Vehicle instance being transition). This means that +self+ refers - # to the vehicle record within each callback block. - def after_transition(*args, &block) - add_transition_callback(:after, *args, &block) - end - - private - # Adds the transition callback to a specific machine or all of the - # state machines for each observed class. - def add_transition_callback(type, *args, &block) - if args.first && !args.first.is_a?(Hash) - # Specific attribute is being targeted - attribute = args.first - transition_args = args[1..-1] - else - # Target all state machines - attribute = nil - transition_args = args - end - - # Add the transition callback to each class being observed - observing.each do |klass| - state_machines = attribute ? [klass.state_machines[attribute]] : klass.state_machines.values - state_machines.each {|machine| machine.send("#{type}_transition", *transition_args, &block)} - end if observing - end - end - end - end -end - -DataMapper::Observer::ClassMethods.class_eval do - include StateMachine::Integrations::DataMapper::Observer -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/sequel.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/sequel.rb deleted file mode 100644 index 7f67dfc..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/integrations/sequel.rb +++ /dev/null @@ -1,200 +0,0 @@ -module StateMachine - module Integrations #:nodoc: - # Adds support for integrating state machines with Sequel models. - # - # == Examples - # - # Below is an example of a simple state machine defined within a - # Sequel model: - # - # class Vehicle < Sequel::Model - # state_machine :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # end - # end - # - # The examples in the sections below will use the above class as a - # reference. - # - # == Actions - # - # By default, the action that will be invoked when a state is transitioned - # is the +save+ action. This will cause the resource to save the changes - # made to the state machine's attribute. *Note* that if any other changes - # were made to the resource prior to transition, then those changes will - # be made as well. - # - # For example, - # - # vehicle = Vehicle.create # => #<Vehicle id=1 name=nil state="parked"> - # vehicle.name = 'Ford Explorer' - # vehicle.ignite # => true - # vehicle.refresh # => #<Vehicle id=1 name="Ford Explorer" state="idling"> - # - # == Transactions - # - # In order to ensure that any changes made during transition callbacks - # are rolled back during a failed attempt, every transition is wrapped - # within a transaction. - # - # For example, - # - # class Message < Sequel::Model - # end - # - # Vehicle.state_machine do - # before_transition do |transition| - # Message.create(:content => transition.inspect) - # false - # end - # end - # - # vehicle = Vehicle.create # => #<Vehicle id=1 name=nil state="parked"> - # vehicle.ignite # => false - # Message.count # => 0 - # - # *Note* that only before callbacks that halt the callback chain and - # failed attempts to save the record will result in the transaction being - # rolled back. If an after callback halts the chain, the previous result - # still applies and the transaction is *not* rolled back. - # - # == Validation errors - # - # If an event fails to successfully fire because there are no matching - # transitions for the current record, a validation error is added to the - # record's state attribute to help in determining why it failed and for - # reporting via the UI. - # - # For example, - # - # vehicle = Vehicle.create(:state => 'idling') # => #<Vehicle id=1 name=nil state="idling"> - # vehicle.ignite # => false - # vehicle.errors.full_messages # => ["state cannot be transitioned via :ignite from :idling"] - # - # If an event fails to fire because of a validation error on the record and - # *not* because a matching transition was not available, no error messages - # will be added to the state attribute. - # - # == Scopes - # - # To assist in filtering models with specific states, a series of class - # methods are defined on the model for finding records with or without a - # particular set of states. - # - # These named scopes are the functional equivalent of the following - # definitions: - # - # class Vehicle < Sequel::Model - # class << self - # def with_states(*states) - # filter(:state => states) - # end - # alias_method :with_state, :with_states - # - # def without_states(*states) - # filter(~{:state => states}) - # end - # alias_method :without_state, :without_states - # end - # end - # - # *Note*, however, that the states are converted to their stored values - # before being passed into the query. - # - # Because of the way scopes work in Sequel, they can be chained like so: - # - # Vehicle.with_state(:parked).order(:id.desc) - # - # == Callbacks - # - # All before/after transition callbacks defined for Sequel resources - # behave in the same way that other Sequel hooks behave. Rather than - # passing in the record as an argument to the callback, the callback is - # instead bound to the object and evaluated within its context. - # - # For example, - # - # class Vehicle < Sequel::Model - # state_machine :initial => :parked do - # before_transition any => :idling do - # put_on_seatbelt - # end - # - # before_transition do |transition| - # # log message - # end - # - # event :ignite do - # transition :parked => :idling - # end - # end - # - # def put_on_seatbelt - # ... - # end - # end - # - # Note, also, that the transition can be accessed by simply defining - # additional arguments in the callback block. - module Sequel - # Should this integration be used for state machines in the given class? - # Classes that include Sequel::Model will automatically use the Sequel - # integration. - def self.matches?(klass) - defined?(::Sequel::Model) && klass <= ::Sequel::Model - end - - # Adds a validation error to the given object after failing to fire a - # specific event - def invalidate(object, event) - object.errors.add(attribute, invalid_message(object, event)) - end - - # Resets an errors previously added when invalidating the given object - def reset(object) - object.errors.clear - end - - # Runs a new database transaction, rolling back any changes if the - # yielded block fails (i.e. returns false). - def within_transaction(object) - object.db.transaction {raise ::Sequel::Error::Rollback unless yield} - end - - protected - # Sets the default action for all Sequel state machines to +save+ - def default_action - :save - end - - # Skips defining reader/writer methods since this is done automatically - def define_attribute_accessor - end - - # Creates a scope for finding records *with* a particular state or - # states for the attribute - def create_with_scope(name) - attribute = self.attribute - lambda {|model, values| model.filter(attribute.to_sym => values)} - end - - # Creates a scope for finding records *without* a particular state or - # states for the attribute - def create_without_scope(name) - attribute = self.attribute - lambda {|model, values| model.filter(~{attribute.to_sym => values})} - end - - # Creates a new callback in the callback chain, always ensuring that - # it's configured to bind to the object as this is the convention for - # Sequel callbacks - def add_callback(type, options, &block) - options[:bind_to_object] = true - options[:terminator] = @terminator ||= lambda {|result| result == false} - super - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/machine.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/machine.rb deleted file mode 100644 index d7545ec..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/machine.rb +++ /dev/null @@ -1,1201 +0,0 @@ -require 'state_machine/extensions' -require 'state_machine/assertions' -require 'state_machine/integrations' - -require 'state_machine/state' -require 'state_machine/event' -require 'state_machine/callback' -require 'state_machine/node_collection' -require 'state_machine/state_collection' -require 'state_machine/matcher_helpers' - -module StateMachine - # Represents a state machine for a particular attribute. State machines - # consist of states, events and a set of transitions that define how the state - # changes after a particular event is fired. - # - # A state machine will not know all of the possible states for an object unless - # they are referenced *somewhere* in the state machine definition. As a result, - # any unused states should be defined with the +other_states+ or +state+ helper. - # - # == Callbacks - # - # Callbacks are supported for hooking before and after every possible - # transition in the machine. Each callback is invoked in the order in which - # it was defined. See StateMachine::Machine#before_transition - # and StateMachine::Machine#after_transition for documentation - # on how to define new callbacks. - # - # === Canceling callbacks - # - # Callbacks can be canceled by throwing :halt at any point during the - # callback. For example, - # - # ... - # throw :halt - # ... - # - # If a +before+ callback halts the chain, the associated transition and all - # later callbacks are canceled. If an +after+ callback halts the chain, - # the later callbacks are canceled, but the transition is still successful. - # - # *Note* that if a +before+ callback fails and the bang version of an event - # was invoked, an exception will be raised instead of returning false. For - # example, - # - # class Vehicle - # state_machine :initial => :parked do - # before_transition any => :idling, :do => lambda {|vehicle| throw :halt} - # ... - # end - # end - # - # vehicle = Vehicle.new - # vehicle.park # => false - # vehicle.park! # => StateMachine::InvalidTransition: Cannot transition state via :park from "idling" - # - # == Observers - # - # Observers, in the sense of external classes and *not* Ruby's Observable - # mechanism, can hook into state machines as well. Such observers use the - # same callback api that's used internally. - # - # Below are examples of defining observers for the following state machine: - # - # class Vehicle - # state_machine do - # event :park do - # transition :idling => :parked - # end - # ... - # end - # ... - # end - # - # Event/Transition behaviors: - # - # class VehicleObserver - # def self.before_park(vehicle, transition) - # logger.info "#{vehicle} instructed to park... state is: #{transition.from}, state will be: #{transition.to}" - # end - # - # def self.after_park(vehicle, transition, result) - # logger.info "#{vehicle} instructed to park... state was: #{transition.from}, state is: #{transition.to}" - # end - # - # def self.before_transition(vehicle, transition) - # logger.info "#{vehicle} instructed to #{transition.event}... #{transition.attribute} is: #{transition.from}, #{transition.attribute} will be: #{transition.to}" - # end - # - # def self.after_transition(vehicle, transition, result) - # logger.info "#{vehicle} instructed to #{transition.event}... #{transition.attribute} was: #{transition.from}, #{transition.attribute} is: #{transition.to}" - # end - # end - # - # Vehicle.state_machine do - # before_transition :on => :park, :do => VehicleObserver.method(:before_park) - # before_transition VehicleObserver.method(:before_transition) - # - # after_transition :on => :park, :do => VehicleObserver.method(:after_park) - # after_transition VehicleObserver.method(:after_transition) - # end - # - # One common callback is to record transitions for all models in the system - # for auditing/debugging purposes. Below is an example of an observer that - # can easily automate this process for all models: - # - # class StateMachineObserver - # def self.before_transition(object, transition) - # Audit.log_transition(object.attributes) - # end - # end - # - # [Vehicle, Switch, Project].each do |klass| - # klass.state_machines.each do |machine| - # machine.before_transition klass.method(:before_transition) - # end - # end - # - # Additional observer-like behavior may be exposed by the various integrations - # available. See below for more information. - # - # == Overriding instance / class methods - # - # Hooking in behavior to the generated instance / class methods from the - # state machine, events, and states is very simple because of the way these - # methods are generated on the class. Using the class's ancestors, the - # original generated method can be referred to via +super+. For example, - # - # class Vehicle - # state_machine do - # event :park do - # transition :idling => :parked - # end - # end - # - # def park(kind = :parallel, *args) - # take_deep_breath if kind == :parallel - # super(*args) - # end - # - # def take_deep_breath - # sleep 3 - # end - # end - # - # In the above example, the +park+ instance method that's generated on the - # Vehicle class (by the associated event) is overriden with custom behavior - # that takes an additional argument. Once this behavior is complete, the - # original method from the state machine is invoked by simply calling - # <tt>super(*args)</tt>. - # - # The same technique can be used for +state+, +state_name+, and all other - # instance *and* class methods on the Vehicle class. - # - # == Integrations - # - # By default, state machines are library-agnostic, meaning that they work - # on any Ruby class and have no external dependencies. However, there are - # certain libraries which expose additional behavior that can be taken - # advantage of by state machines. - # - # This library is built to work out of the box with a few popular Ruby - # libraries that allow for additional behavior to provide a cleaner and - # smoother experience. This is especially the case for objects backed by a - # database that may allow for transactions, persistent storage, - # search/filters, callbacks, etc. - # - # When a state machine is defined for classes using any of the above libraries, - # it will try to automatically determine the integration to use (Agnostic, - # ActiveRecord, DataMapper, or Sequel) based on the class definition. To - # see how each integration affects the machine's behavior, refer to all - # constants defined under the StateMachine::Integrations namespace. - class Machine - include Assertions - include MatcherHelpers - - class << self - # The default message to use when invalidating objects that fail to - # transition when triggering an event - attr_accessor :default_invalid_message - - # Attempts to find or create a state machine for the given class. For - # example, - # - # StateMachine::Machine.find_or_create(Vehicle) - # StateMachine::Machine.find_or_create(Vehicle, :initial => :parked) - # StateMachine::Machine.find_or_create(Vehicle, :status) - # StateMachine::Machine.find_or_create(Vehicle, :status, :initial => :parked) - # - # If a machine of the given name already exists in one of the class's - # superclasses, then a copy of that machine will be created and stored - # in the new owner class (the original will remain unchanged). - def find_or_create(owner_class, *args, &block) - options = args.last.is_a?(Hash) ? args.pop : {} - attribute = args.first || :state - - # Attempts to find an existing machine - if owner_class.respond_to?(:state_machines) && machine = owner_class.state_machines[attribute] - # Create a copy of the state machine if it's being created by a subclass - unless machine.owner_class == owner_class - machine = machine.clone - machine.initial_state = options[:initial] if options.include?(:initial) - machine.owner_class = owner_class - end - - # Evaluate DSL caller block - machine.instance_eval(&block) if block_given? - else - # No existing machine: create a new one - machine = new(owner_class, attribute, options, &block) - end - - machine - end - - # Draws the state machines defined in the given classes using GraphViz. - # The given classes must be a comma-delimited string of class names. - # - # Configuration options: - # * <tt>:file</tt> - A comma-delimited string of files to load that - # contain the state machine definitions to draw - # * <tt>:path</tt> - The path to write the graph file to - # * <tt>:format</tt> - The image format to generate the graph in - # * <tt>:font</tt> - The name of the font to draw state names in - def draw(class_names, options = {}) - raise ArgumentError, 'At least one class must be specified' unless class_names && class_names.split(',').any? - - # Load any files - if files = options.delete(:file) - files.split(',').each {|file| require file} - end - - class_names.split(',').each do |class_name| - # Navigate through the namespace structure to get to the class - klass = Object - class_name.split('::').each do |name| - klass = klass.const_defined?(name) ? klass.const_get(name) : klass.const_missing(name) - end - - # Draw each of the class's state machines - klass.state_machines.each do |name, machine| - machine.draw(options) - end - end - end - end - - # Set defaults - self.default_invalid_message = 'cannot be transitioned via :%s from :%s' - - # The class that the machine is defined in - attr_accessor :owner_class - - # The attribute for which the machine is being defined - attr_reader :attribute - - # The events that trigger transitions. These are sorted, by default, in the - # order in which they were defined. - attr_reader :events - - # A list of all of the states known to this state machine. This will pull - # states from the following sources: - # * Initial state - # * State behaviors - # * Event transitions (:to, :from, and :except_from options) - # * Transition callbacks (:to, :from, :except_to, and :except_from options) - # * Unreferenced states (using +other_states+ helper) - # - # These are sorted, by default, in the order in which they were referenced. - attr_reader :states - - # The callbacks to invoke before/after a transition is performed - # - # Maps :before => callbacks and :after => callbacks - attr_reader :callbacks - - # The action to invoke when an object transitions - attr_reader :action - - # An identifier that forces all methods (including state predicates and - # event methods) to be generated with the value prefixed or suffixed, - # depending on the context. - attr_reader :namespace - - # Creates a new state machine for the given attribute - def initialize(owner_class, *args, &block) - options = args.last.is_a?(Hash) ? args.pop : {} - assert_valid_keys(options, :initial, :action, :plural, :namespace, :integration, :invalid_message) - - # Set machine configuration - @attribute = args.first || :state - @events = NodeCollection.new - @states = StateCollection.new - @callbacks = {:before => [], :after => []} - @namespace = options[:namespace] - @invalid_message = options[:invalid_message] - - self.owner_class = owner_class - self.initial_state = options[:initial] - - # Find an integration that matches this machine's owner class - if integration = options[:integration] ? StateMachine::Integrations.find(options[:integration]) : StateMachine::Integrations.match(owner_class) - extend integration - end - - # Set integration-specific configurations - @action = options.include?(:action) ? options[:action] : default_action - define_attribute_helpers - define_scopes(options[:plural]) - - # Call after hook for integration-specific extensions - after_initialize - - # Evaluate DSL caller block - instance_eval(&block) if block_given? - end - - # Creates a copy of this machine in addition to copies of each associated - # event/states/callback, so that the modifications to those collections do - # not affect the original machine. - def initialize_copy(orig) #:nodoc: - super - - @events = @events.dup - @events.machine = self - @states = @states.dup - @states.machine = self - @callbacks = {:before => @callbacks[:before].dup, :after => @callbacks[:after].dup} - end - - # Sets the class which is the owner of this state machine. Any methods - # generated by states, events, or other parts of the machine will be defined - # on the given owner class. - def owner_class=(klass) - @owner_class = klass - - # Add class-/instance-level methods to the owner class for state initialization - owner_class.class_eval do - extend StateMachine::ClassMethods - include StateMachine::InstanceMethods - end unless owner_class.included_modules.include?(StateMachine::InstanceMethods) - - # Create modules for extending the class with state/event-specific methods - class_helper_module = @class_helper_module = Module.new - instance_helper_module = @instance_helper_module = Module.new - owner_class.class_eval do - extend class_helper_module - include instance_helper_module - end - - # Record this machine as matched to the attribute in the current owner - # class. This will override any machines mapped to the same attribute - # in any superclasses. - owner_class.state_machines[attribute] = self - end - - # Sets the initial state of the machine. This can be either the static name - # of a state or a lambda block which determines the initial state at - # creation time. - def initial_state=(new_initial_state) - @initial_state = new_initial_state - add_states([@initial_state]) unless @initial_state.is_a?(Proc) - - # Update all states to reflect the new initial state - states.each {|state| state.initial = (state.name == @initial_state)} - end - - # Defines a new instance method with the given name on the machine's owner - # class. If the method is already defined in the class, then this will not - # override it. - # - # Not that in order for inheritance to work properly within state machines, - # any states/events/etc. must be referred to from the current state machine - # associated with the executing class. - # - # Example: - # - # attribute = machine.attribute - # machine.define_instance_method(:parked?) do |machine, object| - # machine.state?(object, :parked) - # end - def define_instance_method(method, &block) - attribute = self.attribute - - @instance_helper_module.class_eval do - define_method(method) do |*args| - block.call(self.class.state_machines[attribute], self, *args) - end - end - end - attr_reader :instance_helper_module - - # Defines a new class method with the given name on the machine's owner - # class. If the method is already defined in the class, then this will not - # override it. - # - # Not that in order for inheritance to work properly within state machines, - # any states/events/etc. must be referred to from the current state machine - # associated with the executing class. - # - # Example: - # - # machine.define_class_method(:states) do |machine, klass| - # machine.states.keys - # end - def define_class_method(method, &block) - attribute = self.attribute - - @class_helper_module.class_eval do - define_method(method) do |*args| - block.call(self.state_machines[attribute], self, *args) - end - end - end - - # Gets the initial state of the machine for the given object. If a dynamic - # initial state was configured for this machine, then the object will be - # passed into the lambda block to help determine the actual state. - # - # == Examples - # - # With a static initial state: - # - # class Vehicle - # state_machine :initial => :parked do - # ... - # end - # end - # - # vehicle = Vehicle.new - # Vehicle.state_machines[:state].initial_state(vehicle) # => #<StateMachine::State name=:parked value="parked" initial=true> - # - # With a dynamic initial state: - # - # class Vehicle - # attr_accessor :force_idle - # - # state_machine :initial => lambda {|vehicle| vehicle.force_idle ? :idling : :parked} do - # ... - # end - # end - # - # vehicle = Vehicle.new - # - # vehicle.force_idle = true - # Vehicle.state_machines[:state].initial_state(vehicle) # => #<StateMachine::State name=:idling value="idling" initial=false> - # - # vehicle.force_idle = false - # Vehicle.state_machines[:state].initial_state(vehicle) # => #<StateMachine::State name=:parked value="parked" initial=false> - def initial_state(object) - states.fetch(@initial_state.is_a?(Proc) ? @initial_state.call(object) : @initial_state) - end - - # Customizes the definition of one or more states in the machine. - # - # Configuration options: - # * <tt>:value</tt> - The actual value to store when an object transitions - # to the state. Default is the name (stringified). - # * <tt>:if</tt> - Determines whether an object's value matches the state - # (e.g. :value => lambda {Time.now}, :if => lambda {|state| !state.nil?}). - # By default, the configured value is matched. - # - # == Customizing the stored value - # - # Whenever a state is automatically discovered in the state machine, its - # default value is assumed to be the stringified version of the name. For - # example, - # - # class Vehicle - # state_machine :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # end - # end - # - # In the above state machine, there are two states automatically discovered: - # :parked and :idling. These states, by default, will store their stringified - # equivalents when an object moves into that states (e.g. "parked" / "idling"). - # - # For legacy systems or when tying state machines into existing frameworks, - # it's oftentimes necessary to need to store a different value for a state - # than the default. In order to continue taking advantage of an expressive - # state machine and helper methods, every defined state can be re-configured - # with a custom stored value. For example, - # - # class Vehicle - # state_machine :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # - # state :idling, :value => 'IDLING' - # state :parked, :value => 'PARKED - # end - # end - # - # This is also useful if being used in association with a database and, - # instead of storing the state name in a column, you want to store the - # state's foreign key: - # - # class VehicleState < ActiveRecord::Base - # end - # - # class Vehicle < ActiveRecord::Base - # state_machine :state_id, :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # - # states.each {|state| self.state(state.name, :value => VehicleState.find_by_name(state.name.to_s).id)} - # end - # end - # - # In the above example, each known state is configured to store it's - # associated database id in the +state_id+ attribute. - # - # === Dynamic values - # - # In addition to customizing states with other value types, lambda blocks - # can also be specified to allow for a state's value to be determined - # dynamically at runtime. For example, - # - # class Vehicle - # state_machine :purchased_at, :initial => :available do - # event :purchase do - # transition all => :purchased - # end - # - # event :restock do - # transition all => :available - # end - # - # state :available, :value => nil - # state :purchased, :if => lambda {|value| !value.nil?}, :value => lambda {Time.now} - # end - # end - # - # In the above definition, the <tt>:purchased</tt> state is customized with - # both a dynamic value *and* a value matcher. - # - # When an object transitions to the purchased state, the value's lambda - # block will be called. This will get the current time and store it in the - # object's +purchased_at+ attribute. - # - # *Note* that the custom matcher is very important here. Since there's no - # way for the state machine to figure out an object's state when it's set to - # a runtime value, it must be explicitly defined. If the <tt>:if</tt> option - # were not configured for the state, then an ArgumentError exception would - # be raised at runtime, indicating that the state machine could not figure - # out what the current state of the object was. - # - # == Behaviors - # - # Behaviors define a series of methods to mixin with objects when the current - # state matches the given one(s). This allows instance methods to behave - # a specific way depending on what the value of the object's state is. - # - # For example, - # - # class Vehicle - # attr_accessor :driver - # attr_accessor :passenger - # - # state_machine :initial => :parked do - # event :ignite do - # transition :parked => :idling - # end - # - # state :parked do - # def speed - # 0 - # end - # - # def rotate_driver - # driver = self.driver - # self.driver = passenger - # self.passenger = driver - # true - # end - # end - # - # state :idling, :first_gear do - # def speed - # 20 - # end - # - # def rotate_driver - # self.state = 'parked' - # rotate_driver - # end - # end - # - # other_states :backing_up - # end - # end - # - # In the above example, there are two dynamic behaviors defined for the - # class: - # * +speed+ - # * +rotate_driver+ - # - # Each of these behaviors are instance methods on the Vehicle class. However, - # which method actually gets invoked is based on the current state of the - # object. Using the above class as the example: - # - # vehicle = Vehicle.new - # vehicle.driver = 'John' - # vehicle.passenger = 'Jane' - # - # # Behaviors in the "parked" state - # vehicle.state # => "parked" - # vehicle.speed # => 0 - # vehicle.rotate_driver # => true - # vehicle.driver # => "Jane" - # vehicle.passenger # => "John" - # - # vehicle.ignite # => true - # - # # Behaviors in the "idling" state - # vehicle.state # => "idling" - # vehicle.speed # => 20 - # vehicle.rotate_driver # => true - # vehicle.driver # => "John" - # vehicle.passenger # => "Jane" - # vehicle.state # => "parked" - # - # As can be seen, both the +speed+ and +rotate_driver+ instance method - # implementations changed how they behave based on what the current state - # of the vehicle was. - # - # === Invalid behaviors - # - # If a specific behavior has not been defined for a state, then a - # NoMethodError exception will be raised, indicating that that method would - # not normally exist for an object with that state. - # - # Using the example from before: - # - # vehicle = Vehicle.new - # vehicle.state = 'backing_up' - # vehicle.speed # => NoMethodError: undefined method 'speed' for #<Vehicle:0xb7d296ac> in state "backing_up" - # - # == State-aware class methods - # - # In addition to defining scopes for instance methods that are state-aware, - # the same can be done for certain types of class methods. - # - # Some libraries have support for class-level methods that only run certain - # behaviors based on a conditions hash passed in. For example: - # - # class Vehicle < ActiveRecord::Base - # state_machine do - # ... - # state :first_gear, :second_gear, :third_gear do - # validates_presence_of :speed - # validates_inclusion_of :speed, :in => 0..25, :if => :in_school_zone? - # end - # end - # end - # - # In the above ActiveRecord model, two validations have been defined which - # will *only* run when the Vehicle object is in one of the three states: - # +first_gear+, +second_gear+, or +third_gear. Notice, also, that if/unless - # conditions can continue to be used. - # - # This functionality is not library-specific and can work for any class-level - # method that is defined like so: - # - # def validates_presence_of(attribute, options = {}) - # ... - # end - # - # The minimum requirement is that the last argument in the method be an - # options hash which contains at least <tt>:if</tt> condition support. - def state(*names, &block) - options = names.last.is_a?(Hash) ? names.pop : {} - assert_valid_keys(options, :value, :if) - - states = add_states(names) - states.each do |state| - if options.include?(:value) - state.value = options[:value] - self.states.update(state) - end - - state.matcher = options[:if] if options.include?(:if) - state.context(&block) if block_given? - end - - states.length == 1 ? states.first : states - end - alias_method :other_states, :state - - # Determines whether the given object is in a specific state. If the - # object's current value doesn't match the state, then this will return - # false, otherwise true. If the given state is unknown, then an ArgumentError - # will be raised. - # - # == Examples - # - # class Vehicle - # state_machine :initial => :parked do - # other_states :idling - # end - # end - # - # machine = Vehicle.state_machines[:state] - # vehicle = Vehicle.new # => #<Vehicle:0xb7c464b0 @state="parked"> - # - # machine.state?(vehicle, :parked) # => true - # machine.state?(vehicle, :idling) # => false - # machine.state?(vehicle, :invalid) # => ArgumentError: :invalid is an invalid key for :name index - def state?(object, name) - states.fetch(name).matches?(object.send(attribute)) - end - - # Determines the current state of the given object as configured by this - # state machine. This will attempt to find a known state that matches - # the value of the attribute on the object. If no state is found, then - # an ArgumentError will be raised. - # - # == Examples - # - # class Vehicle - # state_machine :initial => :parked do - # other_states :idling - # end - # end - # - # machine = Vehicle.state_machines[:state] - # - # vehicle = Vehicle.new # => #<Vehicle:0xb7c464b0 @state="parked"> - # machine.state_for(vehicle) # => #<StateMachine::State name=:parked value="parked" initial=true> - # - # vehicle.state = 'idling' - # machine.state_for(vehicle) # => #<StateMachine::State name=:idling value="idling" initial=true> - # - # vehicle.state = 'invalid' - # machine.state_for(vehicle) # => ArgumentError: "invalid" is not a known state value - def state_for(object) - value = object.send(attribute) - state = states[value, :value] || states.detect {|state| state.matches?(value)} - raise ArgumentError, "#{value.inspect} is not a known #{attribute} value" unless state - - state - end - - # Defines one or more events for the machine and the transitions that can - # be performed when those events are run. - # - # This method is also aliased as +on+ for improved compatibility with - # using a domain-specific language. - # - # == Instance methods - # - # The following instance methods are generated when a new event is defined - # (the "park" event is used as an example): - # * <tt>can_park?</tt> - Checks whether the "park" event can be fired given - # the current state of the object. - # * <tt>next_park_transition</tt> - Gets the next transition that would be - # performed if the "park" event were to be fired now on the object or nil - # if no transitions can be performed. - # * <tt>park(run_action = true)</tt> - Fires the "park" event, transitioning - # from the current state to the next valid state. - # * <tt>park!(run_action = true)</tt> - Fires the "park" event, transitioning - # from the current state to the next valid state. If the transition fails, - # then a StateMachine::InvalidTransition error will be raised. - # - # With a namespace of "car", the above names map to the following methods: - # * <tt>can_park_car?</tt> - # * <tt>next_park_car_transition</tt> - # * <tt>park_car</tt> - # * <tt>park_car!</tt> - # - # == Defining transitions - # - # +event+ requires a block which allows you to define the possible - # transitions that can happen as a result of that event. For example, - # - # event :park, :stop do - # transition :idling => :parked - # end - # - # event :first_gear do - # transition :parked => :first_gear, :if => :seatbelt_on? - # end - # - # See StateMachine::Event#transition for more information on - # the possible options that can be passed in. - # - # *Note* that this block is executed within the context of the actual event - # object. As a result, you will not be able to reference any class methods - # on the model without referencing the class itself. For example, - # - # class Vehicle - # def self.safe_states - # [:parked, :idling, :stalled] - # end - # - # state_machine do - # event :park do - # transition Vehicle.safe_states => :parked - # end - # end - # end - # - # == Example - # - # class Vehicle - # state_machine do - # # The park, stop, and halt events will all share the given transitions - # event :park, :stop, :halt do - # transition [:idling, :backing_up] => :parked - # end - # - # event :stop do - # transition :first_gear => :idling - # end - # - # event :ignite do - # transition :parked => :idling - # end - # end - # end - def event(*names, &block) - events = names.collect do |name| - unless event = self.events[name] - self.events << event = Event.new(self, name) - end - - if block_given? - event.instance_eval(&block) - add_states(event.known_states) - end - - event - end - - events.length == 1 ? events.first : events - end - alias_method :on, :event - - # Creates a callback that will be invoked *before* a transition is - # performed so long as the given requirements match the transition. - # - # == The callback - # - # Callbacks must be defined as either the only argument, in the :do option, - # or as a block. For example, - # - # class Vehicle - # state_machine do - # before_transition :set_alarm - # before_transition all => :parked :do => :set_alarm - # before_transition all => :parked do |vehicle, transition| - # vehicle.set_alarm - # end - # ... - # end - # end - # - # == State requirements - # - # Callbacks can require that the machine be transitioning from and to - # specific states. These requirements use a Hash syntax to map beginning - # states to ending states. For example, - # - # before_transition :parked => :idling, :idling => :first_gear, :do => :set_alarm - # - # In this case, the +set_alarm+ callback will only be called if the machine - # is transitioning from +parked+ to +idling+ or from +idling+ to +parked+. - # - # To help define state requirements, a set of helpers are available for - # slightly more complex matching: - # * <tt>all</tt> - Matches every state/event in the machine - # * <tt>all - [:parked, :idling, ...]</tt> - Matches every state/event except those specified - # * <tt>any</tt> - An alias for +all+ (matches every state/event in the machine) - # * <tt>same</tt> - Matches the same state being transitioned from - # - # See StateMachine::MatcherHelpers for more information. - # - # Examples: - # - # before_transition :parked => [:idling, :first_gear], :do => ... # Matches from parked to idling or first_gear - # before_transition all - [:parked, :idling] => :idling, :do => ... # Matches from every state except parked and idling to idling - # before_transition all => :parked, :do => ... # Matches all states to parked - # before_transition any => same, :do => ... # Matches every loopback - # - # == Event requirements - # - # In addition to state requirements, an event requirement can be defined so - # that the callback is only invoked on specific events using the +on+ - # option. This can also use the same matcher helpers as the state - # requirements. - # - # Examples: - # - # before_transition :on => :ignite, :do => ... # Matches only on ignite - # before_transition :on => all - :ignite, :do => ... # Matches on every event except ignite - # before_transition :parked => :idling, :on => :ignite, :do => ... # Matches from parked to idling on ignite - # - # == Verbose Requirements - # - # Requirements can also be defined using verbose options rather than the - # implicit Hash syntax and helper methods described above. - # - # Configuration options: - # * <tt>:from</tt> - One or more states being transitioned from. If none - # are specified, then all states will match. - # * <tt>:to</tt> - One or more states being transitioned to. If none are - # specified, then all states will match. - # * <tt>:on</tt> - One or more events that fired the transition. If none - # are specified, then all events will match. - # * <tt>:except_from</tt> - One or more states *not* being transitioned from - # * <tt>:except_to</tt> - One more states *not* being transitioned to - # * <tt>:except_on</tt> - One or more events that *did not* fire the transition - # - # Examples: - # - # before_transition :from => :ignite, :to => :idling, :on => :park, :do => ... - # before_transition :except_from => :ignite, :except_to => :idling, :except_on => :park, :do => ... - # - # == Conditions - # - # In addition to the state/event requirements, a condition can also be - # defined to help determine whether the callback should be invoked. - # - # Configuration options: - # * <tt>:if</tt> - A method, proc or string to call to determine if the - # callback should occur (e.g. :if => :allow_callbacks, or - # :if => lambda {|user| user.signup_step > 2}). The method, proc or string - # should return or evaluate to a true or false value. - # * <tt>:unless</tt> - A method, proc or string to call to determine if the - # callback should not occur (e.g. :unless => :skip_callbacks, or - # :unless => lambda {|user| user.signup_step <= 2}). The method, proc or - # string should return or evaluate to a true or false value. - # - # Examples: - # - # before_transition :parked => :idling, :if => :moving? - # before_transition :on => :ignite, :unless => :seatbelt_on? - # - # === Accessing the transition - # - # In addition to passing the object being transitioned, the actual - # transition describing the context (e.g. event, from, to) can be accessed - # as well. This additional argument is only passed if the callback allows - # for it. - # - # For example, - # - # class Vehicle - # # Only specifies one parameter (the object being transitioned) - # before_transition :to => :parked, :do => lambda {|vehicle| vehicle.set_alarm} - # - # # Specifies 2 parameters (object being transitioned and actual transition) - # before_transition :to => :parked, :do => lambda {|vehicle, transition| vehicle.set_alarm(transition)} - # end - # - # *Note* that the object in the callback will only be passed in as an - # argument if callbacks are configured to *not* be bound to the object - # involved. This is the default and may change on a per-integration basis. - # - # See StateMachine::Transition for more information about the - # attributes available on the transition. - # - # == Examples - # - # Below is an example of a class with one state machine and various types - # of +before+ transitions defined for it: - # - # class Vehicle - # state_machine do - # # Before all transitions - # before_transition :update_dashboard - # - # # Before specific transition: - # before_transition [:first_gear, :idling] => :parked, :on => :park, :do => :take_off_seatbelt - # - # # With conditional callback: - # before_transition :to => :parked, :do => :take_off_seatbelt, :if => :seatbelt_on? - # - # # Using helpers: - # before_transition all - :stalled => same, :on => any - :crash, :do => :update_dashboard - # ... - # end - # end - # - # As can be seen, any number of transitions can be created using various - # combinations of configuration options. - def before_transition(options = {}, &block) - add_callback(:before, options.is_a?(Hash) ? options : {:do => options}, &block) - end - - # Creates a callback that will be invoked *after* a transition is - # performed so long as the given requirements match the transition. - # - # See +before_transition+ for a description of the possible configurations - # for defining callbacks. - def after_transition(options = {}, &block) - add_callback(:after, options.is_a?(Hash) ? options : {:do => options}, &block) - end - - # Marks the given object as invalid after failing to transition via the - # given event. - # - # By default, this is a no-op. - def invalidate(object, event) - end - - # Resets an errors previously added when invalidating the given object - # - # By default, this is a no-op. - def reset(object) - end - - # Runs a transaction, rolling back any changes if the yielded block fails. - # - # This is only applicable to integrations that involve databases. By - # default, this will not run any transactions, since the changes aren't - # taking place within the context of a database. - def within_transaction(object) - yield - end - - # Draws a directed graph of the machine for visualizing the various events, - # states, and their transitions. - # - # This requires both the Ruby graphviz gem and the graphviz library be - # installed on the system. - # - # Configuration options: - # * <tt>:name</tt> - The name of the file to write to (without the file extension). - # Default is "#{owner_class.name}_#{attribute}" - # * <tt>:path</tt> - The path to write the graph file to. Default is the - # current directory ("."). - # * <tt>:format</tt> - The image format to generate the graph in. - # Default is "png'. - # * <tt>:font</tt> - The name of the font to draw state names in. - # Default is "Arial". - # * <tt>:orientation</tt> - The direction of the graph ("portrait" or - # "landscape"). Default is "portrait". - # * <tt>:output</tt> - Whether to generate the output of the graph - def draw(options = {}) - options = { - :name => "#{owner_class.name}_#{attribute}", - :path => '.', - :format => 'png', - :font => 'Arial', - :orientation => 'portrait', - :output => true - }.merge(options) - assert_valid_keys(options, :name, :path, :format, :font, :orientation, :output) - - begin - # Load the graphviz library - require 'rubygems' - require 'graphviz' - - graph = GraphViz.new('G', - :output => options[:format], - :file => File.join(options[:path], "#{options[:name]}.#{options[:format]}"), - :rankdir => options[:orientation] == 'landscape' ? 'LR' : 'TB' - ) - - # Add nodes - states.by_priority.each do |state| - node = state.draw(graph) - node.fontname = options[:font] - end - - # Add edges - events.each do |event| - edges = event.draw(graph) - edges.each {|edge| edge.fontname = options[:font]} - end - - # Generate the graph - graph.output if options[:output] - graph - rescue LoadError - $stderr.puts 'Cannot draw the machine. `gem install ruby-graphviz` and try again.' - false - end - end - - protected - # Runs additional initialization hooks. By default, this is a no-op. - def after_initialize - end - - # Gets the default action that should be invoked when performing a - # transition on the attribute for this machine. This may change - # depending on the configured integration for the owner class. - def default_action - end - - # Adds helper methods for interacting with this state machine's attribute, - # including reader, writer, and predicate methods - def define_attribute_helpers - define_attribute_accessor - define_attribute_predicate - - attribute = self.attribute - - # Gets the state name for the current value - define_instance_method("#{attribute}_name") do |machine, object| - machine.state_for(object).name - end - end - - # Adds reader/writer methods for accessing the attribute - def define_attribute_accessor - attribute = self.attribute - - @instance_helper_module.class_eval do - attr_reader attribute - attr_writer attribute - end - end - - # Adds predicate method to the owner class for determining the name of the - # current state - def define_attribute_predicate - attribute = self.attribute - - # Checks whether the current state is a given value - define_instance_method("#{attribute}?") do |machine, object, state| - machine.state?(object, state) - end - end - - # Defines the with/without scope helpers for this attribute. Both the - # singular and plural versions of the attribute are defined for each - # scope helper. A custom plural can be specified if it cannot be - # automatically determined by either calling +pluralize+ on the attribute - # name or adding an "s" to the end of the name. - def define_scopes(custom_plural = nil) - attribute = self.attribute - plural = custom_plural || (attribute.to_s.respond_to?(:pluralize) ? attribute.to_s.pluralize : "#{attribute}s") - - [attribute, plural].uniq.each do |name| - [:with, :without].each do |kind| - method = "#{kind}_#{name}" - - if scope = send("create_#{kind}_scope", method) - # Converts state names to their corresponding values so that they - # can be looked up properly - define_class_method(method) do |machine, klass, *states| - machine_states = machine.states - values = states.flatten.map {|state| machine_states.fetch(state).value} - - # Invoke the original scope implementation - scope.call(klass, values) - end - end - end - end - end - - # Creates a scope for finding objects *with* a particular value or values - # for the attribute. - # - # This is only applicable to specific integrations. - def create_with_scope(name) - end - - # Creates a scope for finding objects *without* a particular value or - # values for the attribute. - # - # This is only applicable to specific integrations. - def create_without_scope(name) - end - - # Adds a new transition callback of the given type. - def add_callback(type, options, &block) - callbacks[type] << callback = Callback.new(options, &block) - add_states(callback.known_states) - callback - end - - # Tracks the given set of states in the list of all known states for - # this machine - def add_states(new_states) - new_states.collect do |new_state| - unless state = states[new_state] - states << state = State.new(self, new_state) - end - - state - end - end - - # Generates the message to use when invalidating the given object after - # failing to transition on a specific event - def invalid_message(object, event) - (@invalid_message || self.class.default_invalid_message) % [event.name, state_for(object).name] - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/matcher.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/matcher.rb deleted file mode 100644 index 8e97a6f..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/matcher.rb +++ /dev/null @@ -1,123 +0,0 @@ -require 'singleton' - -module StateMachine - # Provides a general strategy pattern for determining whether a match is found - # for a value. The algorithm that actually determines the match depends on - # the matcher in use. - class Matcher - # The list of values against which queries are matched - attr_reader :values - - # Creates a new matcher for querying against the given set of values - def initialize(values = []) - @values = values.is_a?(Array) ? values : [values] - end - - # Generates a subset of values that exists in both the set of values being - # filtered and the values configured for the matcher - def filter(values) - self.values & values - end - end - - # Matches any given value. Since there is no configuration for this type of - # matcher, it must be used as a singleton. - class AllMatcher < Matcher - include Singleton - - # Generates a blacklist matcher based on the given set of values - # - # == Examples - # - # matcher = StateMachine::AllMatcher.new - [:parked, :idling] - # matcher.matches?(:parked) # => false - # matcher.matches?(:first_gear) # => true - def -(blacklist) - BlacklistMatcher.new(blacklist) - end - - # Always returns true - def matches?(value, context = {}) - true - end - - # Always returns the given set of values - def filter(values) - values - end - - # A human-readable description of this matcher. Always "all". - def description - 'all' - end - end - - # Matches a specific set of values - class WhitelistMatcher < Matcher - # Checks whether the given value exists within the whitelist configured - # for this matcher. - # - # == Examples - # - # matcher = StateMachine::WhitelistMatcher.new([:parked, :idling]) - # matcher.matches?(:parked) # => true - # matcher.matches?(:first_gear) # => false - def matches?(value, context = {}) - values.include?(value) - end - - # A human-readable description of this matcher - def description - values.length == 1 ? values.first.inspect : values.inspect - end - end - - # Matches everything but a specific set of values - class BlacklistMatcher < Matcher - # Checks whether the given value exists outside the blacklist configured - # for this matcher. - # - # == Examples - # - # matcher = StateMachine::BlacklistMatcher.new([:parked, :idling]) - # matcher.matches?(:parked) # => false - # matcher.matches?(:first_gear) # => true - def matches?(value, context = {}) - !values.include?(value) - end - - # Finds all values that are *not* within the blacklist configured for this - # matcher - def filter(values) - values - self.values - end - - # A human-readable description of this matcher - def description - "all - #{values.length == 1 ? values.first.inspect : values.inspect}" - end - end - - # Matches a loopback of two values within a context. Since there is no - # configuration for this type of matcher, it must be used as a singleton. - class LoopbackMatcher < Matcher - include Singleton - - # Checks whether the given value matches what the value originally was. - # This value should be defined in the context. - # - # == Examples - # - # matcher = StateMachine::LoopbackMatcher.new - # matcher.matches?(:parked, :from => :parked) # => true - # matcher.matches?(:parked, :from => :idling) # => false - def matches?(value, context) - context[:from] == value - end - - # A human-readable description of this matcher. Always "same". - def description - 'same' - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/matcher_helpers.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/matcher_helpers.rb deleted file mode 100644 index 2891779..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/matcher_helpers.rb +++ /dev/null @@ -1,53 +0,0 @@ -module StateMachine - # Provides a set of helper methods for generating matchers - module MatcherHelpers - # Represents a state that matches all known states in a machine. - # - # == Examples - # - # class Vehicle - # state_machine do - # before_transition any => :parked, :do => lambda {...} - # before_transition all - :parked => all - :idling, :do => lambda {} - # - # event :park - # transition all => :parked - # end - # - # event :crash - # transition all - :parked => :stalled - # end - # end - # end - # - # In the above example, +all+ will match the following states since they - # are known: - # * +parked+ - # * +stalled+ - def all - AllMatcher.instance - end - alias_method :any, :all - - # Represents a state that matches the original +from+ state. This is useful - # for defining transitions which are loopbacks. - # - # == Examples - # - # class Vehicle - # state_machine do - # event :ignite - # transition [:idling, :first_gear] => same - # end - # end - # end - # - # In the above example, +same+ will match whichever the from state is. In - # the case of the +ignite+ event, it is essential the same as the following: - # - # transition :parked => :parked, :first_gear => :first_gear - def same - LoopbackMatcher.instance - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/node_collection.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/node_collection.rb deleted file mode 100644 index 822b63b..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/node_collection.rb +++ /dev/null @@ -1,142 +0,0 @@ -require 'state_machine/assertions' - -module StateMachine - # Represents a collection of nodes in a state machine, be it events or states. - class NodeCollection - include Enumerable - include Assertions - - # Creates a new collection of nodes for the given state machine. By default, - # the collection is empty. - # - # Configuration options: - # * <tt>:index</tt> - One or more attributes to automatically generate - # hashed indices for in order to perform quick lookups. Default is to - # index by the :name attribute - def initialize(options = {}) - assert_valid_keys(options, :index) - options = {:index => :name}.merge(options) - - @nodes = [] - @indices = Array(options[:index]).inject({}) {|indices, attribute| indices[attribute] = {}; indices} - @default_index = Array(options[:index]).first - end - - # Creates a copy of this collection such that modifications don't affect - # the original collection - def initialize_copy(orig) #:nodoc: - super - - nodes = @nodes - @nodes = [] - @indices = @indices.inject({}) {|indices, (name, index)| indices[name] = {}; indices} - nodes.each {|node| self << node.dup} - end - - # Changes the current machine associated with the collection. In turn, this - # will change the state machine associated with each node in the collection. - def machine=(new_machine) - each {|node| node.machine = new_machine} - end - - # Gets the number of nodes in this collection - def length - @nodes.length - end - - # Gets the set of unique keys for the given index - def keys(index_name = @default_index) - index(index_name).keys - end - - # Adds a new node to the collection. By doing so, this will also add it to - # the configured indices. - def <<(node) - @nodes << node - @indices.each {|attribute, index| index[node.send(attribute)] = node} - self - end - - # Updates the indexed keys for the given node. If the node's attribute - # has changed since it was added to the collection, the old indexed keys - # will be replaced with the updated ones. - def update(node) - @indices.each do |attribute, index| - old_key = index.respond_to?(:key) ? index.key(node) : index.index(node) - new_key = node.send(attribute) - - # Only replace the key if it's changed - if old_key != new_key - index.delete(old_key) - index[new_key] = node - end - end - end - - # Calls the block once for each element in self, passing that element as a - # parameters. - # - # states = StateMachine::NodeCollection.new - # states << StateMachine::State.new(machine, :parked) - # states << StateMachine::State.new(machine, :idling) - # states.each {|state| puts state.name, ' -- '} - # - # ...produces: - # - # parked -- idling -- - def each - @nodes.each {|node| yield node} - self - end - - # Gets the node at the given index. - # - # states = StateMachine::NodeCollection.new - # states << StateMachine::State.new(machine, :parked) - # states << StateMachine::State.new(machine, :idling) - # - # states.at(0).name # => :parked - # states.at(1).name # => :idling - def at(index) - @nodes[index] - end - - # Gets the node indexed by the given key. By default, this will look up the - # key in the first index configured for the collection. A custom index can - # be specified like so: - # - # collection['parked', :value] - # - # The above will look up the "parked" key in a hash indexed by each node's - # +value+ attribute. - # - # If the key cannot be found, then nil will be returned. - def [](key, index_name = @default_index) - index(index_name)[key] - end - - # Gets the node indexed by the given key. By default, this will look up the - # key in the first index configured for the collection. A custom index can - # be specified like so: - # - # collection['parked', :value] - # - # The above will look up the "parked" key in a hash indexed by each node's - # +value+ attribute. - # - # If the key cannot be found, then an IndexError exception will be raised: - # - # collection['invalid', :value] # => IndexError: "invalid" is an invalid value - def fetch(key, index_name = @default_index) - self[key, index_name] || raise(ArgumentError, "#{key.inspect} is an invalid #{index_name}") - end - - private - # Gets the given index. If the index does not exist, then an ArgumentError - # is raised. - def index(name) - raise ArgumentError, 'No indices configured' unless @indices.any? - @indices[name] || raise(ArgumentError, "Invalid index: #{name.inspect}") - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/state.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/state.rb deleted file mode 100644 index b79e2ec..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/state.rb +++ /dev/null @@ -1,237 +0,0 @@ -require 'state_machine/assertions' -require 'state_machine/condition_proxy' - -module StateMachine - # A state defines a value that an attribute can be in after being transitioned - # 0 or more times. States can represent a value of any type in Ruby, though - # the most common (and default) type is String. - # - # In addition to defining the machine's value, a state can also define a - # behavioral context for an object when that object is in the state. See - # StateMachine::Machine#state for more information about how state-driven - # behavior can be utilized. - class State - include Assertions - - # The state machine for which this state is defined - attr_accessor :machine - - # The unique identifier for the state used in event and callback definitions - attr_reader :name - - # The value that is written to a machine's attribute when an object - # transitions into this state - attr_writer :value - - # Whether or not this state is the initial state to use for new objects - attr_accessor :initial - alias_method :initial?, :initial - - # A custom lambda block for determining whether a given value matches this - # state - attr_accessor :matcher - - # Tracks all of the methods that have been defined for the machine's owner - # class when objects are in this state. - # - # Maps :method_name => UnboundMethod - attr_reader :methods - - # Creates a new state within the context of the given machine. - # - # Configuration options: - # * <tt>:initial</tt> - Whether this state is the beginning state for the - # machine. Default is false. - # * <tt>:value</tt> - The value to store when an object transitions to this - # state. Default is the name (stringified). - # * <tt>:if</tt> - Determines whether a value matches this state - # (e.g. :value => lambda {Time.now}, :if => lambda {|state| !state.nil?}). - # By default, the configured value is matched. - def initialize(machine, name, options = {}) #:nodoc: - assert_valid_keys(options, :initial, :value, :if) - - @machine = machine - @name = name - @value = options.include?(:value) ? options[:value] : name && name.to_s - @matcher = options[:if] - @methods = {} - @initial = options.include?(:initial) && options[:initial] - - add_predicate - end - - # Creates a copy of this state in addition to the list of associated - # methods to prevent conflicts across different states. - def initialize_copy(orig) #:nodoc: - super - @methods = methods.dup - end - - # Determines whether there are any states that can be transitioned to from - # this state. If there are none, then this state is considered *final*. - # Any objects in a final state will remain so forever given the current - # machine's definition. - def final? - !machine.events.any? do |event| - event.guards.any? do |guard| - guard.state_requirements.any? do |requirement| - requirement[:from].matches?(name) && !requirement[:to].matches?(name, :from => name) - end - end - end - end - - # Generates a human-readable description of this state's name / value: - # - # For example, - # - # State.new(machine, :parked).description # => "parked" - # State.new(machine, :parked, :value => :parked).description # => "parked" - # State.new(machine, :parked, :value => nil).description # => "parked (nil)" - # State.new(machine, :parked, :value => 1).description # => "parked (1)" - # State.new(machine, :parked, :value => lambda {Time.now}).description # => "parked (*) - def description - description = name ? name.to_s : name.inspect - description << " (#{@value.is_a?(Proc) ? '*' : @value.inspect})" unless name.to_s == @value.to_s - description - end - - # The value that represents this state. If the value is a lambda block, - # then it will be evaluated at this time. Otherwise, the static value is - # returned. - # - # For example, - # - # State.new(machine, :parked, :value => 1).value # => 1 - # State.new(machine, :parked, :value => lambda {Time.now}).value # => Tue Jan 01 00:00:00 UTC 2008 - def value - @value.is_a?(Proc) ? @value.call : @value - end - - # Determines whether this state matches the given value. If no matcher is - # configured, then this will check whether the values are equivalent. - # Otherwise, the matcher will determine the result. - # - # For example, - # - # # Without a matcher - # state = State.new(machine, :parked, :value => 1) - # state.matches?(1) # => true - # state.matches?(2) # => false - # - # # With a matcher - # state = State.new(machine, :parked, :value => lambda {Time.now}, :if => lambda {|value| !value.nil?}) - # state.matches?(nil) # => false - # state.matches?(Time.now) # => true - def matches?(other_value) - matcher ? matcher.call(other_value) : other_value == value - end - - # Defines a context for the state which will be enabled on instances of the - # owner class when the machine is in this state. - # - # This can be called multiple times. Each time a new context is created, a - # new module will be included in the owner class. - def context(&block) - owner_class = machine.owner_class - attribute = machine.attribute - name = self.name - - # Evaluate the method definitions - context = ConditionProxy.new(owner_class, lambda {|object| object.send("#{attribute}_name") == name}) - context.class_eval(&block) - - # Define all of the methods that were created in the module so that they - # don't override the core behavior (i.e. calling the state method) - context.instance_methods.each do |method| - unless owner_class.instance_methods.include?(method) - # Calls the method defined by the current state of the machine. This - # is done using string evaluation so that any block passed into the - # method can then be passed to the state's context method, which is - # not possible with lambdas in Ruby 1.8.6. - owner_class.class_eval <<-end_eval, __FILE__, __LINE__ - def #{method}(*args, &block) - self.class.state_machines[#{attribute.inspect}].state_for(self).call(self, #{method.inspect}, *args, &block) - end - end_eval - end - - # Track the method defined for the context so that it can be invoked - # at a later point in time - methods[method.to_sym] = context.instance_method(method) - end - - # Include the context so that it can be bound to the owner class (the - # context is considered an ancestor, so it's allowed to be bound) - owner_class.class_eval do - include context - end - - context - end - - # Calls a method defined in this state's context on the given object. All - # arguments and any block will be passed into the method defined. - # - # If the method has never been defined for this state, then a NoMethodError - # will be raised. - def call(object, method, *args, &block) - if context_method = methods[method.to_sym] - # Method is defined by the state: proxy it through - context_method.bind(object).call(*args, &block) - else - # Raise exception as if the method never existed on the original object - raise NoMethodError, "undefined method '#{method}' for #{object} in state #{machine.state_for(object).name.inspect}" - end - end - - # Draws a representation of this state on the given machine. This will - # create a new node on the graph with the following properties: - # * +label+ - The human-friendly description of the state. - # * +width+ - The width of the node. Always 1. - # * +height+ - The height of the node. Always 1. - # * +shape+ - The actual shape of the node. If the state is the initial - # state, then "doublecircle", otherwise "circle". - # - # The actual node generated on the graph will be returned. - def draw(graph) - node = graph.add_node(name ? name.to_s : 'nil', - :label => description, - :width => '1', - :height => '1', - :shape => final? ? 'doublecircle' : 'ellipse' - ) - - # Add open arrow for initial state - graph.add_edge(graph.add_node('starting_state', :shape => 'point'), node) if initial? - - node - end - - # Generates a nicely formatted description of this state's contents. - # - # For example, - # - # state = StateMachine::State.new(machine, :parked, :value => 1, :initial => true) - # state # => #<StateMachine::State name=:parked value=1 initial=true context=[]> - def inspect - attributes = [[:name, name], [:value, @value], [:initial, initial?], [:context, methods.keys]] - "#<#{self.class} #{attributes.map {|attr, value| "#{attr}=#{value.inspect}"} * ' '}>" - end - - private - # Adds a predicate method to the owner class so long as a name has - # actually been configured for the state - def add_predicate - return unless name - - qualified_name = name = self.name - qualified_name = "#{machine.namespace}_#{name}" if machine.namespace - - # Checks whether the current value matches this state - machine.define_instance_method("#{qualified_name}?") do |machine, object| - machine.state?(object, name) - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/state_collection.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/state_collection.rb deleted file mode 100644 index 1d34bc3..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/state_collection.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'state_machine/node_collection' - -module StateMachine - # Represents a collection of states in a state machine - class StateCollection < NodeCollection - def initialize #:nodoc: - super(:index => [:name, :value]) - end - - # Gets the order in which states should be displayed based on where they - # were first referenced. This will order states in the following priority: - # - # 1. Initial state - # 2. Event transitions (:from, :except_from, :to, :except_to options) - # 3. States with behaviors - # 4. States referenced via +state+ or +other_states+ - # 5. States referenced in callbacks - # - # This order will determine how the GraphViz visualizations are rendered. - def by_priority - if first = @nodes.first - machine = first.machine - order = select {|state| state.initial}.map {|state| state.name} - - machine.events.each {|event| order += event.known_states} - order += select {|state| state.methods.any?}.map {|state| state.name} - order += keys(:name) - machine.callbacks.values.flatten.map {|callback| callback.known_states}.flatten - order += keys(:name) - - order.uniq! - order.map! {|name| self[name]} - order - else - [] - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/lib/state_machine/transition.rb b/vendor/plugins/state_machine-0.6.3/lib/state_machine/transition.rb deleted file mode 100644 index 230b8ed..0000000 --- a/vendor/plugins/state_machine-0.6.3/lib/state_machine/transition.rb +++ /dev/null @@ -1,138 +0,0 @@ -module StateMachine - # An invalid transition was attempted - class InvalidTransition < StandardError - end - - # A transition represents a state change for a specific attribute. - # - # Transitions consist of: - # * An event - # * A starting state - # * An ending state - class Transition - # The object being transitioned - attr_reader :object - - # The state machine for which this transition is defined - attr_reader :machine - - # The event that triggered the transition - attr_reader :event - - # The original state value *before* the transition - attr_reader :from - - # The original state name *before* the transition - attr_reader :from_name - - # The new state value *after* the transition - attr_reader :to - - # The new state name *after* the transition - attr_reader :to_name - - # Creates a new, specific transition - def initialize(object, machine, event, from_name, to_name) #:nodoc: - @object = object - @machine = machine - @event = event - @from = object.send(machine.attribute) - @from_name = from_name - @to = machine.states[to_name].value - @to_name = to_name - end - - # Gets the attribute which this transition's machine is defined for - def attribute - machine.attribute - end - - # Gets a hash of all the core attributes defined for this transition with - # their names as keys and values of the attributes as values. - # - # == Example - # - # machine = StateMachine.new(Vehicle) - # transition = StateMachine::Transition.new(Vehicle.new, machine, :ignite, :parked, :idling) - # transition.attributes # => {:object => #<Vehicle:0xb7d60ea4>, :attribute => :state, :event => :ignite, :from => 'parked', :to => 'idling'} - def attributes - @attributes ||= {:object => object, :attribute => attribute, :event => event, :from => from, :to => to} - end - - # Runs the actual transition and any before/after callbacks associated - # with the transition. The action associated with the transition/machine - # can be skipped by passing in +false+. - # - # == Examples - # - # class Vehicle - # state_machine :action => :save do - # ... - # end - # end - # - # vehicle = Vehicle.new - # transition = StateMachine::Transition.new(vehicle, machine, :ignite, :parked, :idling) - # transition.perform # => Runs the +save+ action after setting the state attribute - # transition.perform(false) # => Only sets the state attribute - def perform(run_action = true) - result = false - - machine.within_transaction(object) do - catch(:halt) do - # Run before callbacks - callback(:before) - - # Updates the object's attribute to the ending state - object.send("#{attribute}=", to) - result = run_action && machine.action ? object.send(machine.action) != false : true - - # Always run after callbacks regardless of whether the action failed. - # Result is included in case the callback depends on this value - callback(:after, result) - end - - # Make sure the transaction gets the correct return value for determining - # whether it should rollback or not - result = result != false - end - - result - end - - # Generates a nicely formatted description of this transitions's contents. - # - # For example, - # - # transition = StateMachine::Transition.new(object, machine, :ignite, :parked, :idling) - # transition # => #<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling> - def inspect - "#<#{self.class} #{%w(attribute event from from_name to to_name).map {|attr| "#{attr}=#{send(attr).inspect}"} * ' '}>" - end - - protected - # Gets a hash of the context defining this unique transition (including - # event, from state, and to state). - # - # == Example - # - # machine = StateMachine.new(Vehicle) - # transition = StateMachine::Transition.new(Vehicle.new, machine, :ignite, :parked, :idling) - # transition.context # => {:on => :ignite, :from => :parked, :to => :idling} - def context - @context ||= {:on => event, :from => from_name, :to => to_name} - end - - # Runs the callbacks of the given type for this transition. This will - # only invoke callbacks that exactly match the event, from state, and - # to state that describe this transition. - # - # Additional callback parameters can be specified. By default, this - # transition is also passed into callbacks. - def callback(type, *args) - machine.callbacks[type].each do |callback| - callback.call(object, context, self, *args) - end - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/classes/switch.rb b/vendor/plugins/state_machine-0.6.3/test/classes/switch.rb deleted file mode 100644 index adb4177..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/classes/switch.rb +++ /dev/null @@ -1,11 +0,0 @@ -class Switch - state_machine do - event :turn_on do - transition all => :on - end - - event :turn_off do - transition all => :off - end - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/functional/state_machine_test.rb b/vendor/plugins/state_machine-0.6.3/test/functional/state_machine_test.rb deleted file mode 100644 index 0250280..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/functional/state_machine_test.rb +++ /dev/null @@ -1,835 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class AutoShop - attr_accessor :num_customers - - def initialize - @num_customers = 0 - super() - end - - state_machine :initial => :available do - after_transition :available => any, :do => :increment_customers - after_transition :busy => any, :do => :decrement_customers - - event :tow_vehicle do - transition :available => :busy - end - - event :fix_vehicle do - transition :busy => :available - end - end - - # Increments the number of customers in service - def increment_customers - self.num_customers += 1 - end - - # Decrements the number of customers in service - def decrement_customers - self.num_customers -= 1 - end -end - -class Vehicle - attr_accessor :auto_shop, :seatbelt_on, :insurance_premium, :force_idle, :callbacks, :saved - - def initialize(attributes = {}) - attributes = { - :auto_shop => AutoShop.new, - :seatbelt_on => false, - :insurance_premium => 50, - :force_idle => false, - :callbacks => [], - :saved => false - }.merge(attributes) - - attributes.each {|attr, value| send("#{attr}=", value)} - super() - end - - # Defines the state machine for the state of the vehicled - state_machine :initial => lambda {|vehicle| vehicle.force_idle ? :idling : :parked}, :action => :save do - before_transition :parked => any, :do => :put_on_seatbelt - before_transition any => :stalled, :do => :increase_insurance_premium - after_transition any => :parked, :do => lambda {|vehicle| vehicle.seatbelt_on = false} - after_transition :on => :crash, :do => :tow - after_transition :on => :repair, :do => :fix - - # Callback tracking for initial state callbacks - after_transition any => :parked, :do => lambda {|vehicle| vehicle.callbacks << 'before_enter_parked'} - before_transition any => :idling, :do => lambda {|vehicle| vehicle.callbacks << 'before_enter_idling'} - - event :park do - transition [:idling, :first_gear] => :parked - end - - event :ignite do - transition :stalled => :stalled - transition :parked => :idling - end - - event :idle do - transition :first_gear => :idling - end - - event :shift_up do - transition :idling => :first_gear, :first_gear => :second_gear, :second_gear => :third_gear - end - - event :shift_down do - transition :third_gear => :second_gear - transition :second_gear => :first_gear - end - - event :crash do - transition [:first_gear, :second_gear, :third_gear] => :stalled, :if => lambda {|vehicle| vehicle.auto_shop.available?} - end - - event :repair do - transition :stalled => :parked, :if => :auto_shop_busy? - end - end - - state_machine :insurance_state, :initial => :inactive, :namespace => 'insurance' do - event :buy do - transition :inactive => :active - end - - event :cancel do - transition :active => :inactive - end - end - - def save - @saved = true - end - - def new_record? - @saved == false - end - - def park - super - end - - # Tows the vehicle to the auto shop - def tow - auto_shop.tow_vehicle - end - - # Fixes the vehicle; it will no longer be in the auto shop - def fix - auto_shop.fix_vehicle - end - - private - # Safety first! Puts on our seatbelt - def put_on_seatbelt - self.seatbelt_on = true - end - - # We crashed! Increase the insurance premium on the vehicle - def increase_insurance_premium - self.insurance_premium += 100 - end - - # Is the auto shop currently servicing another customer? - def auto_shop_busy? - auto_shop.busy? - end -end - -class Car < Vehicle - state_machine do - event :reverse do - transition [:parked, :idling, :first_gear] => :backing_up - end - - event :park do - transition :backing_up => :parked - end - - event :idle do - transition :backing_up => :idling - end - - event :shift_up do - transition :backing_up => :first_gear - end - end -end - -class Motorcycle < Vehicle - state_machine :initial => :idling -end - -class TrafficLight - state_machine :initial => :stop do - event :cycle do - transition :stop => :proceed, :proceed=> :caution, :caution => :stop - end - - state :stop do - def color - 'red' - end - end - - state :proceed do - def color - 'green' - end - end - - state :caution do - def color - 'yellow' - end - end - end -end - -class VehicleTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - end - - def test_should_not_allow_access_to_subclass_events - assert !@vehicle.respond_to?(:reverse) - end -end - -class VehicleUnsavedTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - end - - def test_should_be_in_parked_state - assert_equal 'parked', @vehicle.state - end - - def test_should_raise_exception_if_checking_invalid_state - assert_raise(ArgumentError) { @vehicle.state?(:invalid) } - end - - def test_should_raise_exception_if_getting_name_of_invalid_state - @vehicle.state = 'invalid' - assert_raise(ArgumentError) { @vehicle.state_name } - end - - def test_should_be_parked - assert @vehicle.parked? - assert @vehicle.state?(:parked) - assert_equal :parked, @vehicle.state_name - end - - def test_should_not_be_idling - assert !@vehicle.idling? - end - - def test_should_not_be_first_gear - assert !@vehicle.first_gear? - end - - def test_should_not_be_second_gear - assert !@vehicle.second_gear? - end - - def test_should_not_be_stalled - assert !@vehicle.stalled? - end - - def test_should_not_be_able_to_park - assert !@vehicle.can_park? - end - - def test_should_not_have_a_next_transition_for_park - assert_nil @vehicle.next_park_transition - end - - def test_should_not_allow_park - assert !@vehicle.park - end - - def test_should_be_able_to_ignite - assert @vehicle.can_ignite? - end - - def test_should_have_a_next_transition_for_ignite - transition = @vehicle.next_ignite_transition - assert_not_nil transition - assert_equal 'parked', transition.from - assert_equal 'idling', transition.to - assert_equal :ignite, transition.event - assert_equal :state, transition.attribute - assert_equal @vehicle, transition.object - end - - def test_should_allow_ignite - assert @vehicle.ignite - assert_equal 'idling', @vehicle.state - end - - def test_should_allow_ignite_with_skipped_action - assert @vehicle.ignite(false) - assert @vehicle.new_record? - end - - def test_should_allow_ignite_bang - assert @vehicle.ignite! - end - - def test_should_allow_ignite_bang_with_skipped_action - assert @vehicle.ignite!(false) - assert @vehicle.new_record? - end - - def test_should_be_saved_after_successful_event - @vehicle.ignite - assert !@vehicle.new_record? - end - - def test_should_not_allow_idle - assert !@vehicle.idle - end - - def test_should_not_allow_shift_up - assert !@vehicle.shift_up - end - - def test_should_not_allow_shift_down - assert !@vehicle.shift_down - end - - def test_should_not_allow_crash - assert !@vehicle.crash - end - - def test_should_not_allow_repair - assert !@vehicle.repair - end - - def test_should_be_insurance_inactive - assert @vehicle.insurance_inactive? - end - - def test_should_be_able_to_buy - assert @vehicle.can_buy_insurance? - end - - def test_should_allow_buying_insurance - assert @vehicle.buy_insurance - end - - def test_should_allow_buying_insurance_bang - assert @vehicle.buy_insurance! - end - - def test_should_allow_ignite_buying_insurance_with_skipped_action - assert @vehicle.buy_insurance!(false) - assert @vehicle.new_record? - end - - def test_should_not_be_insurance_active - assert !@vehicle.insurance_active? - end - - def test_should_not_be_able_to_cancel - assert !@vehicle.can_cancel_insurance? - end - - def test_should_not_allow_cancelling_insurance - assert !@vehicle.cancel_insurance - end -end - -class VehicleParkedTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - end - - def test_should_be_in_parked_state - assert_equal 'parked', @vehicle.state - end - - def test_should_not_have_the_seatbelt_on - assert !@vehicle.seatbelt_on - end - - def test_should_not_allow_park - assert !@vehicle.park - end - - def test_should_allow_ignite - assert @vehicle.ignite - assert_equal 'idling', @vehicle.state - end - - def test_should_not_allow_idle - assert !@vehicle.idle - end - - def test_should_not_allow_shift_up - assert !@vehicle.shift_up - end - - def test_should_not_allow_shift_down - assert !@vehicle.shift_down - end - - def test_should_not_allow_crash - assert !@vehicle.crash - end - - def test_should_not_allow_repair - assert !@vehicle.repair - end - - def test_should_raise_exception_if_repair_not_allowed! - assert_raise(StateMachine::InvalidTransition) {@vehicle.repair!} - end -end - -class VehicleIdlingTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - @vehicle.ignite - end - - def test_should_be_in_idling_state - assert_equal 'idling', @vehicle.state - end - - def test_should_be_idling - assert @vehicle.idling? - end - - def test_should_have_seatbelt_on - assert @vehicle.seatbelt_on - end - - def test_should_allow_park - assert @vehicle.park - end - - def test_should_not_allow_idle - assert !@vehicle.idle - end - - def test_should_allow_shift_up - assert @vehicle.shift_up - end - - def test_should_not_allow_shift_down - assert !@vehicle.shift_down - end - - def test_should_not_allow_crash - assert !@vehicle.crash - end - - def test_should_not_allow_repair - assert !@vehicle.repair - end -end - -class VehicleFirstGearTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - @vehicle.ignite - @vehicle.shift_up - end - - def test_should_be_in_first_gear_state - assert_equal 'first_gear', @vehicle.state - end - - def test_should_be_first_gear - assert @vehicle.first_gear? - end - - def test_should_allow_park - assert @vehicle.park - end - - def test_should_allow_idle - assert @vehicle.idle - end - - def test_should_allow_shift_up - assert @vehicle.shift_up - end - - def test_should_not_allow_shift_down - assert !@vehicle.shift_down - end - - def test_should_allow_crash - assert @vehicle.crash - end - - def test_should_not_allow_repair - assert !@vehicle.repair - end -end - -class VehicleSecondGearTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - @vehicle.ignite - 2.times {@vehicle.shift_up} - end - - def test_should_be_in_second_gear_state - assert_equal 'second_gear', @vehicle.state - end - - def test_should_be_second_gear - assert @vehicle.second_gear? - end - - def test_should_not_allow_park - assert !@vehicle.park - end - - def test_should_not_allow_idle - assert !@vehicle.idle - end - - def test_should_allow_shift_up - assert @vehicle.shift_up - end - - def test_should_allow_shift_down - assert @vehicle.shift_down - end - - def test_should_allow_crash - assert @vehicle.crash - end - - def test_should_not_allow_repair - assert !@vehicle.repair - end -end - -class VehicleThirdGearTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - @vehicle.ignite - 3.times {@vehicle.shift_up} - end - - def test_should_be_in_third_gear_state - assert_equal 'third_gear', @vehicle.state - end - - def test_should_be_third_gear - assert @vehicle.third_gear? - end - - def test_should_not_allow_park - assert !@vehicle.park - end - - def test_should_not_allow_idle - assert !@vehicle.idle - end - - def test_should_not_allow_shift_up - assert !@vehicle.shift_up - end - - def test_should_allow_shift_down - assert @vehicle.shift_down - end - - def test_should_allow_crash - assert @vehicle.crash - end - - def test_should_not_allow_repair - assert !@vehicle.repair - end -end - -class VehicleStalledTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - @vehicle.ignite - @vehicle.shift_up - @vehicle.crash - end - - def test_should_be_in_stalled_state - assert_equal 'stalled', @vehicle.state - end - - def test_should_be_stalled - assert @vehicle.stalled? - end - - def test_should_be_towed - assert @vehicle.auto_shop.busy? - assert_equal 1, @vehicle.auto_shop.num_customers - end - - def test_should_have_an_increased_insurance_premium - assert_equal 150, @vehicle.insurance_premium - end - - def test_should_not_allow_park - assert !@vehicle.park - end - - def test_should_allow_ignite - assert @vehicle.ignite - end - - def test_should_not_change_state_when_ignited - assert_equal 'stalled', @vehicle.state - end - - def test_should_not_allow_idle - assert !@vehicle.idle - end - - def test_should_now_allow_shift_up - assert !@vehicle.shift_up - end - - def test_should_not_allow_shift_down - assert !@vehicle.shift_down - end - - def test_should_not_allow_crash - assert !@vehicle.crash - end - - def test_should_allow_repair_if_auto_shop_is_busy - assert @vehicle.repair - end - - def test_should_not_allow_repair_if_auto_shop_is_available - @vehicle.auto_shop.fix_vehicle - assert !@vehicle.repair - end -end - -class VehicleRepairedTest < Test::Unit::TestCase - def setup - @vehicle = Vehicle.new - @vehicle.ignite - @vehicle.shift_up - @vehicle.crash - @vehicle.repair - end - - def test_should_be_in_parked_state - assert_equal 'parked', @vehicle.state - end - - def test_should_not_have_a_busy_auto_shop - assert @vehicle.auto_shop.available? - end -end - -class MotorcycleTest < Test::Unit::TestCase - def setup - @motorcycle = Motorcycle.new - end - - def test_should_be_in_idling_state - assert_equal 'idling', @motorcycle.state - end - - def test_should_allow_park - assert @motorcycle.park - end - - def test_should_not_allow_ignite - assert !@motorcycle.ignite - end - - def test_should_allow_shift_up - assert @motorcycle.shift_up - end - - def test_should_not_allow_shift_down - assert !@motorcycle.shift_down - end - - def test_should_not_allow_crash - assert !@motorcycle.crash - end - - def test_should_not_allow_repair - assert !@motorcycle.repair - end -end - -class CarTest < Test::Unit::TestCase - def setup - @car = Car.new - end - - def test_should_be_in_parked_state - assert_equal 'parked', @car.state - end - - def test_should_not_have_the_seatbelt_on - assert !@car.seatbelt_on - end - - def test_should_not_allow_park - assert !@car.park - end - - def test_should_allow_ignite - assert @car.ignite - assert_equal 'idling', @car.state - end - - def test_should_not_allow_idle - assert !@car.idle - end - - def test_should_not_allow_shift_up - assert !@car.shift_up - end - - def test_should_not_allow_shift_down - assert !@car.shift_down - end - - def test_should_not_allow_crash - assert !@car.crash - end - - def test_should_not_allow_repair - assert !@car.repair - end - - def test_should_allow_reverse - assert @car.reverse - end -end - -class CarBackingUpTest < Test::Unit::TestCase - def setup - @car = Car.new - @car.reverse - end - - def test_should_be_in_backing_up_state - assert_equal 'backing_up', @car.state - end - - def test_should_allow_park - assert @car.park - end - - def test_should_not_allow_ignite - assert !@car.ignite - end - - def test_should_allow_idle - assert @car.idle - end - - def test_should_allow_shift_up - assert @car.shift_up - end - - def test_should_not_allow_shift_down - assert !@car.shift_down - end - - def test_should_not_allow_crash - assert !@car.crash - end - - def test_should_not_allow_repair - assert !@car.repair - end - - def test_should_not_allow_reverse - assert !@car.reverse - end -end - -class AutoShopAvailableTest < Test::Unit::TestCase - def setup - @auto_shop = AutoShop.new - end - - def test_should_be_in_available_state - assert_equal 'available', @auto_shop.state - end - - def test_should_allow_tow_vehicle - assert @auto_shop.tow_vehicle - end - - def test_should_not_allow_fix_vehicle - assert !@auto_shop.fix_vehicle - end -end - -class AutoShopBusyTest < Test::Unit::TestCase - def setup - @auto_shop = AutoShop.new - @auto_shop.tow_vehicle - end - - def test_should_be_in_busy_state - assert_equal 'busy', @auto_shop.state - end - - def test_should_have_incremented_number_of_customers - assert_equal 1, @auto_shop.num_customers - end - - def test_should_not_allow_tow_vehicle - assert !@auto_shop.tow_vehicle - end - - def test_should_allow_fix_vehicle - assert @auto_shop.fix_vehicle - end -end - -class TrafficLightStopTest < Test::Unit::TestCase - def setup - @light = TrafficLight.new - @light.state = 'stop' - end - - def test_should_use_stop_color - assert_equal 'red', @light.color - end -end - -class TrafficLightProceedTest < Test::Unit::TestCase - def setup - @light = TrafficLight.new - @light.state = 'proceed' - end - - def test_should_use_proceed_color - assert_equal 'green', @light.color - end -end - -class TrafficLightCautionTest < Test::Unit::TestCase - def setup - @light = TrafficLight.new - @light.state = 'caution' - end - - def test_should_use_caution_color - assert_equal 'yellow', @light.color - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/test_helper.rb b/vendor/plugins/state_machine-0.6.3/test/test_helper.rb deleted file mode 100644 index 93e7d49..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/test_helper.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test/unit' - -$:.unshift(File.dirname(__FILE__) + '/../lib') -require File.dirname(__FILE__) + '/../init' diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/assertions_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/assertions_test.rb deleted file mode 100644 index 69ba257..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/assertions_test.rb +++ /dev/null @@ -1,40 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class AssertionsTest < Test::Unit::TestCase - include StateMachine::Assertions - - def default_test - end -end - -class AssertValidKeysTest < AssertionsTest - def test_should_not_raise_exception_if_key_is_valid - assert_nothing_raised { assert_valid_keys({:name => 'foo', :value => 'bar'}, :name, :value, :force) } - end - - def test_should_raise_exception_if_key_is_invalid - exception = assert_raise(ArgumentError) { assert_valid_keys({:name => 'foo', :value => 'bar', :invalid => true}, :name, :value, :force) } - assert_equal 'Invalid key(s): invalid', exception.message - end -end - -class AssertExclusiveKeysTest < AssertionsTest - def test_should_not_raise_exception_if_no_keys_found - assert_nothing_raised { assert_exclusive_keys({:on => :park}, :only, :except) } - end - - def test_should_not_raise_exception_if_one_key_found - assert_nothing_raised { assert_exclusive_keys({:only => :parked}, :only, :except) } - assert_nothing_raised { assert_exclusive_keys({:except => :parked}, :only, :except) } - end - - def test_should_raise_exception_if_two_keys_found - exception = assert_raise(ArgumentError) { assert_exclusive_keys({:only => :parked, :except => :parked}, :only, :except) } - assert_equal 'Conflicting keys: only, except', exception.message - end - - def test_should_raise_exception_if_multiple_keys_found - exception = assert_raise(ArgumentError) { assert_exclusive_keys({:only => :parked, :except => :parked, :on => :park}, :only, :except, :with) } - assert_equal 'Conflicting keys: only, except', exception.message - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/callback_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/callback_test.rb deleted file mode 100644 index d8549e0..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/callback_test.rb +++ /dev/null @@ -1,238 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class CallbackTest < Test::Unit::TestCase - def test_should_raise_exception_if_do_option_not_specified - exception = assert_raise(ArgumentError) { StateMachine::Callback.new } - assert_match ':do callback must be specified', exception.message - end - - def test_should_not_raise_exception_if_do_option_specified - assert_nothing_raised { StateMachine::Callback.new(:do => :run) } - end - - def test_should_not_raise_exception_if_implicit_option_specified - assert_nothing_raised { StateMachine::Callback.new(:do => :run, :invalid => true) } - end - - def test_should_not_bind_to_objects - assert !StateMachine::Callback.bind_to_object - end -end - -class CallbackByDefaultTest < Test::Unit::TestCase - def setup - @object = Object.new - @method = lambda {|*args| args.unshift(self)} - @callback = StateMachine::Callback.new(:do => @method) - end - - def test_should_not_have_a_terminator - assert_nil @callback.terminator - end - - def test_should_have_a_guard_with_all_matcher_requirements - assert_equal StateMachine::AllMatcher.instance, @callback.guard.event_requirement - assert_equal StateMachine::AllMatcher.instance, @callback.guard.state_requirements.first[:from] - assert_equal StateMachine::AllMatcher.instance, @callback.guard.state_requirements.first[:to] - end - - def test_should_not_bind_to_the_object - assert_equal [self, @object], @callback.call(@object) - end - - def test_should_not_have_any_known_states - assert_equal [], @callback.known_states - end -end - -class CallbackWithOnlyMethodTest < Test::Unit::TestCase - def setup - @object = Object.new - @callback = StateMachine::Callback.new(lambda {true}) - end - - def test_should_call_with_empty_context - assert @callback.call(@object) - end -end - -class CallbackWithExplicitRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @callback = StateMachine::Callback.new(:from => :parked, :to => :idling, :on => :ignite, :do => lambda {true}) - end - - def test_should_call_with_empty_context - assert @callback.call(@object, {}) - end - - def test_should_not_call_if_from_not_included - assert !@callback.call(@object, :from => :idling) - end - - def test_should_not_call_if_to_not_included - assert !@callback.call(@object, :to => :parked) - end - - def test_should_not_call_if_on_not_included - assert !@callback.call(@object, :on => :park) - end - - def test_should_call_if_all_requirements_met - assert @callback.call(@object, :from => :parked, :to => :idling, :on => :ignite) - end - - def test_should_include_in_known_states - assert_equal [:parked, :idling], @callback.known_states - end -end - -class CallbackWithImplicitRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @callback = StateMachine::Callback.new(:parked => :idling, :on => :ignite, :do => lambda {true}) - end - - def test_should_call_with_empty_context - assert @callback.call(@object, {}) - end - - def test_should_not_call_if_from_not_included - assert !@callback.call(@object, :from => :idling) - end - - def test_should_not_call_if_to_not_included - assert !@callback.call(@object, :to => :parked) - end - - def test_should_not_call_if_on_not_included - assert !@callback.call(@object, :on => :park) - end - - def test_should_call_if_all_requirements_met - assert @callback.call(@object, :from => :parked, :to => :idling, :on => :ignite) - end - - def test_should_include_in_known_states - assert_equal [:parked, :idling], @callback.known_states - end -end - -class CallbackWithIfConditionTest < Test::Unit::TestCase - def setup - @object = Object.new - end - - def test_should_call_if_true - callback = StateMachine::Callback.new(:if => lambda {true}, :do => lambda {true}) - assert callback.call(@object) - end - - def test_should_not_call_if_false - callback = StateMachine::Callback.new(:if => lambda {false}, :do => lambda {true}) - assert !callback.call(@object) - end -end - -class CallbackWithUnlessConditionTest < Test::Unit::TestCase - def setup - @object = Object.new - end - - def test_should_call_if_false - callback = StateMachine::Callback.new(:unless => lambda {false}, :do => lambda {true}) - assert callback.call(@object) - end - - def test_should_not_call_if_true - callback = StateMachine::Callback.new(:unless => lambda {true}, :do => lambda {true}) - assert !callback.call(@object) - end -end - -class CallbackWithoutTerminatorTest < Test::Unit::TestCase - def setup - @object = Object.new - end - - def test_should_not_halt_if_result_is_false - callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => nil) - assert_nothing_thrown { callback.call(@object) } - end -end - -class CallbackWithTerminatorTest < Test::Unit::TestCase - def setup - @object = Object.new - end - - def test_should_not_halt_if_terminator_does_not_match - callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| false}) - assert_nothing_thrown { callback.call(@object) } - end - - def test_should_halt_if_terminator_matches - callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| true}) - assert_throws(:halt) { callback.call(@object) } - end -end - -class CallbackWithoutArgumentsTest < Test::Unit::TestCase - def setup - @object = Object.new - @callback = StateMachine::Callback.new(:do => lambda {|object| object}) - end - - def test_should_call_method_with_object_as_argument - assert_equal @object, @callback.call(@object, {}, 1, 2, 3) - end -end - -class CallbackWithArgumentsTest < Test::Unit::TestCase - def setup - @object = Object.new - @callback = StateMachine::Callback.new(:do => lambda {|*args| args}) - end - - def test_should_call_method_with_all_arguments - assert_equal [@object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3) - end -end - -class CallbackWithUnboundObjectTest < Test::Unit::TestCase - def setup - @object = Object.new - @callback = StateMachine::Callback.new(:do => lambda {|*args| args.unshift(self)}) - end - - def test_should_call_method_outside_the_context_of_the_object - assert_equal [self, @object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3) - end -end - -class CallbackWithBoundObjectTest < Test::Unit::TestCase - def setup - @object = Object.new - @callback = StateMachine::Callback.new(:do => lambda {|*args| args.unshift(self)}, :bind_to_object => true) - end - - def test_should_call_method_within_the_context_of_the_object - assert_equal [@object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3) - end - - def test_should_ignore_option_for_symbolic_callbacks - class << @object - def after_ignite(*args) - args - end - end - - @callback = StateMachine::Callback.new(:do => :after_ignite, :bind_to_object => true) - assert_equal [], @callback.call(@object) - end - - def test_should_ignore_option_for_string_callbacks - @callback = StateMachine::Callback.new(:do => '[1, 2, 3]', :bind_to_object => true) - assert_equal [1, 2, 3], @callback.call(@object) - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/condition_proxy_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/condition_proxy_test.rb deleted file mode 100644 index 18e35b1..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/condition_proxy_test.rb +++ /dev/null @@ -1,301 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class Validateable - class << self - def validate(*args, &block) - args << block if block_given? - args - end - end -end - -class ConditionProxyTest < Test::Unit::TestCase - def test_should_call_class_with_same_arguments - options = {} - condition_proxy = StateMachine::ConditionProxy.new(Validateable, lambda {}) - validation = condition_proxy.validate(:name, options) - - assert_equal [:name, options], validation - end - - def test_should_pass_block_through_to_class - options = {} - condition_proxy = StateMachine::ConditionProxy.new(Validateable, lambda {}) - - proxy_block = lambda {} - validation = condition_proxy.validate(:name, options, &proxy_block) - - assert_equal [:name, options, proxy_block], validation - end - - def test_should_pass_object_into_proxy_condition - condition_args = [] - condition_proxy = StateMachine::ConditionProxy.new(Validateable, lambda {|*args| condition_args = args}) - validation = condition_proxy.validate(:name) - - object = Validateable.new - validation.last[:if].call(object) - - assert_equal [object], condition_args - end - - def test_should_evaluate_symbol_condition - klass = Class.new(Validateable) do - attr_accessor :callback_called - - def callback - @callback_called = true - end - end - - condition_proxy = StateMachine::ConditionProxy.new(klass, :callback) - validation = condition_proxy.validate(:name) - - object = klass.new - validation.last[:if].call(object) - - assert object.callback_called - end - - def test_should_evaluate_string_condition - klass = Class.new(Validateable) do - attr_accessor :callback_called - end - - condition_proxy = StateMachine::ConditionProxy.new(klass, '@callback_called = true') - validation = condition_proxy.validate(:name) - - object = klass.new - validation.last[:if].call(object) - - assert object.callback_called - end -end - -class ConditionProxyWithoutConditionsTest < Test::Unit::TestCase - def setup - @proxy_result = nil - condition_proxy = StateMachine::ConditionProxy.new(Validateable, lambda {@proxy_result}) - - @object = Validateable.new - @validation = condition_proxy.validate(:name) - @options = @validation.last - end - - def test_should_have_options_configuration - assert_instance_of Hash, @options - end - - def test_should_have_if_option - assert_not_nil @options[:if] - end - - def test_should_be_false_if_proxy_condition_is_false - @proxy_result = false - assert !@options[:if].call(@object) - end - - def test_should_be_true_if_proxy_condition_is_true - @proxy_result = true - assert @options[:if].call(@object) - end - - def test_should_be_true_if_proxy_condition_is_not_true - @proxy_result = 1 - assert @options[:if].call(@object) - end -end - -class ConditionProxyWithIfConditionTest < Test::Unit::TestCase - def setup - @proxy_result = nil - condition_proxy = StateMachine::ConditionProxy.new(Validateable, lambda {@proxy_result}) - - @object = Validateable.new - - @condition_result = nil - @validation = condition_proxy.validate(:name, :if => lambda {@condition_result}) - @options = @validation.pop - end - - def test_should_have_if_option - assert_not_nil @options[:if] - end - - def test_should_be_false_if_proxy_condition_is_false - @proxy_result = false - assert !@options[:if].call(@object) - end - - def test_should_be_false_if_original_condition_is_false - @condition_result = false - assert !@options[:if].call(@object) - end - - def test_should_be_true_if_proxy_and_original_condition_are_true - @proxy_result = true - @condition_result = true - assert @options[:if].call(@object) - end - - def test_should_evaluate_symbol_condition - klass = Class.new(Validateable) do - attr_accessor :callback - end - - condition_proxy = StateMachine::ConditionProxy.new(klass, lambda {true}) - validation = condition_proxy.validate(:name, :if => :callback) - options = validation.last - - object = klass.new - object.callback = false - assert !options[:if].call(object) - - object.callback = true - assert options[:if].call(object) - end - - def test_should_evaluate_string_condition - klass = Class.new(Validateable) do - attr_accessor :callback - end - - condition_proxy = StateMachine::ConditionProxy.new(klass, lambda {true}) - validation = condition_proxy.validate(:name, :if => '@callback') - options = validation.last - - object = klass.new - object.callback = false - assert !options[:if].call(object) - - object.callback = true - assert options[:if].call(object) - end -end - -class ConditionProxyWithMultipleIfConditionsTest < Test::Unit::TestCase - def setup - @proxy_result = true - condition_proxy = StateMachine::ConditionProxy.new(Validateable, lambda {@proxy_result}) - - @object = Validateable.new - - @first_condition_result = nil - @second_condition_result = nil - @validation = condition_proxy.validate(:name, :if => [lambda {@first_condition_result}, lambda {@second_condition_result}]) - @options = @validation.pop - end - - def test_should_be_true_if_all_conditions_are_true - @first_condition_result = true - @second_condition_result = true - assert @options[:if].call(@object) - end - - def test_should_be_false_if_any_condition_is_false - @first_condition_result = true - @second_condition_result = false - assert !@options[:if].call(@object) - - @first_condition_result = false - @second_condition_result = true - assert !@options[:if].call(@object) - end -end - -class ConditionProxyWithUnlessConditionTest < Test::Unit::TestCase - def setup - @proxy_result = nil - condition_proxy = StateMachine::ConditionProxy.new(Validateable, lambda {@proxy_result}) - - @object = Validateable.new - - @condition_result = nil - @validation = condition_proxy.validate(:name, :unless => lambda {@condition_result}) - @options = @validation.pop - end - - def test_should_have_if_option - assert_not_nil @options[:if] - end - - def test_should_be_false_if_proxy_condition_is_false - @proxy_result = false - assert !@options[:if].call(@object) - end - - def test_should_be_false_if_original_condition_is_true - @condition_result = true - assert !@options[:if].call(@object) - end - - def test_should_be_true_if_proxy_is_true_and_original_condition_is_false - @proxy_result = true - @condition_result = false - assert @options[:if].call(@object) - end - - def test_should_evaluate_symbol_condition - klass = Class.new(Validateable) do - attr_accessor :callback - end - - condition_proxy = StateMachine::ConditionProxy.new(klass, lambda {true}) - validation = condition_proxy.validate(:name, :unless => :callback) - options = validation.last - - object = klass.new - object.callback = true - assert !options[:if].call(object) - - object.callback = false - assert options[:if].call(object) - end - - def test_should_evaluate_string_condition - klass = Class.new(Validateable) do - attr_accessor :callback - end - - condition_proxy = StateMachine::ConditionProxy.new(klass, lambda {true}) - validation = condition_proxy.validate(:name, :unless => '@callback') - options = validation.last - - object = klass.new - object.callback = true - assert !options[:if].call(object) - - object.callback = false - assert options[:if].call(object) - end -end - -class ConditionProxyWithMultipleUnlessConditionsTest < Test::Unit::TestCase - def setup - @proxy_result = true - condition_proxy = StateMachine::ConditionProxy.new(Validateable, lambda {@proxy_result}) - - @object = Validateable.new - - @first_condition_result = nil - @second_condition_result = nil - @validation = condition_proxy.validate(:name, :unless => [lambda {@first_condition_result}, lambda {@second_condition_result}]) - @options = @validation.pop - end - - def test_should_be_true_if_all_conditions_are_false - @first_condition_result = false - @second_condition_result = false - assert @options[:if].call(@object) - end - - def test_should_be_false_if_any_condition_is_true - @first_condition_result = true - @second_condition_result = false - assert !@options[:if].call(@object) - - @first_condition_result = false - @second_condition_result = true - assert !@options[:if].call(@object) - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/eval_helpers_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/eval_helpers_test.rb deleted file mode 100644 index f1767aa..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/eval_helpers_test.rb +++ /dev/null @@ -1,111 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class EvalHelpersTest < Test::Unit::TestCase - include StateMachine::EvalHelpers - - def setup - @object = Object.new - end - - def test_should_raise_exception_if_method_is_not_symbol_string_or_proc - exception = assert_raise(ArgumentError) { evaluate_method(@object, 1) } - assert_match /Methods must/, exception.message - end -end - -class EvalHelpersSymbolTest < Test::Unit::TestCase - include StateMachine::EvalHelpers - - def setup - class << (@object = Object.new) - def callback - true - end - end - end - - def test_should_call_method_on_object_with_no_arguments - assert evaluate_method(@object, :callback, 1, 2, 3) - end -end - -class EvalHelpersSymbolWithArgumentsTest < Test::Unit::TestCase - include StateMachine::EvalHelpers - - def setup - class << (@object = Object.new) - def callback(*args) - args - end - end - end - - def test_should_call_method_with_all_arguments - assert_equal [1, 2, 3], evaluate_method(@object, :callback, 1, 2, 3) - end -end - -class EvalHelpersStringTest < Test::Unit::TestCase - include StateMachine::EvalHelpers - - def setup - @object = Object.new - end - - def test_should_evaluate_string - assert_equal 1, evaluate_method(@object, '1') - end - - def test_should_evaluate_string_within_object_context - @object.instance_variable_set('@value', 1) - assert_equal 1, evaluate_method(@object, '@value') - end - - def test_should_ignore_additional_arguments - assert_equal 1, evaluate_method(@object, '1', 2, 3, 4) - end -end - -class EvalHelpersProcTest < Test::Unit::TestCase - include StateMachine::EvalHelpers - - def setup - @object = Object.new - @proc = lambda {|obj| obj} - end - - def test_should_call_proc_with_object_as_argument - assert_equal @object, evaluate_method(@object, @proc, 1, 2, 3) - end -end - -class EvalHelpersProcWithoutArgumentsTest < Test::Unit::TestCase - include StateMachine::EvalHelpers - - def setup - @object = Object.new - @proc = lambda {|*args| args} - class << @proc - def arity - 0 - end - end - end - - def test_should_call_proc_with_no_arguments - assert_equal [], evaluate_method(@object, @proc, 1, 2, 3) - end -end - -class EvalHelpersProcWithArgumentsTest < Test::Unit::TestCase - include StateMachine::EvalHelpers - - def setup - @object = Object.new - @proc = lambda {|*args| args} - end - - def test_should_call_method_with_all_arguments - assert_equal [@object, 1, 2, 3], evaluate_method(@object, @proc, 1, 2, 3) - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/event_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/event_test.rb deleted file mode 100644 index 0229987..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/event_test.rb +++ /dev/null @@ -1,600 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class EventByDefaultTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @event = StateMachine::Event.new(@machine, :ignite) - - @object = @klass.new - end - - def test_should_have_a_machine - assert_equal @machine, @event.machine - end - - def test_should_have_a_name - assert_equal :ignite, @event.name - end - - def test_should_not_have_any_guards - assert @event.guards.empty? - end - - def test_should_have_no_known_states - assert @event.known_states.empty? - end - - def test_should_not_be_able_to_fire - assert !@event.can_fire?(@object) - end - - def test_should_not_have_a_next_transition - assert_nil @event.next_transition(@object) - end - - def test_should_define_a_predicate - assert @object.respond_to?(:can_ignite?) - end - - def test_should_define_a_transition_accessor - assert @object.respond_to?(:next_ignite_transition) - end - - def test_should_define_an_action - assert @object.respond_to?(:ignite) - end - - def test_should_define_a_bang_action - assert @object.respond_to?(:ignite!) - end -end - -class EventTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @event = StateMachine::Event.new(@machine, :ignite) - @event.transition :parked => :idling - end - - def test_should_allow_changing_machine - new_machine = StateMachine::Machine.new(Class.new) - @event.machine = new_machine - assert_equal new_machine, @event.machine - end - - def test_should_provide_matcher_helpers_during_initialization - matchers = [] - - @event.instance_eval do - matchers = [all, any, same] - end - - assert_equal [StateMachine::AllMatcher.instance, StateMachine::AllMatcher.instance, StateMachine::LoopbackMatcher.instance], matchers - end - - def test_should_use_pretty_inspect - assert_match "#<StateMachine::Event name=:ignite transitions=[:parked => :idling]>", @event.inspect - end -end - -class EventWithConflictingHelpersTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def can_ignite? - 0 - end - - def next_ignite_transition - 0 - end - - def ignite - 0 - end - - def ignite! - 0 - end - end - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::Event.new(@machine, :ignite) - @object = @klass.new - end - - def test_should_not_redefine_predicate - assert_equal 0, @object.can_ignite? - end - - def test_should_not_redefine_transition_accessor - assert_equal 0, @object.next_ignite_transition - end - - def test_should_not_redefine_action - assert_equal 0, @object.ignite - end - - def test_should_not_redefine_bang_action - assert_equal 0, @object.ignite! - end - - def test_should_allow_super_chaining - @klass.class_eval do - def can_ignite? - super ? 1 : 0 - end - - def next_ignite_transition - super ? 1 : 0 - end - - def ignite - super ? 1 : 0 - end - - def ignite! - begin - super - 1 - rescue Exception => ex - 0 - end - end - end - - assert_equal 0, @object.can_ignite? - assert_equal 0, @object.next_ignite_transition - assert_equal 0, @object.ignite - assert_equal 0, @object.ignite! - end -end - -class EventWithNamespaceTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :namespace => 'car') - @event = StateMachine::Event.new(@machine, :ignite) - @object = @klass.new - end - - def test_should_namespace_predicate - assert @object.respond_to?(:can_ignite_car?) - end - - def test_should_namespace_transition_accessor - assert @object.respond_to?(:next_ignite_car_transition) - end - - def test_should_namespace_action - assert @object.respond_to?(:ignite_car) - end - - def test_should_namespace_bang_action - assert @object.respond_to?(:ignite_car!) - end -end - -class EventTransitionsTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @event = StateMachine::Event.new(@machine, :ignite) - end - - def test_should_not_raise_exception_if_implicit_option_specified - assert_nothing_raised {@event.transition(:invalid => true)} - end - - def test_should_not_allow_on_option - exception = assert_raise(ArgumentError) {@event.transition(:on => :ignite)} - assert_equal 'Invalid key(s): on', exception.message - end - - def test_should_not_allow_except_to_option - exception = assert_raise(ArgumentError) {@event.transition(:except_to => :parked)} - assert_equal 'Invalid key(s): except_to', exception.message - end - - def test_should_not_allow_except_on_option - exception = assert_raise(ArgumentError) {@event.transition(:except_on => :ignite)} - assert_equal 'Invalid key(s): except_on', exception.message - end - - def test_should_allow_transitioning_without_a_to_state - assert_nothing_raised {@event.transition(:from => :parked)} - end - - def test_should_allow_transitioning_without_a_from_state - assert_nothing_raised {@event.transition(:to => :idling)} - end - - def test_should_allow_except_from_option - assert_nothing_raised {@event.transition(:except_from => :idling)} - end - - def test_should_allow_transitioning_from_a_single_state - assert @event.transition(:parked => :idling) - end - - def test_should_allow_transitioning_from_multiple_states - assert @event.transition([:parked, :idling] => :idling) - end - - def test_should_have_transitions - guard = @event.transition(:to => :idling) - assert_equal [guard], @event.guards - end -end - -class EventAfterBeingCopiedTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @event = StateMachine::Event.new(@machine, :ignite) - @copied_event = @event.dup - end - - def test_should_not_have_the_same_collection_of_guards - assert_not_same @event.guards, @copied_event.guards - end - - def test_should_not_have_the_same_collection_of_known_states - assert_not_same @event.known_states, @copied_event.known_states - end -end - -class EventWithoutTransitionsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @event = StateMachine::Event.new(@machine, :ignite) - @object = @klass.new - end - - def test_should_not_be_able_to_fire - assert !@event.can_fire?(@object) - end - - def test_should_not_have_a_next_transition - assert_nil @event.next_transition(@object) - end - - def test_should_not_fire - assert !@event.fire(@object) - end - - def test_should_raise_exception_on_fire! - exception = assert_raise(StateMachine::InvalidTransition) { @event.fire!(@object) } - assert_equal 'Cannot transition state via :ignite from nil', exception.message - end - - def test_should_not_change_the_current_state - @event.fire(@object) - assert_nil @object.state - end -end - -class EventWithTransitionsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @event = StateMachine::Event.new(@machine, :ignite) - @event.transition(:parked => :idling) - @event.transition(:first_gear => :idling) - end - - def test_should_include_all_transition_states_in_known_states - assert_equal [:parked, :idling, :first_gear], @event.known_states - end - - def test_should_include_new_transition_states_after_calling_known_states - @event.known_states - @event.transition(:stalled => :idling) - - assert_equal [:parked, :idling, :first_gear, :stalled], @event.known_states - end - - def test_should_use_pretty_inspect - assert_match "#<StateMachine::Event name=:ignite transitions=[:parked => :idling, :first_gear => :idling]>", @event.inspect - end -end - -class EventWithoutMatchingTransitionsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @machine.state :parked, :idling - - @event = StateMachine::Event.new(@machine, :ignite) - @event.transition(:parked => :idling) - - @object = @klass.new - @object.state = 'idling' - end - - def test_should_not_be_able_to_fire - assert !@event.can_fire?(@object) - end - - def test_should_not_have_a_next_transition - assert_nil @event.next_transition(@object) - end - - def test_should_not_fire - assert !@event.fire(@object) - end - - def test_should_raise_exception_on_fire! - exception = assert_raise(StateMachine::InvalidTransition) { @event.fire!(@object) } - assert_equal 'Cannot transition state via :ignite from :idling', exception.message - end - - def test_should_not_change_the_current_state - @event.fire(@object) - assert_equal 'idling', @object.state - end -end - -class EventWithMatchingDisabledTransitionsTest < Test::Unit::TestCase - def setup - StateMachine::Integrations.const_set('Custom', Module.new do - def invalidate(object, event) - (object.errors ||= []) << invalid_message(object, event) - end - - def reset(object) - object.errors = [] - end - end) - - @klass = Class.new do - attr_accessor :errors - end - - @machine = StateMachine::Machine.new(@klass, :integration => :custom) - @machine.state :parked, :idling - - @event = StateMachine::Event.new(@machine, :ignite) - @event.transition(:parked => :idling, :if => lambda {false}) - - @object = @klass.new - @object.state = 'parked' - end - - def test_should_not_be_able_to_fire - assert !@event.can_fire?(@object) - end - - def test_should_not_have_a_next_transition - assert_nil @event.next_transition(@object) - end - - def test_should_not_fire - assert !@event.fire(@object) - end - - def test_should_not_change_the_current_state - @event.fire(@object) - assert_equal 'parked', @object.state - end - - def test_should_invalidate_the_state - @event.fire(@object) - assert_equal ['cannot be transitioned via :ignite from :parked'], @object.errors - end - - def test_should_reset_existing_error - @object.errors = ['invalid'] - - @event.fire(@object) - assert_equal ['cannot be transitioned via :ignite from :parked'], @object.errors - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class EventWithMatchingEnabledTransitionsTest < Test::Unit::TestCase - def setup - StateMachine::Integrations.const_set('Custom', Module.new do - def invalidate(object, event) - (object.errors ||= []) << invalid_message(object, event) - end - - def reset(object) - object.errors = [] - end - end) - - @klass = Class.new do - attr_accessor :errors - end - - @machine = StateMachine::Machine.new(@klass, :integration => :custom) - @machine.state :parked, :idling - - @event = StateMachine::Event.new(@machine, :ignite) - @event.transition(:parked => :idling) - - @object = @klass.new - @object.state = 'parked' - end - - def test_should_be_able_to_fire - assert @event.can_fire?(@object) - end - - def test_should_have_a_next_transition - transition = @event.next_transition(@object) - assert_not_nil transition - assert_equal 'parked', transition.from - assert_equal 'idling', transition.to - assert_equal :ignite, transition.event - end - - def test_should_fire - assert @event.fire(@object) - end - - def test_should_change_the_current_state - @event.fire(@object) - assert_equal 'idling', @object.state - end - - def test_should_reset_existing_error - @object.errors = ['invalid'] - - @event.fire(@object) - assert_equal [], @object.errors - end - - def test_should_not_invalidate_the_state - @event.fire(@object) - assert_equal [], @object.errors - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class EventWithTransitionWithoutToStateTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @machine.state :parked - - @event = StateMachine::Event.new(@machine, :park) - @event.transition(:from => :parked) - - @object = @klass.new - @object.state = 'parked' - end - - def test_should_be_able_to_fire - assert @event.can_fire?(@object) - end - - def test_should_have_a_next_transition - transition = @event.next_transition(@object) - assert_not_nil transition - assert_equal 'parked', transition.from - assert_equal 'parked', transition.to - assert_equal :park, transition.event - end - - def test_should_fire - assert @event.fire(@object) - end - - def test_should_not_change_the_current_state - @event.fire(@object) - assert_equal 'parked', @object.state - end -end - -class EventWithTransitionWithNilToStateTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @machine.state nil - @machine.state :idling - - @event = StateMachine::Event.new(@machine, :park) - @event.transition(:idling => nil) - - @object = @klass.new - @object.state = 'idling' - end - - def test_should_be_able_to_fire - assert @event.can_fire?(@object) - end - - def test_should_have_a_next_transition - transition = @event.next_transition(@object) - assert_not_nil transition - assert_equal 'idling', transition.from - assert_equal nil, transition.to - assert_equal :park, transition.event - end - - def test_should_fire - assert @event.fire(@object) - end - - def test_should_not_change_the_current_state - @event.fire(@object) - assert_equal nil, @object.state - end -end - -class EventWithMultipleTransitionsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @machine.state :parked, :idling - - @event = StateMachine::Event.new(@machine, :ignite) - @event.transition(:idling => :idling) - @event.transition(:parked => :idling) # This one should get used - - @object = @klass.new - @object.state = 'parked' - end - - def test_should_be_able_to_fire - assert @event.can_fire?(@object) - end - - def test_should_have_a_next_transition - transition = @event.next_transition(@object) - assert_not_nil transition - assert_equal 'parked', transition.from - assert_equal 'idling', transition.to - assert_equal :ignite, transition.event - end - - def test_should_fire - assert @event.fire(@object) - end - - def test_should_change_the_current_state - @event.fire(@object) - assert_equal 'idling', @object.state - end -end - -begin - # Load library - require 'rubygems' - require 'graphviz' - - class EventDrawingTest < Test::Unit::TestCase - def setup - states = [:parked, :idling, :first_gear] - - @machine = StateMachine::Machine.new(Class.new, :initial => :parked) - @machine.other_states(*states) - - graph = GraphViz.new('G') - states.each {|state| graph.add_node(state.to_s)} - - @event = StateMachine::Event.new(@machine , :park) - @event.transition :parked => :idling - @event.transition :first_gear => :parked - @event.transition :except_from => :parked, :to => :parked - - @edges = @event.draw(graph) - end - - def test_should_generate_edges_for_each_transition - assert_equal 4, @edges.size - end - - def test_should_use_event_name_for_edge_label - assert_equal 'park', @edges.first['label'] - end - end -rescue LoadError - $stderr.puts 'Skipping GraphViz StateMachine::Event tests. `gem install ruby-graphviz` and try again.' -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/guard_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/guard_test.rb deleted file mode 100644 index fb0a933..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/guard_test.rb +++ /dev/null @@ -1,862 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class GuardTest < Test::Unit::TestCase - def setup - @guard = StateMachine::Guard.new(:from => :parked, :to => :idling) - end - - def test_should_not_raise_exception_if_implicit_option_specified - assert_nothing_raised { StateMachine::Guard.new(:invalid => true) } - end - - def test_should_not_have_an_if_condition - assert_nil @guard.if_condition - end - - def test_should_not_have_an_unless_condition - assert_nil @guard.unless_condition - end - - def test_should_have_a_state_requirement - assert_equal 1, @guard.state_requirements.length - end -end - -class GuardWithNoRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new - end - - def test_should_use_all_matcher_for_event_requirement - assert_equal StateMachine::AllMatcher.instance, @guard.event_requirement - end - - def test_should_use_all_matcher_for_from_state_requirement - assert_equal StateMachine::AllMatcher.instance, @guard.state_requirements.first[:from] - end - - def test_should_use_all_matcher_for_to_state_requirement - assert_equal StateMachine::AllMatcher.instance, @guard.state_requirements.first[:to] - end - - def test_should_match_nil_query - assert @guard.matches?(@object, nil) - end - - def test_should_match_empty_query - assert @guard.matches?(@object, {}) - end - - def test_should_match_non_empty_query - assert @guard.matches?(@object, :to => :idling, :from => :parked, :on => :ignite) - end - - def test_should_include_all_requirements_in_match - match = @guard.match(@object, nil) - - assert_equal @guard.state_requirements.first[:from], match[:from] - assert_equal @guard.state_requirements.first[:to], match[:to] - assert_equal @guard.event_requirement, match[:on] - end -end - -class GuardWithFromRequirementTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:from => :parked) - end - - def test_should_use_a_whitelist_matcher - assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from] - end - - def test_should_match_if_not_specified - assert @guard.matches?(@object, :to => :idling) - end - - def test_should_match_if_included - assert @guard.matches?(@object, :from => :parked) - end - - def test_should_not_match_if_not_included - assert !@guard.matches?(@object, :from => :idling) - end - - def test_should_not_match_if_nil - assert !@guard.matches?(@object, :from => nil) - end - - def test_should_ignore_to - assert @guard.matches?(@object, :from => :parked, :to => :idling) - end - - def test_should_ignore_on - assert @guard.matches?(@object, :from => :parked, :on => :ignite) - end - - def test_should_be_included_in_known_states - assert_equal [:parked], @guard.known_states - end - - def test_should_include_requirement_in_match - match = @guard.match(@object, :from => :parked) - assert_equal @guard.state_requirements.first[:from], match[:from] - end -end - -class GuardWithMultipleFromRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:from => [:idling, :parked]) - end - - def test_should_match_if_included - assert @guard.matches?(@object, :from => :idling) - end - - def test_should_not_match_if_not_included - assert !@guard.matches?(@object, :from => :first_gear) - end - - def test_should_be_included_in_known_states - assert_equal [:idling, :parked], @guard.known_states - end -end - -class GuardWithToRequirementTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:to => :idling) - end - - def test_should_use_a_whitelist_matcher - assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to] - end - - def test_should_match_if_not_specified - assert @guard.matches?(@object, :from => :parked) - end - - def test_should_match_if_included - assert @guard.matches?(@object, :to => :idling) - end - - def test_should_not_match_if_not_included - assert !@guard.matches?(@object, :to => :parked) - end - - def test_should_not_match_if_nil - assert !@guard.matches?(@object, :to => nil) - end - - def test_should_ignore_from - assert @guard.matches?(@object, :to => :idling, :from => :parked) - end - - def test_should_ignore_on - assert @guard.matches?(@object, :to => :idling, :on => :ignite) - end - - def test_should_be_included_in_known_states - assert_equal [:idling], @guard.known_states - end - - def test_should_include_requirement_in_match - match = @guard.match(@object, :to => :idling) - assert_equal @guard.state_requirements.first[:to], match[:to] - end -end - -class GuardWithMultipleToRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:to => [:idling, :parked]) - end - - def test_should_match_if_included - assert @guard.matches?(@object, :to => :idling) - end - - def test_should_not_match_if_not_included - assert !@guard.matches?(@object, :to => :first_gear) - end - - def test_should_be_included_in_known_states - assert_equal [:idling, :parked], @guard.known_states - end -end - -class GuardWithOnRequirementTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:on => :ignite) - end - - def test_should_use_a_whitelist_matcher - assert_instance_of StateMachine::WhitelistMatcher, @guard.event_requirement - end - - def test_should_match_if_not_specified - assert @guard.matches?(@object, :from => :parked) - end - - def test_should_match_if_included - assert @guard.matches?(@object, :on => :ignite) - end - - def test_should_not_match_if_not_included - assert !@guard.matches?(@object, :on => :park) - end - - def test_should_not_match_if_nil - assert !@guard.matches?(@object, :on => nil) - end - - def test_should_ignore_to - assert @guard.matches?(@object, :on => :ignite, :to => :parked) - end - - def test_should_ignore_from - assert @guard.matches?(@object, :on => :ignite, :from => :parked) - end - - def test_should_not_be_included_in_known_states - assert_equal [], @guard.known_states - end - - def test_should_include_requirement_in_match - match = @guard.match(@object, :on => :ignite) - assert_equal @guard.event_requirement, match[:on] - end -end - -class GuardWithMultipleOnRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:on => [:ignite, :park]) - end - - def test_should_match_if_included - assert @guard.matches?(@object, :on => :ignite) - end - - def test_should_not_match_if_not_included - assert !@guard.matches?(@object, :on => :shift_up) - end -end - -class GuardWithExceptFromRequirementTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:except_from => :parked) - end - - def test_should_use_a_blacklist_matcher - assert_instance_of StateMachine::BlacklistMatcher, @guard.state_requirements.first[:from] - end - - def test_should_match_if_not_included - assert @guard.matches?(@object, :from => :idling) - end - - def test_should_not_match_if_included - assert !@guard.matches?(@object, :from => :parked) - end - - def test_should_match_if_nil - assert @guard.matches?(@object, :from => nil) - end - - def test_should_ignore_to - assert @guard.matches?(@object, :from => :idling, :to => :parked) - end - - def test_should_ignore_on - assert @guard.matches?(@object, :from => :idling, :on => :ignite) - end - - def test_should_be_included_in_known_states - assert_equal [:parked], @guard.known_states - end -end - -class GuardWithMultipleExceptFromRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:except_from => [:idling, :parked]) - end - - def test_should_match_if_not_included - assert @guard.matches?(@object, :from => :first_gear) - end - - def test_should_not_match_if_included - assert !@guard.matches?(@object, :from => :idling) - end - - def test_should_be_included_in_known_states - assert_equal [:idling, :parked], @guard.known_states - end -end - -class GuardWithExceptToRequirementTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:except_to => :idling) - end - - def test_should_use_a_blacklist_matcher - assert_instance_of StateMachine::BlacklistMatcher, @guard.state_requirements.first[:to] - end - - def test_should_match_if_not_included - assert @guard.matches?(@object, :to => :parked) - end - - def test_should_not_match_if_included - assert !@guard.matches?(@object, :to => :idling) - end - - def test_should_match_if_nil - assert @guard.matches?(@object, :to => nil) - end - - def test_should_ignore_from - assert @guard.matches?(@object, :to => :parked, :from => :idling) - end - - def test_should_ignore_on - assert @guard.matches?(@object, :to => :parked, :on => :ignite) - end - - def test_should_be_included_in_known_states - assert_equal [:idling], @guard.known_states - end -end - -class GuardWithMultipleExceptToRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:except_to => [:idling, :parked]) - end - - def test_should_match_if_not_included - assert @guard.matches?(@object, :to => :first_gear) - end - - def test_should_not_match_if_included - assert !@guard.matches?(@object, :to => :idling) - end - - def test_should_be_included_in_known_states - assert_equal [:idling, :parked], @guard.known_states - end -end - -class GuardWithExceptOnRequirementTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:except_on => :ignite) - end - - def test_should_use_a_blacklist_matcher - assert_instance_of StateMachine::BlacklistMatcher, @guard.event_requirement - end - - def test_should_match_if_not_included - assert @guard.matches?(@object, :on => :park) - end - - def test_should_not_match_if_included - assert !@guard.matches?(@object, :on => :ignite) - end - - def test_should_match_if_nil - assert @guard.matches?(@object, :on => nil) - end - - def test_should_ignore_to - assert @guard.matches?(@object, :on => :park, :to => :idling) - end - - def test_should_ignore_from - assert @guard.matches?(@object, :on => :park, :from => :parked) - end - - def test_should_not_be_included_in_known_states - assert_equal [], @guard.known_states - end -end - -class GuardWithMultipleExceptOnRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:except_on => [:ignite, :park]) - end - - def test_should_match_if_not_included - assert @guard.matches?(@object, :on => :shift_up) - end - - def test_should_not_match_if_included - assert !@guard.matches?(@object, :on => :ignite) - end -end - -class GuardWithConflictingFromRequirementsTest < Test::Unit::TestCase - def test_should_raise_an_exception - exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:from => :parked, :except_from => :parked) } - assert_equal 'Conflicting keys: from, except_from', exception.message - end -end - -class GuardWithConflictingToRequirementsTest < Test::Unit::TestCase - def test_should_raise_an_exception - exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:to => :idling, :except_to => :idling) } - assert_equal 'Conflicting keys: to, except_to', exception.message - end -end - -class GuardWithConflictingOnRequirementsTest < Test::Unit::TestCase - def test_should_raise_an_exception - exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:on => :ignite, :except_on => :ignite) } - assert_equal 'Conflicting keys: on, except_on', exception.message - end -end - -class GuardWithDifferentRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:from => :parked, :to => :idling, :on => :ignite) - end - - def test_should_match_empty_query - assert @guard.matches?(@object) - end - - def test_should_match_if_all_requirements_match - assert @guard.matches?(@object, :from => :parked, :to => :idling, :on => :ignite) - end - - def test_should_not_match_if_from_not_included - assert !@guard.matches?(@object, :from => :idling) - end - - def test_should_not_match_if_to_not_included - assert !@guard.matches?(@object, :to => :parked) - end - - def test_should_not_match_if_on_not_included - assert !@guard.matches?(@object, :on => :park) - end - - def test_should_be_nil_if_unmatched - assert_nil @guard.match(@object, :from => :parked, :to => :idling, :on => :park) - end - - def test_should_include_all_known_states - assert_equal [:parked, :idling], @guard.known_states - end - - def test_should_not_duplicate_known_statse - guard = StateMachine::Guard.new(:except_from => :idling, :to => :idling, :on => :ignite) - assert_equal [:idling], guard.known_states - end -end - -class GuardWithNilRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:from => nil, :to => nil) - end - - def test_should_match_empty_query - assert @guard.matches?(@object) - end - - def test_should_match_if_all_requirements_match - assert @guard.matches?(@object, :from => nil, :to => nil) - end - - def test_should_not_match_if_from_not_included - assert !@guard.matches?(@object, :from => :parked) - end - - def test_should_not_match_if_to_not_included - assert !@guard.matches?(@object, :to => :idling) - end - - def test_should_include_all_known_states - assert_equal [nil], @guard.known_states - end -end - -class GuardWithImplicitRequirementTest < Test::Unit::TestCase - def setup - @guard = StateMachine::Guard.new(:parked => :idling, :on => :ignite) - end - - def test_should_create_an_event_requirement - assert_instance_of StateMachine::WhitelistMatcher, @guard.event_requirement - assert_equal [:ignite], @guard.event_requirement.values - end - - def test_should_use_a_whitelist_from_matcher - assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from] - end - - def test_should_use_a_whitelist_to_matcher - assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to] - end -end - -class GuardWithMultipleImplicitRequirementsTest < Test::Unit::TestCase - def setup - @object = Object.new - @guard = StateMachine::Guard.new(:parked => :idling, :idling => :first_gear, :on => :ignite) - end - - def test_should_create_multiple_state_requirements - assert_equal 2, @guard.state_requirements.length - end - - def test_should_not_match_event_as_state_requirement - assert !@guard.matches?(@object, :from => :on, :to => :ignite) - end - - def test_should_match_if_from_included_in_any - assert @guard.matches?(@object, :from => :parked) - assert @guard.matches?(@object, :from => :idling) - end - - def test_should_not_match_if_from_not_included_in_any - assert !@guard.matches?(@object, :from => :first_gear) - end - - def test_should_match_if_to_included_in_any - assert @guard.matches?(@object, :to => :idling) - assert @guard.matches?(@object, :to => :first_gear) - end - - def test_should_not_match_if_to_not_included_in_any - assert !@guard.matches?(@object, :to => :parked) - end - - def test_should_match_if_all_options_match - assert @guard.matches?(@object, :from => :parked, :to => :idling, :on => :ignite) - assert @guard.matches?(@object, :from => :idling, :to => :first_gear, :on => :ignite) - end - - def test_should_not_match_if_any_options_do_not_match - assert !@guard.matches?(@object, :from => :parked, :to => :idling, :on => :park) - assert !@guard.matches?(@object, :from => :parked, :to => :first_gear, :on => :park) - end - - def test_should_include_all_known_states - assert_equal [:first_gear, :idling, :parked], @guard.known_states.sort_by {|state| state.to_s} - end - - def test_should_not_duplicate_known_statse - guard = StateMachine::Guard.new(:parked => :idling, :first_gear => :idling) - assert_equal [:first_gear, :idling, :parked], guard.known_states.sort_by {|state| state.to_s} - end -end - -class GuardWithImplicitFromRequirementMatcherTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::BlacklistMatcher.new(:parked) - @guard = StateMachine::Guard.new(@matcher => :idling) - end - - def test_should_not_convert_from_to_whitelist_matcher - assert_equal @matcher, @guard.state_requirements.first[:from] - end - - def test_should_convert_to_to_whitelist_matcher - assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to] - end -end - -class GuardWithImplicitToRequirementMatcherTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::BlacklistMatcher.new(:idling) - @guard = StateMachine::Guard.new(:parked => @matcher) - end - - def test_should_convert_from_to_whitelist_matcher - assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from] - end - - def test_should_not_convert_to_to_whitelist_matcher - assert_equal @matcher, @guard.state_requirements.first[:to] - end -end - -class GuardWithImplicitAndExplicitRequirementsTest < Test::Unit::TestCase - def setup - @guard = StateMachine::Guard.new(:parked => :idling, :from => :parked) - end - - def test_should_create_multiple_requirements - assert_equal 2, @guard.state_requirements.length - end - - def test_should_create_implicit_requirements_for_implicit_options - assert(@guard.state_requirements.any? do |state_requirement| - state_requirement[:from].values == [:parked] && state_requirement[:to].values == [:idling] - end) - end - - def test_should_create_implicit_requirements_for_explicit_options - assert(@guard.state_requirements.any? do |state_requirement| - state_requirement[:from].values == [:from] && state_requirement[:to].values == [:parked] - end) - end -end - -class GuardWithIfConditionalTest < Test::Unit::TestCase - def setup - @object = Object.new - end - - def test_should_have_an_if_condition - guard = StateMachine::Guard.new(:if => lambda {true}) - assert_not_nil guard.if_condition - end - - def test_should_match_if_true - guard = StateMachine::Guard.new(:if => lambda {true}) - assert guard.matches?(@object) - end - - def test_should_not_match_if_false - guard = StateMachine::Guard.new(:if => lambda {false}) - assert !guard.matches?(@object) - end - - def test_should_be_nil_if_unmatched - guard = StateMachine::Guard.new(:if => lambda {false}) - assert_nil guard.match(@object) - end -end - -class GuardWithMultipleIfConditionalsTest < Test::Unit::TestCase - def setup - @object = Object.new - end - - def test_should_match_if_all_are_true - guard = StateMachine::Guard.new(:if => [lambda {true}, lambda {true}]) - assert guard.match(@object) - end - - def test_should_not_match_if_any_are_false - guard = StateMachine::Guard.new(:if => [lambda {true}, lambda {false}]) - assert !guard.match(@object) - - guard = StateMachine::Guard.new(:if => [lambda {false}, lambda {true}]) - assert !guard.match(@object) - end -end - -class GuardWithUnlessConditionalTest < Test::Unit::TestCase - def setup - @object = Object.new - end - - def test_should_have_an_unless_condition - guard = StateMachine::Guard.new(:unless => lambda {true}) - assert_not_nil guard.unless_condition - end - - def test_should_match_if_false - guard = StateMachine::Guard.new(:unless => lambda {false}) - assert guard.matches?(@object) - end - - def test_should_not_match_if_true - guard = StateMachine::Guard.new(:unless => lambda {true}) - assert !guard.matches?(@object) - end - - def test_should_be_nil_if_unmatched - guard = StateMachine::Guard.new(:unless => lambda {true}) - assert_nil guard.match(@object) - end -end - -class GuardWithMultipleUnlessConditionalsTest < Test::Unit::TestCase - def setup - @object = Object.new - end - - def test_should_match_if_all_are_false - guard = StateMachine::Guard.new(:unless => [lambda {false}, lambda {false}]) - assert guard.match(@object) - end - - def test_should_not_match_if_any_are_true - guard = StateMachine::Guard.new(:unless => [lambda {true}, lambda {false}]) - assert !guard.match(@object) - - guard = StateMachine::Guard.new(:unless => [lambda {false}, lambda {true}]) - assert !guard.match(@object) - end -end - -class GuardWithConflictingConditionalsTest < Test::Unit::TestCase - def test_should_match_if_if_is_true_and_unless_is_false - guard = StateMachine::Guard.new(:if => lambda {true}, :unless => lambda {false}) - assert guard.match(@object) - end - - def test_should_not_match_if_if_is_false_and_unless_is_true - guard = StateMachine::Guard.new(:if => lambda {false}, :unless => lambda {true}) - assert !guard.match(@object) - end - - def test_should_not_match_if_if_is_false_and_unless_is_false - guard = StateMachine::Guard.new(:if => lambda {false}, :unless => lambda {false}) - assert !guard.match(@object) - end - - def test_should_not_match_if_if_is_true_and_unless_is_true - guard = StateMachine::Guard.new(:if => lambda {true}, :unless => lambda {true}) - assert !guard.match(@object) - end -end - -begin - # Load library - require 'rubygems' - require 'graphviz' - - class GuardDrawingTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - states = [:parked, :idling] - - graph = GraphViz.new('G') - states.each {|state| graph.add_node(state.to_s)} - - @guard = StateMachine::Guard.new(:from => :idling, :to => :parked) - @edges = @guard.draw(graph, :park, states) - end - - def test_should_create_edges - assert_equal 1, @edges.size - end - - def test_should_use_from_state_from_start_node - assert_equal 'idling', @edges.first.instance_variable_get('@xNodeOne') - end - - def test_should_use_to_state_for_end_node - assert_equal 'parked', @edges.first.instance_variable_get('@xNodeTwo') - end - - def test_should_use_event_name_as_label - assert_equal 'park', @edges.first['label'] - end - end - - class GuardDrawingWithFromRequirementTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - states = [:parked, :idling, :first_gear] - - graph = GraphViz.new('G') - states.each {|state| graph.add_node(state.to_s)} - - @guard = StateMachine::Guard.new(:from => [:idling, :first_gear], :to => :parked) - @edges = @guard.draw(graph, :park, states) - end - - def test_should_generate_edges_for_each_valid_from_state - [:idling, :first_gear].each_with_index do |from_state, index| - edge = @edges[index] - assert_equal from_state.to_s, edge.instance_variable_get('@xNodeOne') - assert_equal 'parked', edge.instance_variable_get('@xNodeTwo') - end - end - end - - class GuardDrawingWithExceptFromRequirementTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - states = [:parked, :idling, :first_gear] - - graph = GraphViz.new('G') - states.each {|state| graph.add_node(state.to_s)} - - @guard = StateMachine::Guard.new(:except_from => :parked, :to => :parked) - @edges = @guard.draw(graph, :park, states) - end - - def test_should_generate_edges_for_each_valid_from_state - %w(idling first_gear).each_with_index do |from_state, index| - edge = @edges[index] - assert_equal from_state, edge.instance_variable_get('@xNodeOne') - assert_equal 'parked', edge.instance_variable_get('@xNodeTwo') - end - end - end - - class GuardDrawingWithoutFromRequirementTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - states = [:parked, :idling, :first_gear] - - graph = GraphViz.new('G') - states.each {|state| graph.add_node(state.to_s)} - - @guard = StateMachine::Guard.new(:to => :parked) - @edges = @guard.draw(graph, :park, states) - end - - def test_should_generate_edges_for_each_valid_from_state - %w(parked idling first_gear).each_with_index do |from_state, index| - edge = @edges[index] - assert_equal from_state, edge.instance_variable_get('@xNodeOne') - assert_equal 'parked', edge.instance_variable_get('@xNodeTwo') - end - end - end - - class GuardDrawingWithoutToRequirementTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - - graph = GraphViz.new('G') - graph.add_node('parked') - - @guard = StateMachine::Guard.new(:from => :parked) - @edges = @guard.draw(graph, :park, [:parked]) - end - - def test_should_create_loopback_edge - assert_equal 'parked', @edges.first.instance_variable_get('@xNodeOne') - assert_equal 'parked', @edges.first.instance_variable_get('@xNodeTwo') - end - end - - class GuardDrawingWithNilStateTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - - graph = GraphViz.new('G') - graph.add_node('parked') - - @guard = StateMachine::Guard.new(:from => :idling, :to => nil) - @edges = @guard.draw(graph, :park, [nil, :idling]) - end - - def test_should_generate_edges_for_each_valid_from_state - assert_equal 'idling', @edges.first.instance_variable_get('@xNodeOne') - assert_equal 'nil', @edges.first.instance_variable_get('@xNodeTwo') - end - end -rescue LoadError - $stderr.puts 'Skipping GraphViz StateMachine::Guard tests. `gem install ruby-graphviz` and try again.' -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/integrations/active_record_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/integrations/active_record_test.rb deleted file mode 100644 index a46ae24..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/integrations/active_record_test.rb +++ /dev/null @@ -1,815 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../../test_helper') - -begin - # Load library - require 'rubygems' - - gem 'activerecord', ENV['AR_VERSION'] ? "=#{ENV['AR_VERSION']}" : '>=2.1.0' - require 'active_record' - - FIXTURES_ROOT = File.dirname(__FILE__) + '/../../fixtures/' - - # Load TestCase helpers - require 'active_support/test_case' - require 'active_record/fixtures' - require 'active_record/test_case' - - # Set default fixtures configuration - ActiveSupport::TestCase.class_eval do - self.fixture_path = File.dirname(__FILE__) + '/../../fixtures/' - self.use_instantiated_fixtures = false - self.use_transactional_fixtures = true - end - - # Establish database connection - ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3', 'database' => ':memory:'}) - ActiveRecord::Base.logger = Logger.new("#{File.dirname(__FILE__)}/../../active_record.log") - - # Add model/observer creation helpers - ActiveRecord::TestCase.class_eval do - # Creates a new ActiveRecord model (and the associated table) - def new_model(create_table = true, &block) - model = Class.new(ActiveRecord::Base) do - connection.create_table(:foo, :force => true) {|t| t.string(:state)} if create_table - set_table_name('foo') - - def self.name; 'ActiveRecordTest::Foo'; end - end - model.class_eval(&block) if block_given? - model - end - - # Creates a new ActiveRecord observer - def new_observer(model, &block) - observer = Class.new(ActiveRecord::Observer) do - attr_accessor :notifications - - def initialize - super - @notifications = [] - end - end - observer.observe(model) - observer.class_eval(&block) if block_given? - observer - end - end - - module ActiveRecordTest - class IntegrationTest < ActiveRecord::TestCase - def test_should_match_if_class_inherits_from_active_record - assert StateMachine::Integrations::ActiveRecord.matches?(new_model) - end - - def test_should_not_match_if_class_does_not_inherit_from_active_record - assert !StateMachine::Integrations::ActiveRecord.matches?(Class.new) - end - end - - class MachineByDefaultTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model) - end - - def test_should_use_save_as_action - assert_equal :save, @machine.action - end - - def test_should_create_notifier_before_callback - assert_equal 1, @machine.callbacks[:before].size - end - - def test_should_create_notifier_after_callback - assert_equal 1, @machine.callbacks[:after].size - end - end - - class MachineTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model) - @machine.state :parked, :idling, :first_gear - end - - def test_should_create_singular_with_scope - assert @model.respond_to?(:with_state) - end - - def test_should_only_include_records_with_state_in_singular_with_scope - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - - assert_equal [parked], @model.with_state(:parked) - end - - def test_should_create_plural_with_scope - assert @model.respond_to?(:with_states) - end - - def test_should_only_include_records_with_states_in_plural_with_scope - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - - assert_equal [parked, idling], @model.with_states(:parked, :idling) - end - - def test_should_create_singular_without_scope - assert @model.respond_to?(:without_state) - end - - def test_should_only_include_records_without_state_in_singular_without_scope - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - - assert_equal [parked], @model.without_state(:idling) - end - - def test_should_create_plural_without_scope - assert @model.respond_to?(:without_states) - end - - def test_should_only_include_records_without_states_in_plural_without_scope - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - first_gear = @model.create :state => 'first_gear' - - assert_equal [parked, idling], @model.without_states(:first_gear) - end - - def test_should_allow_chaining_scopes - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - - assert_equal [idling], @model.without_state(:parked).with_state(:idling) - end - - def test_should_rollback_transaction_if_false - @machine.within_transaction(@model.new) do - @model.create - false - end - - assert_equal 0, @model.count - end - - def test_should_not_rollback_transaction_if_true - @machine.within_transaction(@model.new) do - @model.create - true - end - - assert_equal 1, @model.count - end - - def test_should_invalidate_using_errors - I18n.backend = I18n::Backend::Simple.new if Object.const_defined?(:I18n) - - record = @model.new - record.state = 'parked' - - @machine.invalidate(record, StateMachine::Event.new(@machine, :park)) - - assert record.errors.invalid?(:state) - assert_equal 'cannot be transitioned via :park from :parked', record.errors.on(:state) - end - - def test_should_clear_errors_on_reset - record = @model.new - record.state = 'parked' - record.errors.add(:state, 'is invalid') - - @machine.reset(record) - assert_nil record.errors.on(:id) - end - - def test_should_not_override_the_column_reader - record = @model.new - record[:state] = 'parked' - assert_equal 'parked', record.state - end - - def test_should_not_override_the_column_writer - record = @model.new - record.state = 'parked' - assert_equal 'parked', record[:state] - end - end - - class MachineWithoutDatabaseTest < ActiveRecord::TestCase - def setup - @model = new_model(false) do - # Simulate the database not being available entirely - def self.connection - raise ActiveRecord::ConnectionNotEstablished - end - end - end - - def test_should_allow_machine_creation - assert_nothing_raised { StateMachine::Machine.new(@model) } - end - end - - class MachineUnmigratedTest < ActiveRecord::TestCase - def setup - @model = new_model(false) - - # Drop the table so that it definitely doesn't exist - @model.connection.drop_table(:foo) if @model.connection.table_exists?(:foo) - end - - def test_should_allow_machine_creation - assert_nothing_raised { StateMachine::Machine.new(@model) } - end - end - - class MachineWithInitialStateTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model, :initial => :parked) - @record = @model.new - end - - def test_should_set_initial_state_on_created_object - assert_equal 'parked', @record.state - end - end - - class MachineWithColumnStateAttributeTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model, :initial => :parked) - @machine.other_states(:idling) - - @record = @model.new - end - - def test_should_have_an_attribute_predicate - assert @record.respond_to?(:state?) - end - - def test_should_test_for_existence_on_predicate_without_parameters - assert @record.state? - - @record.state = nil - assert !@record.state? - end - - def test_should_return_false_for_predicate_if_does_not_match_current_value - assert !@record.state?(:idling) - end - - def test_should_return_true_for_predicate_if_matches_current_value - assert @record.state?(:parked) - end - - def test_should_raise_exception_for_predicate_if_invalid_state_specified - assert_raise(ArgumentError) { @record.state?(:invalid) } - end - end - - class MachineWithNonColumnStateAttributeUndefinedTest < ActiveRecord::TestCase - def setup - @model = new_model do - def initialize - # Skip attribute initialization - end - end - - @machine = StateMachine::Machine.new(@model, :status, :initial => :parked) - @machine.other_states(:idling) - @record = @model.new - end - - def test_should_not_define_a_reader_attribute_for_the_attribute - assert !@record.respond_to?(:status) - end - - def test_should_not_define_a_writer_attribute_for_the_attribute - assert !@record.respond_to?(:status=) - end - - def test_should_define_an_attribute_predicate - assert @record.respond_to?(:status?) - end - - def test_should_raise_exception_on_predicate_without_parameters - old_verbose, $VERBOSE = $VERBOSE, nil - assert_raise(NoMethodError) { @record.status? } - ensure - $VERBOSE = old_verbose - end - end - - class MachineWithNonColumnStateAttributeDefinedTest < ActiveRecord::TestCase - def setup - @model = new_model do - attr_accessor :status - end - - @machine = StateMachine::Machine.new(@model, :status, :initial => :parked) - @machine.other_states(:idling) - @record = @model.new - end - - def test_should_return_false_for_predicate_if_does_not_match_current_value - assert !@record.status?(:idling) - end - - def test_should_return_true_for_predicate_if_matches_current_value - assert @record.status?(:parked) - end - - def test_should_raise_exception_for_predicate_if_invalid_state_specified - assert_raise(ArgumentError) { @record.status?(:invalid) } - end - - def test_should_set_initial_state_on_created_object - assert_equal 'parked', @record.status - end - end - - class MachineWithComplexPluralizationTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model, :status) - end - - def test_should_create_singular_with_scope - assert @model.respond_to?(:with_status) - end - - def test_should_create_plural_with_scope - assert @model.respond_to?(:with_statuses) - end - end - - class MachineWithCallbacksTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model, :initial => :parked) - @machine.other_states :idling - - @record = @model.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - end - - def test_should_run_before_callbacks - called = false - @machine.before_transition(lambda {called = true}) - - @transition.perform - assert called - end - - def test_should_pass_record_into_before_callbacks_with_one_argument - record = nil - @machine.before_transition(lambda {|arg| record = arg}) - - @transition.perform - assert_equal @record, record - end - - def test_should_pass_record_and_transition_into_before_callbacks_with_multiple_arguments - callback_args = nil - @machine.before_transition(lambda {|*args| callback_args = args}) - - @transition.perform - assert_equal [@record, @transition], callback_args - end - - def test_should_run_before_callbacks_outside_the_context_of_the_record - context = nil - @machine.before_transition(lambda {context = self}) - - @transition.perform - assert_equal self, context - end - - def test_should_run_after_callbacks - called = false - @machine.after_transition(lambda {called = true}) - - @transition.perform - assert called - end - - def test_should_pass_record_into_after_callbacks_with_one_argument - record = nil - @machine.after_transition(lambda {|arg| record = arg}) - - @transition.perform - assert_equal @record, record - end - - def test_should_pass_record_transition_and_result_into_after_callbacks_with_multiple_arguments - callback_args = nil - @machine.after_transition(lambda {|*args| callback_args = args}) - - @transition.perform - assert_equal [@record, @transition, true], callback_args - end - - def test_should_run_after_callbacks_outside_the_context_of_the_record - context = nil - @machine.after_transition(lambda {context = self}) - - @transition.perform - assert_equal self, context - end - - def test_should_include_transition_states_in_known_states - @machine.before_transition :to => :first_gear, :do => lambda {} - - assert_equal [:parked, :idling, :first_gear], @machine.states.map {|state| state.name} - end - - def test_should_allow_symbolic_callbacks - callback_args = nil - - klass = class << @record; self; end - klass.send(:define_method, :after_ignite) do |*args| - callback_args = args - end - - @machine.before_transition(:after_ignite) - - @transition.perform - assert_equal [@transition], callback_args - end - - def test_should_allow_string_callbacks - class << @record - attr_reader :callback_result - end - - @machine.before_transition('@callback_result = [1, 2, 3]') - @transition.perform - - assert_equal [1, 2, 3], @record.callback_result - end - end - - class MachineWithFailedBeforeCallbacksTest < ActiveRecord::TestCase - def setup - @before_count = 0 - - @model = new_model - @machine = StateMachine::Machine.new(@model) - @machine.state :parked, :idling - @machine.before_transition(lambda {@before_count += 1; false}) - @machine.before_transition(lambda {@before_count += 1}) - - @record = @model.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - @result = @transition.perform - end - - def test_should_not_be_successful - assert !@result - end - - def test_should_not_change_current_state - assert_equal 'parked', @record.state - end - - def test_should_not_run_action - assert @record.new_record? - end - - def test_should_not_run_further_before_callbacks - assert_equal 1, @before_count - end - end - - class MachineWithFailedActionTest < ActiveRecord::TestCase - def setup - @model = new_model do - validates_inclusion_of :state, :in => %w(first_gear) - end - - @machine = StateMachine::Machine.new(@model) - @machine.state :parked, :idling - @record = @model.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - @result = @transition.perform - end - - def test_should_not_be_successful - assert !@result - end - - def test_should_change_current_state - assert_equal 'idling', @record.state - end - - def test_should_not_save_record - assert @record.new_record? - end - end - - class MachineWithStateDrivenValidationsTest < ActiveRecord::TestCase - def setup - @model = new_model do - attr_accessor :seatbelt - end - - @machine = StateMachine::Machine.new(@model) - @machine.state :first_gear, :second_gear do - validates_presence_of :seatbelt - end - @machine.other_states :parked - end - - def test_should_be_valid_if_validation_fails_outside_state_scope - record = @model.new(:state => 'parked', :seatbelt => nil) - assert record.valid? - end - - def test_should_be_invalid_if_validation_fails_within_state_scope - record = @model.new(:state => 'first_gear', :seatbelt => nil) - assert !record.valid? - end - - def test_should_be_valid_if_validation_succeeds_within_state_scope - record = @model.new(:state => 'second_gear', :seatbelt => true) - assert record.valid? - end - end - - class MachineWithFailedAfterCallbacksTest < ActiveRecord::TestCase - def setup - @after_count = 0 - - @model = new_model - @machine = StateMachine::Machine.new(@model) - @machine.state :parked, :idling - @machine.after_transition(lambda {@after_count += 1; false}) - @machine.after_transition(lambda {@after_count += 1}) - - @record = @model.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - @result = @transition.perform - end - - def test_should_be_successful - assert @result - end - - def test_should_change_current_state - assert_equal 'idling', @record.state - end - - def test_should_save_record - assert !@record.new_record? - end - - def test_should_not_run_further_after_callbacks - assert_equal 1, @after_count - end - end - - class MachineWithObserversTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model) - @machine.state :parked, :idling - @record = @model.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - end - - def test_should_call_before_event_method - observer = new_observer(@model) do - def before_ignite(*args) - notifications << args - end - end - instance = observer.instance - - @transition.perform - assert_equal [[@record, @transition]], instance.notifications - end - - def test_should_call_before_transition_method - observer = new_observer(@model) do - def before_transition(*args) - notifications << args - end - end - instance = observer.instance - - @transition.perform - assert_equal [[@record, @transition]], instance.notifications - end - - def test_should_call_after_event_method - observer = new_observer(@model) do - def after_ignite(*args) - notifications << args - end - end - instance = observer.instance - - @transition.perform - assert_equal [[@record, @transition]], instance.notifications - end - - def test_should_call_after_transition_method - observer = new_observer(@model) do - def after_transition(*args) - notifications << args - end - end - instance = observer.instance - - @transition.perform - assert_equal [[@record, @transition]], instance.notifications - end - - def test_should_call_event_method_before_transition_method - observer = new_observer(@model) do - def before_ignite(*args) - notifications << :before_ignite - end - - def before_transition(*args) - notifications << :before_transition - end - end - instance = observer.instance - - @transition.perform - assert_equal [:before_ignite, :before_transition], instance.notifications - end - - def test_should_call_methods_outside_the_context_of_the_record - observer = new_observer(@model) do - def before_ignite(*args) - notifications << self - end - end - instance = observer.instance - - @transition.perform - assert_equal [instance], instance.notifications - end - end - - class MachineWithNamespacedObserversTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model, :namespace => 'car') - @machine.state :parked, :idling - @record = @model.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - end - - def test_should_call_namespaced_before_event_method - observer = new_observer(@model) do - def before_ignite_car(*args) - notifications << args - end - end - instance = observer.instance - - @transition.perform - assert_equal [[@record, @transition]], instance.notifications - end - - def test_should_call_namespaced_after_event_method - observer = new_observer(@model) do - def after_ignite_car(*args) - notifications << args - end - end - instance = observer.instance - - @transition.perform - assert_equal [[@record, @transition]], instance.notifications - end - end - - class MachineWithMixedCallbacksTest < ActiveRecord::TestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model) - @machine.state :parked, :idling - @record = @model.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - - @notifications = [] - - # Create callbacks - @machine.before_transition(lambda {@notifications << :callback_before_transition}) - @machine.after_transition(lambda {@notifications << :callback_after_transition}) - - # Create observer callbacks - observer = new_observer(@model) do - def before_ignite(*args) - notifications << :observer_before_ignite - end - - def before_transition(*args) - notifications << :observer_before_transition - end - - def after_ignite(*args) - notifications << :observer_after_ignite - end - - def after_transition(*args) - notifications << :observer_after_transition - end - end - instance = observer.instance - instance.notifications = @notifications - - @transition.perform - end - - def test_should_invoke_callbacks_in_specific_order - expected = [ - :callback_before_transition, - :observer_before_ignite, - :observer_before_transition, - :callback_after_transition, - :observer_after_ignite, - :observer_after_transition - ] - - assert_equal expected, @notifications - end - end - - if Object.const_defined?(:I18n) - class MachineWithInternationalizationTest < ActiveRecord::TestCase - def setup - I18n.backend = I18n::Backend::Simple.new - - # Initialize the backend - I18n.backend.translate(:en, 'activerecord.errors.messages.invalid_transition', :event => 'ignite', :value => 'idling') - - @model = new_model - end - - def test_should_invalidate_using_i18n_default - I18n.backend.store_translations(:en, { - :activerecord => { - :errors => { - :messages => { - :invalid_transition => 'cannot {{event}} when {{value}}' - } - } - } - }) - - machine = StateMachine::Machine.new(@model) - machine.state :parked, :idling - event = StateMachine::Event.new(machine, :ignite) - - record = @model.new(:state => 'idling') - - machine.invalidate(record, event) - assert_equal 'cannot ignite when idling', record.errors.on(:state) - end - - def test_should_invalidate_using_customized_i18n_key_if_specified - I18n.backend.store_translations(:en, { - :activerecord => { - :errors => { - :messages => { - :bad_transition => 'cannot {{event}} when {{value}}' - } - } - } - }) - - machine = StateMachine::Machine.new(@model, :invalid_message => :bad_transition) - machine.state :parked, :idling - event = StateMachine::Event.new(machine, :ignite) - - record = @model.new(:state => 'idling') - - machine.invalidate(record, event) - assert_equal 'cannot ignite when idling', record.errors.on(:state) - end - end - - def test_should_invalidate_using_customized_i18n_string_if_specified - machine = StateMachine::Machine.new(@model, :invalid_message => 'cannot {{event}} when {{value}}') - machine.state :parked, :idling - event = StateMachine::Event.new(machine, :ignite) - - record = @model.new(:state => 'idling') - - machine.invalidate(record, event) - assert_equal 'cannot ignite when idling', record.errors.on(:state) - end - else - $stderr.puts 'Skipping ActiveRecord I18n tests. `gem install active_record` >= v2.2.0 and try again.' - end - end -rescue LoadError - $stderr.puts "Skipping ActiveRecord tests. `gem install activerecord#{" -v #{ENV['AR_VERSION']}" if ENV['AR_VERSION']}` and try again." -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/integrations/data_mapper_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/integrations/data_mapper_test.rb deleted file mode 100644 index 19322d4..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/integrations/data_mapper_test.rb +++ /dev/null @@ -1,549 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../../test_helper') - -begin - # Load library - require 'rubygems' - - gem 'dm-core', ENV['DM_VERSION'] ? "=#{ENV['DM_VERSION']}" : '>=0.9.0' - require 'dm-core' - - # Establish database connection - DataMapper.setup(:default, 'sqlite3::memory:') - DataObjects::Sqlite3.logger = DataObjects::Logger.new("#{File.dirname(__FILE__)}/../../data_mapper.log", :info) - - module DataMapperTest - class BaseTestCase < Test::Unit::TestCase - def default_test - end - - protected - # Creates a new DataMapper resource (and the associated table) - def new_resource(auto_migrate = true, &block) - resource = Class.new do - include DataMapper::Resource - - storage_names[:default] = 'foo' - def self.name; 'DataMapperTest::Foo'; end - - property :id, Integer, :serial => true - property :state, String - - auto_migrate! if auto_migrate - end - resource.class_eval(&block) if block_given? - resource - end - - # Creates a new DataMapper observer - def new_observer(resource, &block) - observer = Class.new do - include DataMapper::Observer - end - observer.observe(resource) - observer.class_eval(&block) if block_given? - observer - end - end - - class IntegrationTest < BaseTestCase - def test_should_match_if_class_inherits_from_active_record - assert StateMachine::Integrations::DataMapper.matches?(new_resource) - end - - def test_should_not_match_if_class_does_not_inherit_from_active_record - assert !StateMachine::Integrations::DataMapper.matches?(Class.new) - end - end - - class MachineByDefaultTest < BaseTestCase - def setup - @resource = new_resource - @machine = StateMachine::Machine.new(@resource) - end - - def test_should_use_save_as_action - assert_equal :save, @machine.action - end - end - - class MachineTest < BaseTestCase - def setup - @resource = new_resource - @machine = StateMachine::Machine.new(@resource) - @machine.state :parked, :idling, :first_gear - end - - def test_should_create_singular_with_scope - assert @resource.respond_to?(:with_state) - end - - def test_should_only_include_records_with_state_in_singular_with_scope - parked = @resource.create :state => 'parked' - idling = @resource.create :state => 'idling' - - assert_equal [parked], @resource.with_state(:parked) - end - - def test_should_create_plural_with_scope - assert @resource.respond_to?(:with_states) - end - - def test_should_only_include_records_with_states_in_plural_with_scope - parked = @resource.create :state => 'parked' - idling = @resource.create :state => 'idling' - - assert_equal [parked, idling], @resource.with_states(:parked, :idling) - end - - def test_should_create_singular_without_scope - assert @resource.respond_to?(:without_state) - end - - def test_should_only_include_records_without_state_in_singular_without_scope - parked = @resource.create :state => 'parked' - idling = @resource.create :state => 'idling' - - assert_equal [parked], @resource.without_state(:idling) - end - - def test_should_create_plural_without_scope - assert @resource.respond_to?(:without_states) - end - - def test_should_only_include_records_without_states_in_plural_without_scope - parked = @resource.create :state => 'parked' - idling = @resource.create :state => 'idling' - first_gear = @resource.create :state => 'first_gear' - - assert_equal [parked, idling], @resource.without_states(:first_gear) - end - - def test_should_allow_chaining_scopes - parked = @resource.create :state => 'parked' - idling = @resource.create :state => 'idling' - - assert_equal [idling], @resource.without_state(:parked).with_state(:idling) - end - - def test_should_rollback_transaction_if_false - @machine.within_transaction(@resource.new) do - @resource.create - false - end - - assert_equal 0, @resource.all.size - end - - def test_should_not_rollback_transaction_if_true - @machine.within_transaction(@resource.new) do - @resource.create - true - end - - assert_equal 1, @resource.all.size - end - - def test_should_invalidate_using_errors - record = @resource.new - record.state = 'parked' - - @machine.invalidate(record, StateMachine::Event.new(@machine, :park)) - - assert_equal ['cannot be transitioned via :park from :parked'], record.errors.on(:state) - end - - def test_should_clear_errors_on_reset - record = @resource.new - record.state = 'parked' - record.errors.add(:state, 'is invalid') - - @machine.reset(record) - assert_nil record.errors.on(:id) - end - - def test_should_not_override_the_column_reader - record = @resource.new - record.attribute_set(:state, 'parked') - assert_equal 'parked', record.state - end - - def test_should_not_override_the_column_writer - record = @resource.new - record.state = 'parked' - assert_equal 'parked', record.attribute_get(:state) - end - end - - class MachineUnmigratedTest < BaseTestCase - def setup - @resource = new_resource(false) - end - - def test_should_allow_machine_creation - assert_nothing_raised { StateMachine::Machine.new(@resource) } - end - end - - class MachineWithInitialStateTest < BaseTestCase - def setup - @resource = new_resource - @machine = StateMachine::Machine.new(@resource, :initial => 'parked') - @record = @resource.new - end - - def test_should_set_initial_state_on_created_object - assert_equal 'parked', @record.state - end - end - - class MachineWithNonColumnStateAttributeUndefinedTest < BaseTestCase - def setup - @resource = new_resource do - def initialize - # Skip attribute initialization - end - end - - @machine = StateMachine::Machine.new(@resource, :status, :initial => 'parked') - @record = @resource.new - end - - def test_should_not_define_a_reader_attribute_for_the_attribute - assert !@record.respond_to?(:status) - end - - def test_should_not_define_a_writer_attribute_for_the_attribute - assert !@record.respond_to?(:status=) - end - - def test_should_define_an_attribute_predicate - assert @record.respond_to?(:status?) - end - end - - class MachineWithComplexPluralizationTest < BaseTestCase - def setup - @resource = new_resource - @machine = StateMachine::Machine.new(@resource, :status) - end - - def test_should_create_singular_with_scope - assert @resource.respond_to?(:with_status) - end - - def test_should_create_plural_with_scope - assert @resource.respond_to?(:with_statuses) - end - end - - class MachineWithNonColumnStateAttributeDefinedTest < BaseTestCase - def setup - @resource = new_resource do - attr_accessor :status - end - - @machine = StateMachine::Machine.new(@resource, :status, :initial => 'parked') - @record = @resource.new - end - - def test_should_set_initial_state_on_created_object - assert_equal 'parked', @record.status - end - end - - class MachineWithCallbacksTest < BaseTestCase - def setup - @resource = new_resource - @machine = StateMachine::Machine.new(@resource) - @machine.state :parked, :idling - @record = @resource.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - end - - def test_should_run_before_callbacks - called = false - @machine.before_transition(lambda {called = true}) - - @transition.perform - assert called - end - - def test_should_pass_transition_into_before_callbacks_with_one_argument - transition = nil - @machine.before_transition(lambda {|arg| transition = arg}) - - @transition.perform - assert_equal @transition, transition - end - - def test_should_pass_transition_into_before_callbacks_with_multiple_arguments - callback_args = nil - @machine.before_transition(lambda {|*args| callback_args = args}) - - @transition.perform - assert_equal [@transition], callback_args - end - - def test_should_run_before_callbacks_within_the_context_of_the_record - context = nil - @machine.before_transition(lambda {context = self}) - - @transition.perform - assert_equal @record, context - end - - def test_should_run_after_callbacks - called = false - @machine.after_transition(lambda {called = true}) - - @transition.perform - assert called - end - - def test_should_pass_transition_and_result_into_after_callbacks_with_multiple_arguments - callback_args = nil - @machine.after_transition(lambda {|*args| callback_args = args}) - - @transition.perform - assert_equal [@transition, true], callback_args - end - - def test_should_run_after_callbacks_with_the_context_of_the_record - context = nil - @machine.after_transition(lambda {context = self}) - - @transition.perform - assert_equal @record, context - end - - def test_should_allow_symbolic_callbacks - callback_args = nil - - klass = class << @record; self; end - klass.send(:define_method, :after_ignite) do |*args| - callback_args = args - end - - @machine.before_transition(:after_ignite) - - @transition.perform - assert_equal [@transition], callback_args - end - - def test_should_allow_string_callbacks - class << @record - attr_reader :callback_result - end - - @machine.before_transition('@callback_result = [1, 2, 3]') - @transition.perform - - assert_equal [1, 2, 3], @record.callback_result - end - end - - begin - gem 'dm-observer', ENV['DM_VERSION'] ? "=#{ENV['DM_VERSION']}" : '>=0.9.0' - require 'dm-observer' - - class MachineWithObserversTest < BaseTestCase - def setup - @resource = new_resource - @machine = StateMachine::Machine.new(@resource) - @machine.state :parked, :idling - @record = @resource.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - end - - def test_should_provide_matcher_helpers - matchers = [] - - new_observer(@resource) do - matchers = [all, any, same] - end - - assert_equal [StateMachine::AllMatcher.instance, StateMachine::AllMatcher.instance, StateMachine::LoopbackMatcher.instance], matchers - end - - def test_should_call_before_transition_callback_if_requirements_match - called = false - - observer = new_observer(@resource) do - before_transition :from => :parked do - called = true - end - end - - @transition.perform - assert called - end - - def test_should_not_call_before_transition_callback_if_requirements_do_not_match - called = false - - observer = new_observer(@resource) do - before_transition :from => :idling do - called = true - end - end - - @transition.perform - assert !called - end - - def test_should_allow_targeting_specific_machine - @second_machine = StateMachine::Machine.new(@resource, :status) - - called_state = false - called_status = false - - observer = new_observer(@resource) do - before_transition :state, :from => :parked do - called_state = true - end - - before_transition :status, :from => :parked do - called_status = true - end - end - - @transition.perform - - assert called_state - assert !called_status - end - - def test_should_pass_transition_to_before_callbacks - callback_args = nil - - observer = new_observer(@resource) do - before_transition do |*args| - callback_args = args - end - end - - @transition.perform - assert_equal [@transition], callback_args - end - - def test_should_call_after_transition_callback_if_requirements_match - called = false - - observer = new_observer(@resource) do - after_transition :from => :parked do - called = true - end - end - - @transition.perform - assert called - end - - def test_should_not_call_after_transition_callback_if_requirements_do_not_match - called = false - - observer = new_observer(@resource) do - after_transition :from => :idling do - called = true - end - end - - @transition.perform - assert !called - end - - def test_should_pass_transition_and_result_to_before_callbacks - callback_args = nil - - observer = new_observer(@resource) do - after_transition do |*args| - callback_args = args - end - end - - @transition.perform - assert_equal [@transition, true], callback_args - end - end - - class MachineWithMixedCallbacksTest < BaseTestCase - def setup - @resource = new_resource - @machine = StateMachine::Machine.new(@resource) - @machine.state :parked, :idling - @record = @resource.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - - @notifications = notifications = [] - - # Create callbacks - @machine.before_transition(lambda {notifications << :callback_before_transition}) - @machine.after_transition(lambda {notifications << :callback_after_transition}) - - observer = new_observer(@resource) do - before_transition do - notifications << :observer_before_transition - end - - after_transition do - notifications << :observer_after_transition - end - end - - @transition.perform - end - - def test_should_invoke_callbacks_in_specific_order - expected = [ - :callback_before_transition, - :observer_before_transition, - :callback_after_transition, - :observer_after_transition - ] - - assert_equal expected, @notifications - end - end - rescue LoadError - $stderr.puts "Skipping DataMapper Observer tests. `gem install dm-observer#{" -v #{ENV['DM_VERSION']}" if ENV['DM_VERSION']}` and try again." - end - - begin - gem 'dm-validations', ENV['DM_VERSION'] ? "=#{ENV['DM_VERSION']}" : '>=0.9.0' - require 'dm-validations' - - class MachineWithStateDrivenValidationsTest < BaseTestCase - def setup - @resource = new_resource do - attr_accessor :seatbelt - end - - @machine = StateMachine::Machine.new(@resource) - @machine.state :first_gear, :second_gear do - validates_present :seatbelt - end - @machine.other_states :parked - end - - def test_should_be_valid_if_validation_fails_outside_state_scope - record = @resource.new(:state => 'parked', :seatbelt => nil) - assert record.valid? - end - - def test_should_be_invalid_if_validation_fails_within_state_scope - record = @resource.new(:state => 'first_gear', :seatbelt => nil) - assert !record.valid? - end - - def test_should_be_valid_if_validation_succeeds_within_state_scope - record = @resource.new(:state => 'second_gear', :seatbelt => true) - assert record.valid? - end - end - rescue LoadError - $stderr.puts "Skipping DataMapper Validation tests. `gem install dm-validations#{" -v #{ENV['DM_VERSION']}" if ENV['DM_VERSION']}` and try again." - end - end -rescue LoadError - $stderr.puts "Skipping DataMapper tests. `gem install dm-core#{" -v #{ENV['DM_VERSION']}" if ENV['DM_VERSION']}`, `gem install cucumber rspec hoe launchy do_sqlite3` and try again." -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/integrations/sequel_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/integrations/sequel_test.rb deleted file mode 100644 index 3eb1716..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/integrations/sequel_test.rb +++ /dev/null @@ -1,364 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../../test_helper') - -begin - # Load library - require 'rubygems' - - gem 'sequel', ENV['SEQUEL_VERSION'] ? "=#{ENV['SEQUEL_VERSION']}" : '>=2.8.0' - require 'sequel' - require 'logger' - - # Establish database connection - DB = Sequel.connect('sqlite:///', :loggers => [Logger.new("#{File.dirname(__FILE__)}/../../sequel.log")]) - - module SequelTest - class BaseTestCase < Test::Unit::TestCase - def default_test - end - - protected - # Creates a new Sequel model (and the associated table) - def new_model(auto_migrate = true, &block) - DB.create_table! :foo do - primary_key :id - column :state, :string - end if auto_migrate - model = Class.new(Sequel::Model(:foo)) do - self.raise_on_save_failure = false - - def self.name; 'SequelTest::Foo'; end - end - model.class_eval(&block) if block_given? - model - end - end - - class IntegrationTest < BaseTestCase - def test_should_match_if_class_inherits_from_sequel - assert StateMachine::Integrations::Sequel.matches?(new_model) - end - - def test_should_not_match_if_class_does_not_inherit_from_sequel - assert !StateMachine::Integrations::Sequel.matches?(Class.new) - end - end - - class MachineByDefaultTest < BaseTestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model) - end - - def test_should_use_save_as_action - assert_equal :save, @machine.action - end - end - - class MachineTest < BaseTestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model) - @machine.state :parked, :idling, :first_gear - end - - def test_should_create_singular_with_scope - assert @model.respond_to?(:with_state) - end - - def test_should_only_include_records_with_state_in_singular_with_scope - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - - assert_equal [parked], @model.with_state(:parked).all - end - - def test_should_create_plural_with_scope - assert @model.respond_to?(:with_states) - end - - def test_should_only_include_records_with_states_in_plural_with_scope - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - - assert_equal [parked, idling], @model.with_states(:parked, :idling).all - end - - def test_should_create_singular_without_scope - assert @model.respond_to?(:without_state) - end - - def test_should_only_include_records_without_state_in_singular_without_scope - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - - assert_equal [parked], @model.without_state(:idling).all - end - - def test_should_create_plural_without_scope - assert @model.respond_to?(:without_states) - end - - def test_should_only_include_records_without_states_in_plural_without_scope - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - first_gear = @model.create :state => 'first_gear' - - assert_equal [parked, idling], @model.without_states(:first_gear).all - end - - def test_should_allow_chaining_scopes_and_fitlers - parked = @model.create :state => 'parked' - idling = @model.create :state => 'idling' - - assert_equal [idling], @model.without_state(:parked).filter(:state => 'idling').all - end - - def test_should_rollback_transaction_if_false - @machine.within_transaction(@model.new) do - @model.create - false - end - - assert_equal 0, @model.count - end - - def test_should_not_rollback_transaction_if_true - @machine.within_transaction(@model.new) do - @model.create - true - end - - assert_equal 1, @model.count - end - - def test_should_invalidate_using_errors - record = @model.new - record.state = 'parked' - - @machine.invalidate(record, StateMachine::Event.new(@machine, :park)) - - assert_equal ['cannot be transitioned via :park from :parked'], record.errors.on(:state) - end - - def test_should_clear_errors_on_reset - record = @model.new - record.state = 'parked' - record.errors.add(:state, 'is invalid') - - @machine.reset(record) - assert_nil record.errors.on(:id) - end - - def test_should_not_override_the_column_reader - record = @model.new - record[:state] = 'parked' - assert_equal 'parked', record.state - end - - def test_should_not_override_the_column_writer - record = @model.new - record.state = 'parked' - assert_equal 'parked', record[:state] - end - end - - class MachineUnmigratedTest < BaseTestCase - def setup - @model = new_model(false) - end - - def test_should_allow_machine_creation - assert_nothing_raised { StateMachine::Machine.new(@model) } - end - end - - class MachineWithInitialStateTest < BaseTestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model, :initial => 'parked') - @record = @model.new - end - - def test_should_set_initial_state_on_created_object - assert_equal 'parked', @record.state - end - end - - class MachineWithNonColumnStateAttributeUndefinedTest < BaseTestCase - def setup - @model = new_model do - def initialize - # Skip attribute initialization - end - end - - @machine = StateMachine::Machine.new(@model, :status, :initial => 'parked') - @record = @model.new - end - - def test_should_not_define_a_reader_attribute_for_the_attribute - assert !@record.respond_to?(:status) - end - - def test_should_not_define_a_writer_attribute_for_the_attribute - assert !@record.respond_to?(:status=) - end - - def test_should_define_an_attribute_predicate - assert @record.respond_to?(:status?) - end - end - - class MachineWithNonColumnStateAttributeDefinedTest < BaseTestCase - def setup - @model = new_model do - attr_accessor :status - end - - @machine = StateMachine::Machine.new(@model, :status, :initial => 'parked') - @record = @model.new - end - - def test_should_set_initial_state_on_created_object - assert_equal 'parked', @record.status - end - end - - class MachineWithComplexPluralizationTest < BaseTestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model, :status) - end - - def test_should_create_singular_with_scope - assert @model.respond_to?(:with_status) - end - - def test_should_create_plural_with_scope - assert @model.respond_to?(:with_statuses) - end - end - - class MachineWithCallbacksTest < BaseTestCase - def setup - @model = new_model - @machine = StateMachine::Machine.new(@model) - @machine.state :parked, :idling - @record = @model.new(:state => 'parked') - @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling) - end - - def test_should_run_before_callbacks - called = false - @machine.before_transition(lambda {called = true}) - - @transition.perform - assert called - end - - def test_should_pass_transition_into_before_callbacks_with_one_argument - transition = nil - @machine.before_transition(lambda {|arg| transition = arg}) - - @transition.perform - assert_equal @transition, transition - end - - def test_should_pass_transition_into_before_callbacks_with_multiple_arguments - callback_args = nil - @machine.before_transition(lambda {|*args| callback_args = args}) - - @transition.perform - assert_equal [@transition], callback_args - end - - def test_should_run_before_callbacks_within_the_context_of_the_record - context = nil - @machine.before_transition(lambda {context = self}) - - @transition.perform - assert_equal @record, context - end - - def test_should_run_after_callbacks - called = false - @machine.after_transition(lambda {called = true}) - - @transition.perform - assert called - end - - def test_should_pass_transition_and_result_into_after_callbacks_with_multiple_arguments - callback_args = nil - @machine.after_transition(lambda {|*args| callback_args = args}) - - @transition.perform - assert_equal [@transition, true], callback_args - end - - def test_should_run_after_callbacks_with_the_context_of_the_record - context = nil - @machine.after_transition(lambda {context = self}) - - @transition.perform - assert_equal @record, context - end - - def test_should_allow_symbolic_callbacks - callback_args = nil - - klass = class << @record; self; end - klass.send(:define_method, :after_ignite) do |*args| - callback_args = args - end - - @machine.before_transition(:after_ignite) - - @transition.perform - assert_equal [@transition], callback_args - end - - def test_should_allow_string_callbacks - class << @record - attr_reader :callback_result - end - - @machine.before_transition('@callback_result = [1, 2, 3]') - @transition.perform - - assert_equal [1, 2, 3], @record.callback_result - end - end - - class MachineWithStateDrivenValidationsTest < BaseTestCase - def setup - @model = new_model do - attr_accessor :seatbelt - end - - @machine = StateMachine::Machine.new(@model) - @machine.state :first_gear do - validates_presence_of :seatbelt - end - @machine.other_states :parked - end - - def test_should_be_valid_if_validation_fails_outside_state_scope - record = @model.new(:state => 'parked', :seatbelt => nil) - assert record.valid? - end - - def test_should_be_invalid_if_validation_fails_within_state_scope - record = @model.new(:state => 'first_gear', :seatbelt => nil) - assert !record.valid? - end - - def test_should_be_valid_if_validation_succeeds_within_state_scope - record = @model.new(:state => 'first_gear', :seatbelt => true) - assert record.valid? - end - end - end -rescue LoadError - $stderr.puts "Skipping Sequel tests. `gem install sequel#{" -v #{ENV['SEQUEL_VERSION']}" if ENV['SEQUEL_VERSION']}` and try again." -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/integrations_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/integrations_test.rb deleted file mode 100644 index d4336b7..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/integrations_test.rb +++ /dev/null @@ -1,42 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class IntegrationMatcherTest < Test::Unit::TestCase - def setup - @klass = Class.new - end - - def test_should_return_nil_if_no_match_found - assert_nil StateMachine::Integrations.match(@klass) - end - - def test_should_return_integration_class_if_match_found - integration = Module.new do - def self.matches?(klass) - true - end - end - StateMachine::Integrations.const_set('Custom', integration) - - assert_equal integration, StateMachine::Integrations.match(@klass) - ensure - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class IntegrationFinderTest < Test::Unit::TestCase - def test_should_find_active_record - assert_equal StateMachine::Integrations::ActiveRecord, StateMachine::Integrations.find(:active_record) - end - - def test_should_find_data_mapper - assert_equal StateMachine::Integrations::DataMapper, StateMachine::Integrations.find(:data_mapper) - end - - def test_should_find_sequel - assert_equal StateMachine::Integrations::Sequel, StateMachine::Integrations.find(:sequel) - end - - def test_should_raise_an_exception_if_invalid - assert_raise(NameError) { StateMachine::Integrations.find(:invalid) } - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/invalid_transition_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/invalid_transition_test.rb deleted file mode 100644 index a956ac4..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/invalid_transition_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class InvalidTransitionTest < Test::Unit::TestCase - def test_should_exist - assert_not_nil StateMachine::InvalidTransition - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/machine_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/machine_test.rb deleted file mode 100644 index af5780a..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/machine_test.rb +++ /dev/null @@ -1,1648 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class MachineByDefaultTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @object = @klass.new - end - - def test_should_have_an_owner_class - assert_equal @klass, @machine.owner_class - end - - def test_should_have_an_attribute - assert_equal :state, @machine.attribute - end - - def test_should_have_an_initial_state - assert_not_nil @machine.initial_state(@object) - end - - def test_should_have_a_nil_initial_state - assert_nil @machine.initial_state(@object).value - end - - def test_should_not_have_any_events - assert !@machine.events.any? - end - - def test_should_not_have_any_before_callbacks - assert @machine.callbacks[:before].empty? - end - - def test_should_not_have_any_after_callbacks - assert @machine.callbacks[:after].empty? - end - - def test_should_not_have_an_action - assert_nil @machine.action - end - - def test_should_not_have_a_namespace - assert_nil @machine.namespace - end - - def test_should_have_a_nil_state - assert_equal [nil], @machine.states.keys - end - - def test_should_set_initial_on_nil_state - assert @machine.state(nil).initial - end - - def test_should_not_be_extended_by_the_active_record_integration - assert !(class << @machine; ancestors; end).include?(StateMachine::Integrations::ActiveRecord) - end - - def test_should_not_be_extended_by_the_datamapper_integration - assert !(class << @machine; ancestors; end).include?(StateMachine::Integrations::DataMapper) - end - - def test_should_not_be_extended_by_the_sequel_integration - assert !(class << @machine; ancestors; end).include?(StateMachine::Integrations::Sequel) - end - - def test_should_define_a_reader_attribute_for_the_attribute - assert @object.respond_to?(:state) - end - - def test_should_define_a_writer_attribute_for_the_attribute - assert @object.respond_to?(:state=) - end - - def test_should_define_a_predicate_for_the_attribute - assert @object.respond_to?(:state?) - end - - def test_should_define_a_name_reader_for_the_attribute - assert @object.respond_to?(:state_name) - end - - def test_should_not_define_singular_with_scope - assert !@klass.respond_to?(:with_state) - end - - def test_should_not_define_singular_without_scope - assert !@klass.respond_to?(:without_state) - end - - def test_should_not_define_plural_with_scope - assert !@klass.respond_to?(:with_states) - end - - def test_should_not_define_plural_without_scope - assert !@klass.respond_to?(:without_states) - end - - def test_should_extend_owner_class_with_class_methods - assert (class << @klass; ancestors; end).include?(StateMachine::ClassMethods) - end - - def test_should_include_instance_methods_in_owner_class - assert @klass.included_modules.include?(StateMachine::InstanceMethods) - end - - def test_should_define_state_machines_reader - expected = {:state => @machine} - assert_equal expected, @klass.state_machines - end -end - -class MachineWithCustomAttributeTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :status) - @object = @klass.new - end - - def test_should_use_custom_attribute - assert_equal :status, @machine.attribute - end - - def test_should_define_a_reader_attribute_for_the_attribute - assert @object.respond_to?(:status) - end - - def test_should_define_a_writer_attribute_for_the_attribute - assert @object.respond_to?(:status=) - end - - def test_should_define_a_predicate_for_the_attribute - assert @object.respond_to?(:status?) - end - - def test_should_define_a_name_reader_for_the_attribute - assert @object.respond_to?(:status_name) - end -end - -class MachineWithStaticInitialStateTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def initialize(attributes = {}) - attributes.each {|attr, value| send("#{attr}=", value)} - super() - end - end - - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - end - - def test_should_have_an_initial_state - object = @klass.new - assert_equal 'parked', @machine.initial_state(object).value - end - - def test_should_set_initial_on_state_object - assert @machine.state(:parked).initial - end - - def test_should_set_initial_state_if_existing_is_nil - object = @klass.new(:state => nil) - assert_equal 'parked', object.state - end - - def test_should_set_initial_state_if_existing_is_empty - object = @klass.new(:state => '') - assert_equal 'parked', object.state - end - - def test_should_not_set_initial_state_if_existing_is_not_empty - object = @klass.new(:state => 'idling') - assert_equal 'idling', object.state - end - - def test_should_be_included_in_known_states - assert_equal [:parked], @machine.states.keys - end -end - -class MachineWithDynamicInitialStateTest < Test::Unit::TestCase - def setup - @klass = Class.new do - attr_accessor :initial_state - end - @machine = StateMachine::Machine.new(@klass, :initial => lambda {|object| object.initial_state || :default}) - @machine.state :parked, :idling, :default - @object = @klass.new - end - - def test_should_use_the_record_for_determining_the_initial_state - @object.initial_state = :parked - assert_equal :parked, @machine.initial_state(@object).name - - @object.initial_state = :idling - assert_equal :idling, @machine.initial_state(@object).name - end - - def test_should_set_initial_state_on_created_object - assert_equal 'default', @object.state - end - - def test_should_not_be_included_in_known_states - assert_equal [:parked, :idling, :default], @machine.states.map {|state| state.name} - end -end - -class MachineWithCustomActionTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new, :action => :save) - end - - def test_should_use_the_custom_action - assert_equal :save, @machine.action - end -end - -class MachineWithNilActionTest < Test::Unit::TestCase - def setup - integration = Module.new do - def default_action - :save - end - end - StateMachine::Integrations.const_set('Custom', integration) - @machine = StateMachine::Machine.new(Class.new, :action => nil, :integration => :custom) - end - - def test_should_have_a_nil_action - assert_nil @machine.action - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class MachineWithoutIntegrationTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @object = @klass.new - end - - def test_transaction_should_yield - @yielded = false - @machine.within_transaction(@object) do - @yielded = true - end - - assert @yielded - end - - def test_invalidation_should_do_nothing - assert_nil @machine.invalidate(@object, StateMachine::Event.new(@machine, :park)) - end - - def test_reset_should_do_nothing - assert_nil @machine.reset(@object) - end -end - -class MachineWithCustomIntegrationTest < Test::Unit::TestCase - def setup - StateMachine::Integrations.const_set('Custom', Module.new) - @machine = StateMachine::Machine.new(Class.new, :integration => :custom) - end - - def test_should_be_extended_by_the_integration - assert (class << @machine; ancestors; end).include?(StateMachine::Integrations::Custom) - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class MachineWithIntegrationTest < Test::Unit::TestCase - def setup - @integration = Module.new do - class << self; attr_accessor :initialized, :with_scopes, :without_scopes; end - @initialized = false - @with_scopes = [] - @without_scopes = [] - - def after_initialize - StateMachine::Integrations::Custom.initialized = true - end - - def default_action - :save - end - - def create_with_scope(name) - StateMachine::Integrations::Custom.with_scopes << name - lambda {} - end - - def create_without_scope(name) - StateMachine::Integrations::Custom.without_scopes << name - lambda {} - end - end - - StateMachine::Integrations.const_set('Custom', @integration) - @machine = StateMachine::Machine.new(Class.new, :integration => :custom) - end - - def test_should_call_after_initialize_hook - assert @integration.initialized - end - - def test_should_use_the_default_action - assert_equal :save, @machine.action - end - - def test_should_use_the_custom_action_if_specified - machine = StateMachine::Machine.new(Class.new, :integration => :custom, :action => :save!) - assert_equal :save!, machine.action - end - - def test_should_define_a_singular_and_plural_with_scope - assert_equal %w(with_state with_states), @integration.with_scopes - end - - def test_should_define_a_singular_and_plural_without_scope - assert_equal %w(without_state without_states), @integration.without_scopes - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class MachineWithCustomPluralTest < Test::Unit::TestCase - def setup - @integration = Module.new do - class << self; attr_accessor :with_scopes, :without_scopes; end - @with_scopes = [] - @without_scopes = [] - - def create_with_scope(name) - StateMachine::Integrations::Custom.with_scopes << name - lambda {} - end - - def create_without_scope(name) - StateMachine::Integrations::Custom.without_scopes << name - lambda {} - end - end - - StateMachine::Integrations.const_set('Custom', @integration) - @machine = StateMachine::Machine.new(Class.new, :integration => :custom, :plural => 'staties') - end - - def test_should_define_a_singular_and_plural_with_scope - assert_equal %w(with_state with_staties), @integration.with_scopes - end - - def test_should_define_a_singular_and_plural_without_scope - assert_equal %w(without_state without_staties), @integration.without_scopes - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class MachineWithCustomInvalidationTest < Test::Unit::TestCase - def setup - @integration = Module.new do - def invalidate(object, event) - object.error = invalid_message(object, event) - end - end - StateMachine::Integrations.const_set('Custom', @integration) - - @klass = Class.new do - attr_accessor :error - end - - @machine = StateMachine::Machine.new(@klass, :integration => :custom, :invalid_message => 'cannot %s when %s') - @machine.state :parked - - @object = @klass.new - @object.state = 'parked' - end - - def test_use_custom_message - @machine.invalidate(@object, StateMachine::Event.new(@machine, :park)) - assert_equal 'cannot park when parked', @object.error - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class MachineTest < Test::Unit::TestCase - def test_should_raise_exception_if_invalid_option_specified - assert_raise(ArgumentError) {StateMachine::Machine.new(Class.new, :invalid => true)} - end - - def test_should_not_raise_exception_if_custom_invalid_message_specified - assert_nothing_raised {StateMachine::Machine.new(Class.new, :invalid_message => 'custom')} - end - - def test_should_evaluate_a_block_during_initialization - called = true - StateMachine::Machine.new(Class.new) do - called = respond_to?(:event) - end - - assert called - end - - def test_should_provide_matcher_helpers_during_initialization - matchers = [] - - StateMachine::Machine.new(Class.new) do - matchers = [all, any, same] - end - - assert_equal [StateMachine::AllMatcher.instance, StateMachine::AllMatcher.instance, StateMachine::LoopbackMatcher.instance], matchers - end -end - -class MachineAfterBeingCopiedTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new, :state, :initial => :parked) - @machine.event(:ignite) {} - @machine.before_transition(lambda {}) - @machine.after_transition(lambda {}) - - @copied_machine = @machine.clone - end - - def test_should_not_have_the_same_collection_of_states - assert_not_same @copied_machine.states, @machine.states - end - - def test_should_copy_each_state - assert_not_same @copied_machine.states[:parked], @machine.states[:parked] - end - - def test_should_update_machine_for_each_state - assert_equal @copied_machine, @copied_machine.states[:parked].machine - end - - def test_should_not_update_machine_for_original_state - assert_equal @machine, @machine.states[:parked].machine - end - - def test_should_not_have_the_same_collection_of_events - assert_not_same @copied_machine.events, @machine.events - end - - def test_should_copy_each_event - assert_not_same @copied_machine.events[:ignite], @machine.events[:ignite] - end - - def test_should_update_machine_for_each_event - assert_equal @copied_machine, @copied_machine.events[:ignite].machine - end - - def test_should_not_update_machine_for_original_event - assert_equal @machine, @machine.events[:ignite].machine - end - - def test_should_not_have_the_same_callbacks - assert_not_same @copied_machine.callbacks, @machine.callbacks - end - - def test_should_not_have_the_same_before_callbacks - assert_not_same @copied_machine.callbacks[:before], @machine.callbacks[:before] - end - - def test_should_not_have_the_same_after_callbacks - assert_not_same @copied_machine.callbacks[:after], @machine.callbacks[:after] - end -end - -class MachineAfterChangingOwnerClassTest < Test::Unit::TestCase - def setup - @original_class = Class.new - @machine = StateMachine::Machine.new(@original_class) - - @new_class = Class.new(@original_class) - @new_machine = @machine.clone - @new_machine.owner_class = @new_class - - @object = @new_class.new - end - - def test_should_update_owner_class - assert_equal @new_class, @new_machine.owner_class - end - - def test_should_not_change_original_owner_class - assert_equal @original_class, @machine.owner_class - end - - def test_should_change_the_associated_machine_in_the_new_class - assert_equal @new_machine, @new_class.state_machines[:state] - end - - def test_should_not_change_the_associated_machine_in_the_original_class - assert_equal @machine, @original_class.state_machines[:state] - end -end - -class MachineAfterChangingInitialState < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @machine.initial_state = :idling - - @object = @klass.new - end - - def test_should_change_the_initial_state - assert_equal :idling, @machine.initial_state(@object).name - end - - def test_should_include_in_known_states - assert_equal [:parked, :idling], @machine.states.map {|state| state.name} - end - - def test_should_reset_original_initial_state - assert !@machine.state(:parked).initial - end - - def test_should_set_new_state_to_initial - assert @machine.state(:idling).initial - end -end - -class MachineWithInstanceHelpersTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @object = @klass.new - end - - def test_should_not_redefine_existing_public_methods - @klass.class_eval do - def state - 'parked' - end - end - - @machine.define_instance_method(:state) {} - assert_equal 'parked', @object.state - end - - def test_should_not_redefine_existing_protected_methods - @klass.class_eval do - protected - def state - 'parked' - end - end - - @machine.define_instance_method(:state) {} - assert_equal 'parked', @object.send(:state) - end - - def test_should_not_redefine_existing_private_methods - @klass.class_eval do - private - def state - 'parked' - end - end - - @machine.define_instance_method(:state) {} - assert_equal 'parked', @object.send(:state) - end - - def test_should_define_nonexistent_methods - @machine.define_instance_method(:state) {'parked'} - assert_equal 'parked', @object.state - end -end - -class MachineWithClassHelpersTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - end - - def test_should_not_redefine_existing_public_methods - class << @klass - def states - [] - end - end - - @machine.define_class_method(:states) {} - assert_equal [], @klass.states - end - - def test_should_not_redefine_existing_protected_methods - class << @klass - protected - def states - [] - end - end - - @machine.define_class_method(:states) {} - assert_equal [], @klass.send(:states) - end - - def test_should_not_redefine_existing_private_methods - class << @klass - private - def states - [] - end - end - - @machine.define_class_method(:states) {} - assert_equal [], @klass.send(:states) - end - - def test_should_define_nonexistent_methods - @machine.define_class_method(:states) {[]} - assert_equal [], @klass.states - end -end - -class MachineWithConflictingHelpersTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def self.with_state - :with_state - end - - def self.with_states - :with_states - end - - def self.without_state - :without_state - end - - def self.without_states - :without_states - end - - attr_accessor :status - - def state - 'parked' - end - - def state=(value) - self.status = value - end - - def state? - true - end - - def state_name - :parked - end - end - - StateMachine::Integrations.const_set('Custom', Module.new do - def create_with_scope(name) - lambda {|klass, values| []} - end - - def create_without_scope(name) - lambda {|klass, values| []} - end - end) - - @machine = StateMachine::Machine.new(@klass, :integration => :custom) - @machine.state :parked, :idling - @object = @klass.new - end - - def test_should_not_redefine_singular_with_scope - assert_equal :with_state, @klass.with_state - end - - def test_should_not_redefine_plural_with_scope - assert_equal :with_states, @klass.with_states - end - - def test_should_not_redefine_singular_without_scope - assert_equal :without_state, @klass.without_state - end - - def test_should_not_redefine_plural_without_scope - assert_equal :without_states, @klass.without_states - end - - def test_should_not_redefine_attribute_writer - assert_equal 'parked', @object.state - end - - def test_should_not_redefine_attribute_writer - @object.state = 'parked' - assert_equal 'parked', @object.status - end - - def test_should_not_define_attribute_predicate - assert @object.state? - end - - def test_should_not_redefine_attribute_name_reader - assert_equal :parked, @object.state_name - end - - def test_should_allow_super_chaining - @klass.class_eval do - def self.with_state(*states) - super == [] - end - - def self.with_states(*states) - super == [] - end - - def self.without_state(*states) - super == [] - end - - def self.without_states(*states) - super == [] - end - - attr_accessor :status - - def state - super || 'parked' - end - - def state=(value) - super - self.status = value - end - - def state?(state) - super ? 1 : 0 - end - - def state_name - super == :parked ? 1 : 0 - end - end - - assert_equal true, @klass.with_state - assert_equal true, @klass.with_states - assert_equal true, @klass.without_state - assert_equal true, @klass.without_states - - assert_equal 'parked', @object.state - @object.state = 'idling' - assert_equal 'idling', @object.status - assert_equal 0, @object.state?(:parked) - assert_equal 0, @object.state_name - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class MachineWithoutInitializeTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @object = @klass.new - end - - def test_should_initialize_state - assert_equal 'parked', @object.state - end -end - -class MachineWithInitializeWithoutSuperTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def initialize - end - end - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @object = @klass.new - end - - def test_should_not_initialize_state - assert_nil @object.state - end -end - -class MachineWithInitializeAndSuperTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def initialize - super() - end - end - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @object = @klass.new - end - - def test_should_initialize_state - assert_equal 'parked', @object.state - end -end - -class MachineWithInitializeArgumentsAndBlockTest < Test::Unit::TestCase - def setup - @superclass = Class.new do - attr_reader :args - attr_reader :block_given - - def initialize(*args) - @args = args - @block_given = block_given? - end - end - @klass = Class.new(@superclass) - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @object = @klass.new(1, 2, 3) {} - end - - def test_should_initialize_state - assert_equal 'parked', @object.state - end - - def test_should_preserve_arguments - assert_equal [1, 2, 3], @object.args - end - - def test_should_preserve_block - assert @object.block_given - end -end - -class MachineWithCustomInitializeTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def initialize - initialize_state_machines - end - end - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @object = @klass.new - end - - def test_should_initialize_state - assert_equal 'parked', @object.state - end -end - -class MachineWithStatesTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @parked, @idling = @machine.state :parked, :idling - - @object = @klass.new - end - - def test_should_have_states - assert_equal [nil, :parked, :idling], @machine.states.map {|state| state.name} - end - - def test_should_allow_state_lookup_by_name - assert_equal @parked, @machine.states[:parked] - end - - def test_should_allow_state_lookup_by_value - assert_equal @parked, @machine.states['parked', :value] - end - - def test_should_use_stringified_name_for_value - assert_equal 'parked', @parked.value - end - - def test_should_not_use_custom_matcher - assert_nil @parked.matcher - end - - def test_should_raise_exception_if_invalid_option_specified - exception = assert_raise(ArgumentError) {@machine.state(:first_gear, :invalid => true)} - assert_equal 'Invalid key(s): invalid', exception.message - end - - def test_should_not_be_in_state_if_value_does_not_match - assert !@machine.state?(@object, :parked) - assert !@machine.state?(@object, :idling) - end - - def test_should_be_in_state_if_value_matches - assert @machine.state?(@object, nil) - end - - def test_raise_exception_if_checking_invalid_state - assert_raise(ArgumentError) { @machine.state?(@object, :invalid) } - end - - def test_should_find_state_for_object_if_value_is_known - @object.state = 'parked' - assert_equal @parked, @machine.state_for(@object) - end - - def test_should_raise_exception_if_finding_state_for_object_with_unknown_value - @object.state = 'invalid' - exception = assert_raise(ArgumentError) { @machine.state_for(@object) } - assert_equal '"invalid" is not a known state value', exception.message - end -end - -class MachineWithStatesWithCustomValuesTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = @machine.state :parked, :value => 1 - - @object = @klass.new - @object.state = 1 - end - - def test_should_use_custom_value - assert_equal 1, @state.value - end - - def test_should_allow_lookup_by_custom_value - assert_equal @state, @machine.states[1, :value] - end - - def test_should_be_in_state_if_value_matches - assert @machine.state?(@object, :parked) - end - - def test_should_not_be_in_state_if_value_does_not_match - @object.state = 2 - assert !@machine.state?(@object, :parked) - end - - def test_should_find_state_for_object_if_value_is_known - assert_equal @state, @machine.state_for(@object) - end -end - -class MachineWithStateWithMatchersTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = @machine.state :parked, :if => lambda {|value| !value.nil?} - - @object = @klass.new - @object.state = 1 - end - - def test_should_use_custom_matcher - assert_not_nil @state.matcher - assert @state.matches?(1) - assert !@state.matches?(nil) - end - - def test_should_be_in_state_if_value_matches - assert @machine.state?(@object, :parked) - end - - def test_should_not_be_in_state_if_value_does_not_match - @object.state = nil - assert !@machine.state?(@object, :parked) - end - - def test_should_find_state_for_object_if_value_is_known - assert_equal @state, @machine.state_for(@object) - end -end - -class MachineWithStatesWithBehaviorsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - - @parked, @idling = @machine.state :parked, :idling do - def speed - 0 - end - end - end - - def test_should_define_behaviors_for_each_state - assert_not_nil @parked.methods[:speed] - assert_not_nil @idling.methods[:speed] - end - - def test_should_define_different_behaviors_for_each_state - assert_not_equal @parked.methods[:speed], @idling.methods[:speed] - end -end - -class MachineWithExistingStateTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = @machine.state :parked - @same_state = @machine.state :parked, :value => 1 - end - - def test_should_not_create_a_new_state - assert_same @state, @same_state - end - - def test_should_update_attributes - assert_equal 1, @state.value - end - - def test_should_no_longer_be_able_to_look_up_state_by_original_value - assert_nil @machine.states['parked', :value] - end - - def test_should_be_able_to_look_up_state_by_new_value - assert_equal @state, @machine.states[1, :value] - end -end - -class MachineWithOtherStates < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @parked, @idling = @machine.other_states(:parked, :idling) - end - - def test_should_include_other_states_in_known_states - assert_equal [@parked, @idling], @machine.states.to_a - end - - def test_should_use_default_value - assert_equal 'idling', @idling.value - end - - def test_should_not_create_matcher - assert_nil @idling.matcher - end -end - -class MachineWithEventsTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - end - - def test_should_return_the_created_event - assert_instance_of StateMachine::Event, @machine.event(:ignite) - end - - def test_should_create_event_with_given_name - event = @machine.event(:ignite) {} - assert_equal :ignite, event.name - end - - def test_should_evaluate_block_within_event_context - responded = false - @machine.event :ignite do - responded = respond_to?(:transition) - end - - assert responded - end - - def test_should_be_aliased_as_on - event = @machine.on(:ignite) {} - assert_equal :ignite, event.name - end - - def test_should_have_events - event = @machine.event(:ignite) - assert_equal [event], @machine.events.to_a - end -end - -class MachineWithExistingEventTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @event = @machine.event(:ignite) - @same_event = @machine.event(:ignite) - end - - def test_should_not_create_new_event - assert_same @event, @same_event - end - - def test_should_allow_accessing_event_without_block - assert_equal @event, @machine.event(:ignite) - end -end - -class MachineWithEventsWithTransitionsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @event = @machine.event(:ignite) do - transition :parked => :idling - transition :stalled => :idling - end - end - - def test_should_have_events - assert_equal [@event], @machine.events.to_a - end - - def test_should_track_states_defined_in_event_transitions - assert_equal [:parked, :idling, :stalled], @machine.states.map {|state| state.name} - end - - def test_should_not_duplicate_states_defined_in_multiple_event_transitions - @machine.event :park do - transition :idling => :parked - end - - assert_equal [:parked, :idling, :stalled], @machine.states.map {|state| state.name} - end - - def test_should_track_state_from_new_events - @machine.event :shift_up do - transition :idling => :first_gear - end - - assert_equal [:parked, :idling, :stalled, :first_gear], @machine.states.map {|state| state.name} - end -end - -class MachineWithMultipleEventsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @park, @shift_down = @machine.event(:park, :shift_down) do - transition :first_gear => :parked - end - end - - def test_should_have_events - assert_equal [@park, @shift_down], @machine.events.to_a - end - - def test_should_define_transitions_for_each_event - [@park, @shift_down].each {|event| assert_equal 1, event.guards.size} - end - - def test_should_transition_the_same_for_each_event - object = @klass.new - object.state = 'first_gear' - object.park - assert_equal 'parked', object.state - - object = @klass.new - object.state = 'first_gear' - object.shift_down - assert_equal 'parked', object.state - end -end - -class MachineWithTransitionCallbacksTest < Test::Unit::TestCase - def setup - @klass = Class.new do - attr_accessor :callbacks - end - - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @event = @machine.event :ignite do - transition :parked => :idling - end - - @object = @klass.new - @object.callbacks = [] - end - - def test_should_not_raise_exception_if_implicit_option_specified - assert_nothing_raised {@machine.before_transition :invalid => true, :do => lambda {}} - end - - def test_should_raise_exception_if_do_option_not_specified - exception = assert_raise(ArgumentError) {@machine.before_transition :to => :idling} - assert_equal ':do callback must be specified', exception.message - end - - def test_should_invoke_callbacks_during_transition - @machine.before_transition lambda {|object| object.callbacks << 'before'} - @machine.after_transition lambda {|object| object.callbacks << 'after'} - - @event.fire(@object) - assert_equal %w(before after), @object.callbacks - end - - def test_should_support_from_requirement - @machine.before_transition :from => :parked, :do => lambda {|object| object.callbacks << :parked} - @machine.before_transition :from => :idling, :do => lambda {|object| object.callbacks << :idling} - - @event.fire(@object) - assert_equal [:parked], @object.callbacks - end - - def test_should_support_except_from_requirement - @machine.before_transition :except_from => :parked, :do => lambda {|object| object.callbacks << :parked} - @machine.before_transition :except_from => :idling, :do => lambda {|object| object.callbacks << :idling} - - @event.fire(@object) - assert_equal [:idling], @object.callbacks - end - - def test_should_support_to_requirement - @machine.before_transition :to => :parked, :do => lambda {|object| object.callbacks << :parked} - @machine.before_transition :to => :idling, :do => lambda {|object| object.callbacks << :idling} - - @event.fire(@object) - assert_equal [:idling], @object.callbacks - end - - def test_should_support_except_to_requirement - @machine.before_transition :except_to => :parked, :do => lambda {|object| object.callbacks << :parked} - @machine.before_transition :except_to => :idling, :do => lambda {|object| object.callbacks << :idling} - - @event.fire(@object) - assert_equal [:parked], @object.callbacks - end - - def test_should_support_on_requirement - @machine.before_transition :on => :park, :do => lambda {|object| object.callbacks << :park} - @machine.before_transition :on => :ignite, :do => lambda {|object| object.callbacks << :ignite} - - @event.fire(@object) - assert_equal [:ignite], @object.callbacks - end - - def test_should_support_except_on_requirement - @machine.before_transition :except_on => :park, :do => lambda {|object| object.callbacks << :park} - @machine.before_transition :except_on => :ignite, :do => lambda {|object| object.callbacks << :ignite} - - @event.fire(@object) - assert_equal [:park], @object.callbacks - end - - def test_should_support_implicit_requirement - @machine.before_transition :parked => :idling, :do => lambda {|object| object.callbacks << :parked} - @machine.before_transition :idling => :parked, :do => lambda {|object| object.callbacks << :idling} - - @event.fire(@object) - assert_equal [:parked], @object.callbacks - end - - def test_should_track_states_defined_in_transition_callbacks - @machine.before_transition :parked => :idling, :do => lambda {} - @machine.after_transition :first_gear => :second_gear, :do => lambda {} - - assert_equal [:parked, :idling, :first_gear, :second_gear], @machine.states.map {|state| state.name} - end - - def test_should_not_duplicate_states_defined_in_multiple_event_transitions - @machine.before_transition :parked => :idling, :do => lambda {} - @machine.after_transition :first_gear => :second_gear, :do => lambda {} - @machine.after_transition :parked => :idling, :do => lambda {} - - assert_equal [:parked, :idling, :first_gear, :second_gear], @machine.states.map {|state| state.name} - end - - def test_should_define_predicates_for_each_state - [:parked?, :idling?].each {|predicate| assert @object.respond_to?(predicate)} - end -end - -class MachineWithOwnerSubclassTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @subclass = Class.new(@klass) - end - - def test_should_have_a_different_collection_of_state_machines - assert_not_same @klass.state_machines, @subclass.state_machines - end - - def test_should_have_the_same_attribute_associated_state_machines - assert_equal @klass.state_machines, @subclass.state_machines - end -end - -class MachineWithExistingMachinesOnOwnerClassTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @second_machine = StateMachine::Machine.new(@klass, :status, :initial => :idling) - @object = @klass.new - end - - def test_should_track_each_state_machine - expected = {:state => @machine, :status => @second_machine} - assert_equal expected, @klass.state_machines - end - - def test_should_initialize_state_for_both_machines - assert_equal 'parked', @object.state - assert_equal 'idling', @object.status - end -end - -class MachineWithNamespaceTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :namespace => 'car', :initial => :parked) do - event :ignite do - transition :parked => :idling - end - - event :park do - transition :idling => :parked - end - end - @object = @klass.new - end - - def test_should_namespace_state_predicates - [:car_parked?, :car_idling?].each do |name| - assert @object.respond_to?(name) - end - end - - def test_should_namespace_event_checks - [:can_ignite_car?, :can_park_car?].each do |name| - assert @object.respond_to?(name) - end - end - - def test_should_namespace_event_transition_readers - [:next_ignite_car_transition, :next_park_car_transition].each do |name| - assert @object.respond_to?(name) - end - end - - def test_should_namespace_events - [:ignite_car, :park_car].each do |name| - assert @object.respond_to?(name) - end - end - - def test_should_namespace_bang_events - [:ignite_car!, :park_car!].each do |name| - assert @object.respond_to?(name) - end - end -end - -class MachineFinderWithoutExistingMachineTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.find_or_create(@klass) - end - - def test_should_accept_a_block - called = false - StateMachine::Machine.find_or_create(Class.new) do - called = respond_to?(:event) - end - - assert called - end - - def test_should_create_a_new_machine - assert_not_nil @machine - end - - def test_should_use_default_state - assert_equal :state, @machine.attribute - end -end - -class MachineFinderWithExistingOnSameClassTest < Test::Unit::TestCase - def setup - @klass = Class.new - @existing_machine = StateMachine::Machine.new(@klass) - @machine = StateMachine::Machine.find_or_create(@klass) - end - - def test_should_accept_a_block - called = false - StateMachine::Machine.find_or_create(@klass) do - called = respond_to?(:event) - end - - assert called - end - - def test_should_not_create_a_new_machine - assert_same @machine, @existing_machine - end -end - -class MachineFinderWithExistingMachineOnSuperclassTest < Test::Unit::TestCase - def setup - integration = Module.new do - def self.matches?(klass) - false - end - end - StateMachine::Integrations.const_set('Custom', integration) - - @base_class = Class.new - @base_machine = StateMachine::Machine.new(@base_class, :status, :action => :save, :integration => :custom) - @base_machine.event(:ignite) {} - @base_machine.before_transition(lambda {}) - @base_machine.after_transition(lambda {}) - - @klass = Class.new(@base_class) - @machine = StateMachine::Machine.find_or_create(@klass, :status) - end - - def test_should_accept_a_block - called = false - StateMachine::Machine.find_or_create(Class.new(@base_class)) do - called = respond_to?(:event) - end - - assert called - end - - def test_should_create_a_new_machine - assert_not_nil @machine - assert_not_same @machine, @base_machine - end - - def test_should_copy_the_base_attribute - assert_equal :status, @machine.attribute - end - - def test_should_copy_the_base_configuration - assert_equal :save, @machine.action - end - - def test_should_copy_events - # Can't assert equal arrays since their machines change - assert_equal 1, @machine.events.length - end - - def test_should_copy_before_callbacks - assert_equal @base_machine.callbacks[:before], @machine.callbacks[:before] - end - - def test_should_copy_after_transitions - assert_equal @base_machine.callbacks[:after], @machine.callbacks[:after] - end - - def test_should_use_the_same_integration - assert (class << @machine; ancestors; end).include?(StateMachine::Integrations::Custom) - end - - def teardown - StateMachine::Integrations.send(:remove_const, 'Custom') - end -end - -class MachineFinderCustomOptionsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.find_or_create(@klass, :status, :initial => :parked) - @object = @klass.new - end - - def test_should_use_custom_attribute - assert_equal :status, @machine.attribute - end - - def test_should_set_custom_initial_state - assert_equal :parked, @machine.initial_state(@object).name - end -end - -begin - # Load library - require 'rubygems' - require 'graphviz' - - class MachineDrawingTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def self.name; 'Vehicle'; end - end - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @machine.event :ignite do - transition :parked => :idling - end - end - - def test_should_raise_exception_if_invalid_option_specified - assert_raise(ArgumentError) {@machine.draw(:invalid => true)} - end - - def test_should_save_file_with_class_name_by_default - graph = @machine.draw(:output => false) - assert_equal './Vehicle_state.png', graph.instance_variable_get('@filename') - end - - def test_should_allow_base_name_to_be_customized - graph = @machine.draw(:name => 'machine', :output => false) - assert_equal './machine.png', graph.instance_variable_get('@filename') - end - - def test_should_allow_format_to_be_customized - graph = @machine.draw(:format => 'jpg', :output => false) - assert_equal './Vehicle_state.jpg', graph.instance_variable_get('@filename') - assert_equal 'jpg', graph.instance_variable_get('@format') - end - - def test_should_allow_path_to_be_customized - graph = @machine.draw(:path => "#{File.dirname(__FILE__)}/", :output => false) - assert_equal "#{File.dirname(__FILE__)}/Vehicle_state.png", graph.instance_variable_get('@filename') - end - - def test_should_allow_orientation_to_be_landscape - graph = @machine.draw(:orientation => 'landscape', :output => false) - assert_equal 'LR', graph['rankdir'] - end - - def test_should_allow_orientation_to_be_portrait - graph = @machine.draw(:orientation => 'portrait', :output => false) - assert_equal 'TB', graph['rankdir'] - end - end - - class MachineDrawingWithIntegerStatesTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def self.name; 'Vehicle'; end - end - @machine = StateMachine::Machine.new(@klass, :state_id, :initial => :parked) - @machine.event :ignite do - transition :parked => :idling - end - @machine.state :parked, :value => 1 - @machine.state :idling, :value => 2 - @graph = @machine.draw - end - - def test_should_draw_all_states - assert_equal 3, @graph.node_count - end - - def test_should_draw_all_events - assert_equal 2, @graph.edge_count - end - - def test_should_draw_machine - assert File.exist?('./Vehicle_state_id.png') - ensure - FileUtils.rm('./Vehicle_state_id.png') - end - end - - class MachineDrawingWithNilStatesTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def self.name; 'Vehicle'; end - end - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @machine.event :ignite do - transition :parked => :idling - end - @machine.state :parked, :value => nil - @graph = @machine.draw - end - - def test_should_draw_all_states - assert_equal 3, @graph.node_count - end - - def test_should_draw_all_events - assert_equal 2, @graph.edge_count - end - - def test_should_draw_machine - assert File.exist?('./Vehicle_state.png') - ensure - FileUtils.rm('./Vehicle_state.png') - end - end - - class MachineDrawingWithDynamicStatesTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def self.name; 'Vehicle'; end - end - @machine = StateMachine::Machine.new(@klass, :initial => :parked) - @machine.event :activate do - transition :parked => :idling - end - @machine.state :idling, :value => lambda {Time.now} - @graph = @machine.draw - end - - def test_should_draw_all_states - assert_equal 3, @graph.node_count - end - - def test_should_draw_all_events - assert_equal 2, @graph.edge_count - end - - def test_should_draw_machine - assert File.exist?('./Vehicle_state.png') - ensure - FileUtils.rm('./Vehicle_state.png') - end - end - - class MachineClassDrawingTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def self.name; 'Vehicle'; end - end - @machine = StateMachine::Machine.new(@klass) - @machine.event :ignite do - transition :parked => :idling - end - end - - def test_should_raise_exception_if_no_class_names_specified - exception = assert_raise(ArgumentError) {StateMachine::Machine.draw(nil)} - assert_equal 'At least one class must be specified', exception.message - end - - def test_should_load_files - StateMachine::Machine.draw('Switch', :file => "#{File.dirname(__FILE__)}/../classes/switch.rb") - assert defined?(::Switch) - ensure - FileUtils.rm('./Switch_state.png') - end - - def test_should_allow_path_and_format_to_be_customized - StateMachine::Machine.draw('Switch', :file => "#{File.dirname(__FILE__)}/../classes/switch.rb", :path => "#{File.dirname(__FILE__)}/", :format => 'jpg') - assert File.exist?("#{File.dirname(__FILE__)}/Switch_state.jpg") - ensure - FileUtils.rm("#{File.dirname(__FILE__)}/Switch_state.jpg") - end - end -rescue LoadError - $stderr.puts 'Skipping GraphViz StateMachine::Machine tests. `gem install ruby-graphviz` and try again.' -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/matcher_helpers_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/matcher_helpers_test.rb deleted file mode 100644 index 7c092b6..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/matcher_helpers_test.rb +++ /dev/null @@ -1,37 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class MatcherHelpersAllTest < Test::Unit::TestCase - include StateMachine::MatcherHelpers - - def setup - @matcher = all - end - - def test_should_build_an_all_matcher - assert_equal StateMachine::AllMatcher.instance, @matcher - end -end - -class MatcherHelpersAnyTest < Test::Unit::TestCase - include StateMachine::MatcherHelpers - - def setup - @matcher = any - end - - def test_should_build_an_all_matcher - assert_equal StateMachine::AllMatcher.instance, @matcher - end -end - -class MatcherHelpersSameTest < Test::Unit::TestCase - include StateMachine::MatcherHelpers - - def setup - @matcher = same - end - - def test_should_build_a_loopback_matcher - assert_equal StateMachine::LoopbackMatcher.instance, @matcher - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/matcher_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/matcher_test.rb deleted file mode 100644 index 3423b1b..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/matcher_test.rb +++ /dev/null @@ -1,155 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class MatcherByDefaultTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::Matcher.new - end - - def test_should_have_no_values - assert_equal [], @matcher.values - end - - def test_should_filter_all_values - assert_equal [], @matcher.filter([:parked, :idling]) - end -end - -class MatcherWithValueTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::Matcher.new(nil) - end - - def test_should_have_values - assert_equal [nil], @matcher.values - end - - def test_should_filter_unknown_values - assert_equal [nil], @matcher.filter([nil, :parked]) - end -end - -class MatcherWithMultipleValuesTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::Matcher.new([:parked, :idling]) - end - - def test_should_have_values - assert_equal [:parked, :idling], @matcher.values - end - - def test_should_filter_unknown_values - assert_equal [:parked], @matcher.filter([:parked, :first_gear]) - end -end - -class AllMatcherTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::AllMatcher.instance - end - - def test_should_have_no_values - assert_equal [], @matcher.values - end - - def test_should_always_match - [nil, :parked, :idling].each {|value| assert @matcher.matches?(value)} - end - - def test_should_not_filter_any_values - assert_equal [:parked, :idling], @matcher.filter([:parked, :idling]) - end - - def test_should_generate_blacklist_matcher_after_subtraction - matcher = @matcher - [:parked, :idling] - assert_instance_of StateMachine::BlacklistMatcher, matcher - assert_equal [:parked, :idling], matcher.values - end - - def test_should_have_a_description - assert_equal 'all', @matcher.description - end -end - -class WhitelistMatcherTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::WhitelistMatcher.new([:parked, :idling]) - end - - def test_should_have_values - assert_equal [:parked, :idling], @matcher.values - end - - def test_should_filter_unknown_values - assert_equal [:parked, :idling], @matcher.filter([:parked, :idling, :first_gear]) - end - - def test_should_match_known_values - assert @matcher.matches?(:parked) - end - - def test_should_not_match_unknown_values - assert !@matcher.matches?(:first_gear) - end - - def test_should_have_a_description - assert_equal '[:parked, :idling]', @matcher.description - - matcher = StateMachine::WhitelistMatcher.new([:parked]) - assert_equal ':parked', matcher.description - end -end - -class BlacklistMatcherTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::BlacklistMatcher.new([:parked, :idling]) - end - - def test_should_have_values - assert_equal [:parked, :idling], @matcher.values - end - - def test_should_filter_known_values - assert_equal [:first_gear], @matcher.filter([:parked, :idling, :first_gear]) - end - - def test_should_match_unknown_values - assert @matcher.matches?(:first_gear) - end - - def test_should_not_match_known_values - assert !@matcher.matches?(:parked) - end - - def test_should_have_a_description - assert_equal 'all - [:parked, :idling]', @matcher.description - - matcher = StateMachine::BlacklistMatcher.new([:parked]) - assert_equal 'all - :parked', matcher.description - end -end - -class LoopbackMatcherTest < Test::Unit::TestCase - def setup - @matcher = StateMachine::LoopbackMatcher.instance - end - - def test_should_have_no_values - assert_equal [], @matcher.values - end - - def test_should_filter_all_values - assert_equal [], @matcher.filter([:parked, :idling]) - end - - def test_should_match_if_from_context_is_same - assert @matcher.matches?(:parked, :from => :parked) - end - - def test_should_not_match_if_from_context_is_different - assert !@matcher.matches?(:parked, :from => :idling) - end - - def test_should_have_a_description - assert_equal 'same', @matcher.description - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/node_collection_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/node_collection_test.rb deleted file mode 100644 index 15d6a08..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/node_collection_test.rb +++ /dev/null @@ -1,204 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class NodeCollectionByDefaultTest < Test::Unit::TestCase - def setup - @collection = StateMachine::NodeCollection.new - end - - def test_should_not_have_any_nodes - assert_equal 0, @collection.length - end - - def test_should_index_by_name - @collection << object = Struct.new(:name).new(:parked) - assert_equal object, @collection[:parked] - end -end - -class NodeCollectionTest < Test::Unit::TestCase - def setup - @collection = StateMachine::NodeCollection.new - end - - def test_should_raise_exception_if_invalid_option_specified - exception = assert_raise(ArgumentError) { StateMachine::NodeCollection.new(:invalid => true) } - assert_equal 'Invalid key(s): invalid', exception.message - end - - def test_should_raise_exception_on_lookup_if_invalid_index_specified - exception = assert_raise(ArgumentError) { @collection[:something, :invalid] } - assert_equal 'Invalid index: :invalid', exception.message - end - - def test_should_raise_exception_on_fetch_if_invalid_index_specified - exception = assert_raise(ArgumentError) { @collection.fetch(:something, :invalid) } - assert_equal 'Invalid index: :invalid', exception.message - end -end - -class NodeCollectionAfterBeingCopiedTest < Test::Unit::TestCase - def setup - @collection = StateMachine::NodeCollection.new - @collection << @parked = Struct.new(:name).new(:parked) - - @copied_collection = @collection.dup - @copied_collection << @idling = Struct.new(:name).new(:idling) - end - - def test_should_not_modify_the_original_list - assert_equal 1, @collection.length - assert_equal 2, @copied_collection.length - end - - def test_should_not_modify_the_indices - assert_nil @collection[:idling] - assert_equal @idling, @copied_collection[:idling] - end - - def test_should_copy_each_node - assert_not_same @parked, @copied_collection[:parked] - end -end - -class NodeCollectionWithoutIndicesTest < Test::Unit::TestCase - def setup - @collection = StateMachine::NodeCollection.new(:index => {}) - end - - def test_should_allow_adding_node - @collection << Object.new - assert_equal 1, @collection.length - end - - def test_should_not_allow_keys_retrieval - exception = assert_raise(ArgumentError) { @collection.keys } - assert_equal 'No indices configured', exception.message - end - - def test_should_not_allow_lookup - @collection << object = Object.new - exception = assert_raise(ArgumentError) { @collection[0] } - assert_equal 'No indices configured', exception.message - end - - def test_should_not_allow_fetching - @collection << object = Object.new - exception = assert_raise(ArgumentError) { @collection.fetch(0) } - assert_equal 'No indices configured', exception.message - end -end - -class NodeCollectionWithIndicesTest < Test::Unit::TestCase - def setup - @collection = StateMachine::NodeCollection.new(:index => [:name, :value]) - - @object = Struct.new(:name, :value).new(:parked, 1) - @collection << @object - end - - def test_should_use_first_index_by_default_on_key_retrieval - assert_equal [:parked], @collection.keys - end - - def test_should_allow_customizing_index_for_key_retrieval - assert_equal [1], @collection.keys(:value) - end - - def test_should_use_first_index_by_default_on_lookup - assert_equal @object, @collection[:parked] - assert_nil @collection[1] - end - - def test_should_allow_customizing_index_on_lookup - assert_equal @object, @collection[1, :value] - assert_nil @collection[:parked, :value] - end - - def test_should_use_first_index_by_default_on_fetch - assert_equal @object, @collection.fetch(:parked) - exception = assert_raise(ArgumentError) { @collection.fetch(1) } - assert_equal '1 is an invalid name', exception.message - end - - def test_should_allow_customizing_index_on_fetch - assert_equal @object, @collection.fetch(1, :value) - exception = assert_raise(ArgumentError) { @collection.fetch(:parked, :value) } - assert_equal ':parked is an invalid value', exception.message - end -end - -class NodeCollectionWithNodesTest < Test::Unit::TestCase - def setup - @collection = StateMachine::NodeCollection.new - - @klass = Struct.new(:name) - @parked = @klass.new(:parked) - @idling = @klass.new(:idling) - - @collection << @parked - @collection << @idling - end - - def test_should_be_able_to_enumerate - order = [] - @collection.each {|object| order << object} - - assert_equal [@parked, @idling], order - end - - def test_should_be_able_to_access_by_index - assert_equal @parked, @collection.at(0) - assert_equal @idling, @collection.at(1) - end -end - -class NodeCollectionAfterUpdateTest < Test::Unit::TestCase - def setup - @collection = StateMachine::NodeCollection.new(:index => [:name, :value]) - - @klass = Struct.new(:name, :value) - @parked = @klass.new(:parked, 1) - @idling = @klass.new(:idling, 2) - - @collection << @parked << @idling - - @parked.name = :parking - @parked.value = 0 - @collection.update(@parked) - end - - def test_should_not_change_the_index - assert_equal @parked, @collection.at(0) - end - - def test_should_not_duplicate_in_the_collection - assert_equal 2, @collection.length - end - - def test_should_add_each_indexed_key - assert_equal @parked, @collection[:parking] - assert_equal @parked, @collection[0, :value] - end - - def test_should_remove_each_old_indexed_key - assert_nil @collection[:parked] - assert_nil @collection[1, :value] - end -end - -class NodeCollectionChangingMachineTest < Test::Unit::TestCase - def setup - @collection = StateMachine::NodeCollection.new - - @klass = Struct.new(:name, :machine) - @collection << @parked = @klass.new(:parked) - @collection << @idling = @klass.new(:idling) - - @collection.machine = :machine - end - - def test_should_update_each_node_machine - assert_equal :machine, @parked.machine - assert_equal :machine, @idling.machine - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/state_collection_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/state_collection_test.rb deleted file mode 100644 index 9e7e9c8..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/state_collection_test.rb +++ /dev/null @@ -1,163 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class StateCollectionByDefaultTest < Test::Unit::TestCase - def setup - @states = StateMachine::StateCollection.new - end - - def test_should_not_have_any_nodes - assert_equal 0, @states.length - end - - def test_should_be_empty_by_priority - assert_equal [], @states.by_priority - end -end - -class StateCollectionWithInitialStateTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - - @states = StateMachine::StateCollection.new - @states << @parked = StateMachine::State.new(@machine, :parked) - @states << @idling = StateMachine::State.new(@machine, :idling) - - @parked.initial = true - end - - def test_should_order_state_before_transition_states - @machine.event :ignite do - transition :to => :idling - end - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_state_before_states_with_behaviors - @idling.context do - def speed - 0 - end - end - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_state_before_other_states - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_state_before_callback_states - @machine.before_transition :from => :idling, :do => lambda {} - assert_equal [@parked, @idling], @states.by_priority - end -end - -class StateCollectionWithStateBehaviorsTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - - @states = StateMachine::StateCollection.new - @states << @parked = StateMachine::State.new(@machine, :parked) - @states << @idling = StateMachine::State.new(@machine, :idling) - - @idling.context do - def speed - 0 - end - end - end - - def test_should_order_states_after_initial_state - @parked.initial = true - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_states_after_transition_states - @machine.event :ignite do - transition :from => :parked - end - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_states_before_other_states - assert_equal [@idling, @parked], @states.by_priority - end - - def test_should_order_state_before_callback_states - @machine.before_transition :from => :parked, :do => lambda {} - assert_equal [@idling, @parked], @states.by_priority - end -end - -class StateCollectionWithEventTransitionsTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - - @states = StateMachine::StateCollection.new - @states << @parked = StateMachine::State.new(@machine, :parked) - @states << @idling = StateMachine::State.new(@machine, :idling) - - @machine.event :ignite do - transition :to => :idling - end - end - - def test_should_order_states_after_initial_state - @parked.initial = true - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_states_before_states_with_behaviors - @parked.context do - def speed - 0 - end - end - assert_equal [@idling, @parked], @states.by_priority - end - - def test_should_order_states_before_other_states - assert_equal [@idling, @parked], @states.by_priority - end - - def test_should_order_state_before_callback_states - @machine.before_transition :from => :parked, :do => lambda {} - assert_equal [@idling, @parked], @states.by_priority - end -end - -class StateCollectionWithTransitionCallbacksTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - - @states = StateMachine::StateCollection.new - @states << @parked = StateMachine::State.new(@machine, :parked) - @states << @idling = StateMachine::State.new(@machine, :idling) - - @machine.before_transition :to => :idling, :do => lambda {} - end - - def test_should_order_states_after_initial_state - @parked.initial = true - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_states_after_transition_states - @machine.event :ignite do - transition :from => :parked - end - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_states_after_states_with_behaviors - @parked.context do - def speed - 0 - end - end - assert_equal [@parked, @idling], @states.by_priority - end - - def test_should_order_states_after_other_states - assert_equal [@parked, @idling], @states.by_priority - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/state_machine_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/state_machine_test.rb deleted file mode 100644 index 57dc0cf..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/state_machine_test.rb +++ /dev/null @@ -1,31 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class StateMachineByDefaultTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = @klass.state_machine - end - - def test_should_use_state_attribute - assert_equal :state, @machine.attribute - end -end - -class StateMachineTest < Test::Unit::TestCase - def setup - @klass = Class.new - end - - def test_should_allow_state_machines_on_any_class - assert @klass.respond_to?(:state_machine) - end - - def test_should_evaluate_block_within_machine_context - responded = false - @klass.state_machine(:state) do - responded = respond_to?(:event) - end - - assert responded - end -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/state_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/state_test.rb deleted file mode 100644 index 2aae142..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/state_test.rb +++ /dev/null @@ -1,714 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class StateByDefaultTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked) - end - - def test_should_have_a_machine - assert_equal @machine, @state.machine - end - - def test_should_have_a_name - assert_equal :parked, @state.name - end - - def test_should_use_stringify_the_name_as_the_value - assert_equal 'parked', @state.value - end - - def test_should_not_be_initial - assert !@state.initial - end - - def test_should_not_have_a_matcher - assert_nil @state.matcher - end - - def test_should_not_have_any_methods - expected = {} - assert_equal expected, @state.methods - end -end - -class StateTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked) - end - - def test_should_raise_exception_if_invalid_option_specified - exception = assert_raise(ArgumentError) {StateMachine::State.new(@machine, :parked, :invalid => true)} - assert_equal 'Invalid key(s): invalid', exception.message - end - - def test_should_allow_changing_machine - new_machine = StateMachine::Machine.new(Class.new) - @state.machine = new_machine - assert_equal new_machine, @state.machine - end - - def test_should_allow_changing_value - @state.value = 1 - assert_equal 1, @state.value - end - - def test_should_allow_changing_initial - @state.initial = true - assert @state.initial - end - - def test_should_allow_changing_matcher - matcher = lambda {} - @state.matcher = matcher - assert_equal matcher, @state.matcher - end - - def test_should_use_pretty_inspect - assert_equal '#<StateMachine::State name=:parked value="parked" initial=false context=[]>', @state.inspect - end -end - -class StateWithoutNameTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, nil) - end - - def test_should_have_a_nil_name - assert_nil @state.name - end - - def test_should_have_a_nil_value - assert_nil @state.value - end - - def test_should_not_redefine_nil_predicate - object = @klass.new - assert !object.nil? - assert !object.respond_to?('?') - end - - def test_should_have_a_description - assert_equal 'nil', @state.description - end -end - -class StateWithNameTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, :parked) - end - - def test_should_have_a_name - assert_equal :parked, @state.name - end - - def test_should_use_stringify_the_name_as_the_value - assert_equal 'parked', @state.value - end - - def test_should_match_stringified_name - assert @state.matches?('parked') - assert !@state.matches?('idling') - end - - def test_should_not_include_value_in_description - assert_equal 'parked', @state.description - end - - def test_should_define_predicate - assert @klass.new.respond_to?(:parked?) - end -end - -class StateWithNilValueTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, :parked, :value => nil) - end - - def test_should_have_a_name - assert_equal :parked, @state.name - end - - def test_should_have_a_nil_value - assert_nil @state.value - end - - def test_should_match_nil_values - assert @state.matches?(nil) - end - - def test_should_have_a_description - assert_equal 'parked (nil)', @state.description - end - - def test_should_define_predicate - object = @klass.new - assert object.respond_to?(:parked?) - end -end - -class StateWithSymbolicValueTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, :parked, :value => :parked) - end - - def test_should_use_custom_value - assert_equal :parked, @state.value - end - - def test_should_not_include_value_in_description - assert_equal 'parked', @state.description - end - - def test_should_match_symbolic_value - assert @state.matches?(:parked) - assert !@state.matches?('parked') - end - - def test_should_define_predicate - object = @klass.new - assert object.respond_to?(:parked?) - end -end - -class StateWithIntegerValueTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, :parked, :value => 1) - end - - def test_should_use_custom_value - assert_equal 1, @state.value - end - - def test_should_include_value_in_description - assert_equal 'parked (1)', @state.description - end - - def test_should_match_integer_value - assert @state.matches?(1) - assert !@state.matches?(2) - end - - def test_should_define_predicate - object = @klass.new - assert object.respond_to?(:parked?) - end -end - -class StateWithLambdaValueTest < Test::Unit::TestCase - def setup - @klass = Class.new - @args = nil - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, :parked, :value => lambda {|*args| @args = args; :parked}) - end - - def test_should_use_evaluated_value - assert_equal :parked, @state.value - end - - def test_should_include_masked_value_in_description - assert_equal 'parked (*)', @state.description - end - - def test_should_not_pass_in_any_arguments - @state.value - assert_equal [], @args - end - - def test_should_define_predicate - object = @klass.new - assert object.respond_to?(:parked?) - end -end - -class StateWithMatcherTest < Test::Unit::TestCase - def setup - @klass = Class.new - @args = nil - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, :parked, :if => lambda {|value| value == 1}) - end - - def test_should_not_match_actual_value - assert !@state.matches?('parked') - end - - def test_should_match_evaluated_block - assert @state.matches?(1) - end -end - -class StateInitialTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked, :initial => true) - end - - def test_should_be_initial - assert @state.initial - assert @state.initial? - end -end - -class StateNotInitialTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked, :initial => false) - end - - def test_should_not_be_initial - assert !@state.initial - assert !@state.initial? - end -end - -class StateFinalTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked) - end - - def test_should_be_final_without_input_transitions - assert @state.final? - end - - def test_should_be_final_with_input_transitions - @machine.event :park do - transition :idling => :parked - end - - assert @state.final? - end - - def test_should_be_final_with_loopback - @machine.event :ignite do - transition :parked => same - end - - assert @state.final? - end -end - -class StateNotFinalTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked) - end - - def test_should_not_be_final_with_outgoing_whitelist_transitions - @machine.event :ignite do - transition :parked => :idling - end - - assert !@state.final? - end - - def test_should_not_be_final_with_outgoing_all_transitions - @machine.event :ignite do - transition all => :idling - end - - assert !@state.final? - end - - def test_should_not_be_final_with_outgoing_blacklist_transitions - @machine.event :ignite do - transition all - :first_gear => :idling - end - - assert !@state.final? - end -end - -class StateWithConflictingHelpersTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def parked? - 0 - end - end - @machine = StateMachine::Machine.new(@klass) - @machine.state :parked - @object = @klass.new - end - - def test_should_not_redefine_state_predicate - assert_equal 0, @object.parked? - end - - def test_should_allow_super_chaining - @klass.class_eval do - def parked? - super ? 1 : 0 - end - end - - assert_equal 0, @object.parked? - end -end - -class StateWithNamespaceTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass, :namespace => 'gear') - @state = StateMachine::State.new(@machine, :parked) - @object = @klass.new - end - - def test_should_namespace_predicate - assert @object.respond_to?(:gear_parked?) - end -end - -class StateAfterBeingCopiedTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked) - @copied_state = @state.dup - end - - def test_should_not_have_the_same_collection_of_methods - assert_not_same @state.methods, @copied_state.methods - end -end - -class StateWithContextTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @ancestors = @klass.ancestors - @state = StateMachine::State.new(@machine, :idling) - - speed_method = nil - rpm_method = nil - @state.context do - def speed - 0 - end - speed_method = instance_method(:speed) - - def rpm - 1000 - end - rpm_method = instance_method(:rpm) - end - - @speed_method = speed_method - @rpm_method = rpm_method - end - - def test_should_include_new_module_in_owner_class - assert_not_equal @ancestors, @klass.ancestors - assert_equal 1, @klass.ancestors.size - @ancestors.size - end - - def test_should_define_each_context_method_in_owner_class - %w(speed rpm).each {|method| assert @klass.method_defined?(method)} - end - - def test_should_not_use_context_methods_as_owner_class_methods - assert_not_equal @speed_method, @klass.instance_method(:speed) - assert_not_equal @rpm_method, @klass.instance_method(:rpm) - end - - def test_should_include_context_methods_in_state_methods - assert_equal @speed_method, @state.methods[:speed] - assert_equal @rpm_method, @state.methods[:rpm] - end -end - -class StateWithMultipleContextsTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @ancestors = @klass.ancestors - @state = StateMachine::State.new(@machine, :idling) - - speed_method = nil - @state.context do - def speed - 0 - end - - speed_method = instance_method(:speed) - end - @speed_method = speed_method - - rpm_method = nil - @state.context do - def rpm - 1000 - end - - rpm_method = instance_method(:rpm) - end - @rpm_method = rpm_method - end - - def test_should_include_new_module_in_owner_class - assert_not_equal @ancestors, @klass.ancestors - assert_equal 2, @klass.ancestors.size - @ancestors.size - end - - def test_should_define_each_context_method_in_owner_class - %w(speed rpm).each {|method| assert @klass.method_defined?(method)} - end - - def test_should_not_use_context_methods_as_owner_class_methods - assert_not_equal @speed_method, @klass.instance_method(:speed) - assert_not_equal @rpm_method, @klass.instance_method(:rpm) - end - - def test_should_include_context_methods_in_state_methods - assert_equal @speed_method, @state.methods[:speed] - assert_equal @rpm_method, @state.methods[:rpm] - end -end - -class StateWithExistingContextMethodTest < Test::Unit::TestCase - def setup - @klass = Class.new do - def speed - 60 - end - end - @original_speed_method = @klass.instance_method(:speed) - - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, :idling) - @state.context do - def speed - 0 - end - end - end - - def test_should_not_override_method - assert_equal @original_speed_method, @klass.instance_method(:speed) - end -end - -class StateWithRedefinedContextMethodTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @state = StateMachine::State.new(@machine, 'on') - - old_speed_method = nil - @state.context do - def speed - 0 - end - old_speed_method = instance_method(:speed) - end - @old_speed_method = old_speed_method - - current_speed_method = nil - @state.context do - def speed - 'green' - end - current_speed_method = instance_method(:speed) - end - @current_speed_method = current_speed_method - end - - def test_should_track_latest_defined_method - assert_equal @current_speed_method, @state.methods[:speed] - end -end - -class StateWithInvalidMethodCallTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @ancestors = @klass.ancestors - @state = StateMachine::State.new(@machine, :idling) - @state.context do - def speed - 0 - end - end - - @object = @klass.new - end - - def test_should_raise_an_exception - exception = assert_raise(NoMethodError) { @state.call(@object, :invalid) } - assert_equal "undefined method 'invalid' for #{@object} in state nil", exception.message - end -end - -class StateWithValidMethodCallTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @ancestors = @klass.ancestors - @state = StateMachine::State.new(@machine, :idling) - @state.context do - def speed(arg = nil) - block_given? ? [arg, yield] : arg - end - end - - @object = @klass.new - end - - def test_should_not_raise_an_exception - assert_nothing_raised { @state.call(@object, :speed) } - end - - def test_should_pass_arguments_through - assert_equal 1, @state.call(@object, :speed, 1) - end - - def test_should_pass_blocks_through - assert_equal [nil, 1], @state.call(@object, :speed) {1} - end - - def test_should_pass_both_arguments_and_blocks_through - assert_equal [1, 2], @state.call(@object, :speed, 1) {2} - end -end - -begin - # Load library - require 'rubygems' - require 'graphviz' - - class StateDrawingTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @machine.event :ignite do - transition :parked => :idling - end - @state = StateMachine::State.new(@machine, :parked, :value => 1) - - graph = GraphViz.new('G') - @node = @state.draw(graph) - end - - def test_should_use_ellipse_shape - assert_equal 'ellipse', @node['shape'] - end - - def test_should_set_width_to_one - assert_equal '1', @node['width'] - end - - def test_should_set_height_to_one - assert_equal '1', @node['height'] - end - - def test_should_use_stringified_name_as_name - assert_equal 'parked', @node.name - end - - def test_should_use_description_as_label - assert_equal 'parked (1)', @node['label'] - end - end - - class StateDrawingInitialTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @machine.event :ignite do - transition :parked => :idling - end - @state = StateMachine::State.new(@machine, :parked, :initial => true) - - @graph = GraphViz.new('G') - @node = @state.draw(@graph) - end - - def test_should_use_ellipse_as_shape - assert_equal 'ellipse', @node['shape'] - end - - def test_should_draw_edge_between_point_and_state - assert_equal 2, @graph.node_count - assert_equal 1, @graph.edge_count - end - end - - class StateDrawingNilNameTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, nil) - - graph = GraphViz.new('G') - @node = @state.draw(graph) - end - - def test_should_use_stringified_nil_as_name - assert_equal 'nil', @node.name - end - - def test_should_use_description_as_label - assert_equal 'nil', @node['label'] - end - end - - class StateDrawingLambdaValueTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked, :value => lambda {}) - - graph = GraphViz.new('G') - @node = @state.draw(graph) - end - - def test_should_use_stringified_name_as_name - assert_equal 'parked', @node.name - end - - def test_should_use_description_as_label - assert_equal 'parked (*)', @node['label'] - end - end - - class StateDrawingNonFinalTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @machine.event :ignite do - transition :parked => :idling - end - @state = StateMachine::State.new(@machine, :parked) - - graph = GraphViz.new('G') - @node = @state.draw(graph) - end - - def test_should_use_ellipse_as_shape - assert_equal 'ellipse', @node['shape'] - end - end - - class StateDrawingFinalTest < Test::Unit::TestCase - def setup - @machine = StateMachine::Machine.new(Class.new) - @state = StateMachine::State.new(@machine, :parked) - - graph = GraphViz.new('G') - @node = @state.draw(graph) - end - - def test_should_use_doublecircle_as_shape - assert_equal 'doublecircle', @node['shape'] - end - end -rescue LoadError - $stderr.puts 'Skipping GraphViz StateMachine::State tests. `gem install ruby-graphviz` and try again.' -end diff --git a/vendor/plugins/state_machine-0.6.3/test/unit/transition_test.rb b/vendor/plugins/state_machine-0.6.3/test/unit/transition_test.rb deleted file mode 100644 index e8da0c9..0000000 --- a/vendor/plugins/state_machine-0.6.3/test/unit/transition_test.rb +++ /dev/null @@ -1,442 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../test_helper') - -class TransitionTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @machine.state :parked, :idling - - @object = @klass.new - @object.state = 'parked' - - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - end - - def test_should_have_an_object - assert_equal @object, @transition.object - end - - def test_should_have_a_machine - assert_equal @machine, @transition.machine - end - - def test_should_have_an_event - assert_equal :ignite, @transition.event - end - - def test_should_have_a_from_value - assert_equal 'parked', @transition.from - end - - def test_should_have_a_from_name - assert_equal :parked, @transition.from_name - end - - def test_should_have_a_to_value - assert_equal 'idling', @transition.to - end - - def test_should_have_a_to_name - assert_equal :idling, @transition.to_name - end - - def test_should_have_an_attribute - assert_equal :state, @transition.attribute - end - - def test_should_generate_attributes - expected = {:object => @object, :attribute => :state, :event => :ignite, :from => 'parked', :to => 'idling'} - assert_equal expected, @transition.attributes - end - - def test_should_use_pretty_inspect - assert_equal '#<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>', @transition.inspect - end -end - -class TransitionWithDynamicToValueTest < Test::Unit::TestCase - def setup - @klass = Class.new - @machine = StateMachine::Machine.new(@klass) - @machine.state :parked - @machine.state :idling, :value => lambda {1} - - @object = @klass.new - @object.state = 'parked' - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - end - - def test_should_evaluate_to_value - assert_equal 1, @transition.to - end -end - -class TransitionAfterBeingPerformedTest < Test::Unit::TestCase - def setup - @klass = Class.new do - attr_reader :saved, :save_state - - def save - @save_state = state - @saved = true - end - end - - @machine = StateMachine::Machine.new(@klass, :action => :save) - @machine.state :parked, :idling - - @object = @klass.new - @object.state = 'parked' - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - @result = @transition.perform - end - - def test_should_be_successful - assert_equal true, @result - end - - def test_should_the_current_state - assert_equal 'idling', @object.state - end - - def test_should_run_the_action - assert @object.saved - end - - def test_should_run_the_action_after_saving_the_state - assert_equal 'idling', @object.save_state - end -end - -class TransitionWithoutRunningActionTest < Test::Unit::TestCase - def setup - @klass = Class.new do - attr_reader :saved - - def save - @saved = true - end - end - - @machine = StateMachine::Machine.new(@klass, :action => :save) - @machine.state :parked, :idling - - @object = @klass.new - @object.state = 'parked' - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - @result = @transition.perform(false) - end - - def test_should_be_successful - assert_equal true, @result - end - - def test_should_the_current_state - assert_equal 'idling', @object.state - end - - def test_should_not_run_the_action - assert !@object.saved - end -end - -class TransitionWithCallbacksTest < Test::Unit::TestCase - def setup - @klass = Class.new do - attr_reader :saved, :save_state - - def save - @save_state = state - @saved = true - end - end - - @machine = StateMachine::Machine.new(@klass) - @machine.state :parked, :idling - - @object = @klass.new - @object.state = 'parked' - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - end - - def test_should_run_before_callbacks_before_changing_the_state - @machine.before_transition(lambda {|object| @state = object.state}) - @transition.perform - - assert_equal 'parked', @state - end - - def test_should_run_after_callbacks_after_running_the_action - @machine.after_transition(lambda {|object| @state = object.state}) - @transition.perform - - assert_equal 'idling', @state - end - - def test_should_run_before_callbacks_in_the_order_they_were_defined - @callbacks = [] - @machine.before_transition(lambda {@callbacks << 1}) - @machine.before_transition(lambda {@callbacks << 2}) - @transition.perform - - assert_equal [1, 2], @callbacks - end - - def test_should_run_after_callbacks_in_the_order_they_were_defined - @callbacks = [] - @machine.after_transition(lambda {@callbacks << 1}) - @machine.after_transition(lambda {@callbacks << 2}) - @transition.perform - - assert_equal [1, 2], @callbacks - end - - def test_should_only_run_before_callbacks_that_match_transition_context - @count = 0 - callback = lambda {@count += 1} - - @machine.before_transition :from => :parked, :to => :idling, :on => :park, :do => callback - @machine.before_transition :from => :parked, :to => :parked, :on => :park, :do => callback - @machine.before_transition :from => :parked, :to => :idling, :on => :ignite, :do => callback - @machine.before_transition :from => :idling, :to => :idling, :on => :park, :do => callback - @transition.perform - - assert_equal 1, @count - end - - def test_should_only_run_after_callbacks_that_match_transition_context - @count = 0 - callback = lambda {@count += 1} - - @machine.after_transition :from => :parked, :to => :idling, :on => :park, :do => callback - @machine.after_transition :from => :parked, :to => :parked, :on => :park, :do => callback - @machine.after_transition :from => :parked, :to => :idling, :on => :ignite, :do => callback - @machine.after_transition :from => :idling, :to => :idling, :on => :park, :do => callback - @transition.perform - - assert_equal 1, @count - end - - def test_should_pass_transition_to_before_callbacks - @machine.before_transition(lambda {|*args| @args = args}) - @transition.perform - - assert_equal [@object, @transition], @args - end - - def test_should_pass_transition_and_action_result_to_after_callbacks - @machine.after_transition(lambda {|*args| @args = args}) - @transition.perform - - assert_equal [@object, @transition, true], @args - end -end - -class TransitionHaltedDuringBeforeCallbacksTest < Test::Unit::TestCase - def setup - @klass = Class.new do - class << self; attr_accessor :cancelled_transaction; end - attr_reader :saved - - def save - @saved = true - end - end - @before_count = 0 - @after_count = 0 - - @machine = StateMachine::Machine.new(@klass, :action => :save) - @machine.state :parked, :idling - class << @machine - def within_transaction(object) - owner_class.cancelled_transaction = yield == false - end - end - - @machine.before_transition lambda {@before_count += 1; throw :halt} - @machine.before_transition lambda {@before_count += 1} - @machine.after_transition lambda {@after_count += 1} - - @object = @klass.new - @object.state = 'parked' - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - @result = @transition.perform - end - - def test_should_not_be_successful - assert !@result - end - - def test_should_not_change_current_state - assert_equal 'parked', @object.state - end - - def test_should_not_run_action - assert !@object.saved - end - - def test_should_not_run_further_before_callbacks - assert_equal 1, @before_count - end - - def test_should_not_run_after_callbacks - assert_equal 0, @after_count - end - - def test_should_cancel_the_transaction - assert @klass.cancelled_transaction - end -end - -class TransitionHaltedDuringActionTest < Test::Unit::TestCase - def setup - @klass = Class.new do - class << self; attr_accessor :cancelled_transaction; end - attr_reader :saved - - def save - throw :halt - end - end - @before_count = 0 - @after_count = 0 - - @machine = StateMachine::Machine.new(@klass, :action => :save) - @machine.state :parked, :idling - class << @machine - def within_transaction(object) - owner_class.cancelled_transaction = yield == false - end - end - - @machine.before_transition lambda {@before_count += 1} - @machine.after_transition lambda {@after_count += 1} - - @object = @klass.new - @object.state = 'parked' - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - @result = @transition.perform - end - - def test_should_not_be_successful - assert !@result - end - - def test_should_change_current_state - assert_equal 'idling', @object.state - end - - def test_should_run_before_callbacks - assert_equal 1, @before_count - end - - def test_should_not_run_after_callbacks - assert_equal 0, @after_count - end - - def test_should_cancel_the_transaction - assert @klass.cancelled_transaction - end -end - -class TransitionHaltedAfterCallbackTest < Test::Unit::TestCase - def setup - @klass = Class.new do - class << self; attr_accessor :cancelled_transaction; end - attr_reader :saved - - def save - @saved = true - end - end - @before_count = 0 - @after_count = 0 - - @machine = StateMachine::Machine.new(@klass, :action => :save) - @machine.state :parked, :idling - class << @machine - def within_transaction(object) - owner_class.cancelled_transaction = yield == false - end - end - - @machine.before_transition lambda {@before_count += 1} - @machine.after_transition lambda {@after_count += 1; throw :halt} - @machine.after_transition lambda {@after_count += 1} - - @object = @klass.new - @object.state = 'parked' - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - @result = @transition.perform - end - - def test_should_be_successful - assert @result - end - - def test_should_change_current_state - assert_equal 'idling', @object.state - end - - def test_should_run_before_callbacks - assert_equal 1, @before_count - end - - def test_should_not_run_further_after_callbacks - assert_equal 1, @after_count - end - - def test_should_not_cancel_the_transaction - assert !@klass.cancelled_transaction - end -end - -class TransitionWithFailedActionTest < Test::Unit::TestCase - def setup - @klass = Class.new do - class << self; attr_accessor :cancelled_transaction; end - attr_reader :saved - - def save - false - end - end - @before_count = 0 - @after_count = 0 - - @machine = StateMachine::Machine.new(@klass, :action => :save) - @machine.state :parked, :idling - class << @machine - def within_transaction(object) - owner_class.cancelled_transaction = yield == false - end - end - - @machine.before_transition lambda {@before_count += 1} - @machine.after_transition lambda {@after_count += 1} - - @object = @klass.new - @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling) - @result = @transition.perform - end - - def test_should_not_be_successful - assert !@result - end - - def test_should_change_current_state - assert_equal 'idling', @object.state - end - - def test_should_run_before_callbacks - assert_equal 1, @before_count - end - - def test_should_run_after_callbacks - assert_equal 1, @after_count - end - - def test_should_cancel_the_transaction - assert @klass.cancelled_transaction - end -end |