[
  {
    "path": ".document",
    "content": "README.rdoc\nlib/**/*.rb\nbin/*\nfeatures/**/*.feature\n-\nLICENSE\n"
  },
  {
    "path": ".gitignore",
    "content": "*.sw?\n*~\n.DS_Store\n.idea\ncoverage\npkg\nrdoc\nGemfile.lock\nspec/debug.log\nspec/*.db\nTODO\n.rvmrc\nalto\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: ruby\nrvm:\n  - 1.8.7\n  - 1.9.2\n  - 1.9.3\n  - 2.0.0\n  # - jruby-18mode # JRuby in 1.8 mode\n  # - jruby-19mode # JRuby in 1.9 mode\n  - rbx-18mode\n  - rbx-19mode\nservices: mongodb\n"
  },
  {
    "path": "API",
    "content": "\nOverwrite method to read the current state. Used to provide another storage mechanism,\ndifferent from the standard Rails read_attribute method.\n\n  class MyClass\n    include AASM\n\n    def aasm_read_state\n      # retrieve the current state manually\n    end\n  end\n\n\nOverwrite method to write the current state (and actually persist it). Used to provide\nanother storage mechanism, different from the standard Rails write_attribute method.\n\n  class MyClass\n    include AASM\n\n    def aasm_write_state\n      # store and persist the current state manually\n    end\n  end\n\n\nOverwrite method to write the current state (without persisting it).\n\n  class MyClass\n    include AASM\n\n    def aasm_write_state_without_persistence\n      # store the current state manually\n    end\n  end\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# CHANGELOG\n\n## 3.0.19\n\n * fixed deprecation warning with *Rails 4* (`Relation#update_all` with conditions is deprecated)\n * fixing [issue #69](https://github.com/aasm/aasm/issues/69) ( *ActiveRecord* scopes are not chainable)\n\n## 3.0.18\n\n * fixing [issue #66](https://github.com/aasm/aasm/issues/66) (state methods not reflecting the current state)\n\n## 3.0.17\n\n * supporting instance level inspection for states (including permissible state, see [issue #54](https://github.com/aasm/aasm/issues/54))\n * added autocreation of constants for each state ([@jherdman](https://github.com/jherdman))\n\n## 3.0.16\n\n * added autocreation of state scopes for Mongoid (thanks to [@jonnyshields](https://github.com/johnnyshields))\n\n## 3.0.15\n\n * added support for localized state names (on a class level, like `Record.aasm.states.map(&:localized_name)`)\n\n## 3.0.14\n\n * supporting event inspection for to-states transitions (`Event#transitions_to_state?`)\n\n## 3.0.13\n\n * supporting *ActiveRecord* transactions when firing an event\n\n## 3.0.12\n\n * `aasm_from_states_for_state` now supports to filter for specific transition\n\n## 3.0.11\n\n * added class method `aasm_from_states_for_state` to retrieve all from states (regarding transitions) for a given state\n\n## 3.0.10\n\n * added support for transitions from all other states (thanks to [@swrobel](https://github.com/swrobel))\n\n## 3.0.9\n\n * guard checks (e.g. `may_edit?`) now support guard parameters as well\n\n## 3.0.8\n\n * fixed issue with generating docs using yard\n\n## 3.0.7\n\n * removed deprecation warning when localizing aasm state names (look at [issue #38](https://github.com/rubyist/aasm/issues/38) for details)\n\n## 3.0.6\n\n * bugfix: if configured to skip validation the code does not validate anymore\n\n## 3.0.5\n\n * bugfix: get rid of error with old rubygems versions\n\n## 3.0.4\n\n * bugfix: Subclasses of aasm-enabled classes don't lose settings anymore (thanks to codez)\n\n## 3.0.3\n\n * bugfix: ActiveRecord scopes are generated when using the new DSL\n\n## 3.0.2\n\n * ActiveRecord persistence can ignore validation when trying to save invalid models\n\n## 3.0.1\n\n * added support for Mongoid (Thanks, Michał Taberski)\n\n## 3.0.0\n\n * switched documentation to the new DSL\n * whiny transactions: by default, raise an exception if an event transition is not possible\n * you may disable whiny transactions\n\n## 2.4.0\n\n * supporting new DSL (which is much shorter)\n\n## 2.3.1\n\n * bugfix: avoid naming conflict with i18n\n\n## 2.3.0\n\n * supporting i18n\n * supporting regular expressions for hash values and strings\n\n"
  },
  {
    "path": "Gemfile",
    "content": "source 'https://rubygems.org'\n\ngemspec\n"
  },
  {
    "path": "HOWTO",
    "content": "How to\n\n1. Run tests for Mongoid\n\nStart MongoDB\n\n  $> mongod\n\nRun the specs\n\n  $> rspec spec/unit/persistence/mongoid_persistance_spec.rb\n\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2006-2012 Scott Barron\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# AASM - Ruby state machines [![Build Status](https://secure.travis-ci.org/aasm/aasm.png)](http://travis-ci.org/aasm/aasm) [![Code Climate](https://codeclimate.com/github/aasm/aasm.png)](https://codeclimate.com/github/aasm/aasm) [![Coverage Status](https://coveralls.io/repos/aasm/aasm/badge.png?branch=master)](https://coveralls.io/r/aasm/aasm)\n\nThis package contains AASM, a library for adding finite state machines to Ruby classes.\n\nAASM started as the *acts_as_state_machine* plugin but has evolved into a more generic library\nthat no longer targets only ActiveRecord models. It currently provides adapters for\n[ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html) and\n[Mongoid](http://mongoid.org/), but it can be used for any Ruby class, no matter what\nparent class it has (if any).\n\n## Usage\n\nAdding a state machine is as simple as including the AASM module and start defining\n**states** and **events** together with their **transitions**:\n\n```ruby\nclass Job\n  include AASM\n\n  aasm do\n    state :sleeping, :initial => true\n    state :running\n    state :cleaning\n\n    event :run do\n      transitions :from => :sleeping, :to => :running\n    end\n\n    event :clean do\n      transitions :from => :running, :to => :cleaning\n    end\n\n    event :sleep do\n      transitions :from => [:running, :cleaning], :to => :sleeping\n    end\n  end\n\nend\n```\n\nThis provides you with a couple of public methods for instances of the class `Job`:\n\n```ruby\njob = Job.new\njob.sleeping? # => true\njob.may_run?  # => true\njob.run\njob.running?  # => true\njob.sleeping? # => false\njob.may_run?  # => false\njob.run       # => raises AASM::InvalidTransition\n```\n\nIf you don't like exceptions and prefer a simple `true` or `false` as response, tell\nAASM not to be *whiny*:\n\n```ruby\nclass Job\n  ...\n  aasm :whiny_transitions => false do\n    ...\n  end\nend\n\njob.running?  # => true\njob.may_run?  # => false\njob.run       # => false\n```\n\n### Callbacks\n\nYou can define a number of callbacks for your transitions. These methods will be\ncalled, when certain criteria are met, like entering a particular state:\n\n```ruby\nclass Job\n  include AASM\n\n  aasm do\n    state :sleeping, :initial => true, :before_enter => :do_something\n    state :running\n\n    event :run, :after => Proc.new { |user| notify_somebody(user) } do\n      transitions :from => :sleeping, :to => :running, :on_transition => Proc.new {|obj, *args| obj.set_process(*args) }\n    end\n\n    event :sleep do\n      after do\n        ...\n      end\n      error do |e|\n        ...\n      end\n      transitions :from => :running, :to => :sleeping\n    end\n  end\n\n  def set_process(name)\n    ...\n  end\n\n  def do_something\n    ...\n  end\n\n  def notify_somebody(user)\n    ...\n  end\n\nend\n```\n\nIn this case `do_something` is called before actually entering the state `sleeping`,\nwhile `notify_somebody` is called after the transition `run` (from `sleeping` to `running`)\nis finished.\n\nHere you can see a list of all possible callbacks, together with their order of calling:\n\n```ruby\n  event:before\n    previous_state:before_exit\n      new_state:before_enter\n        ...update state...\n      previous_state:after_exit\n    new_state:after_enter\n  event:after\n```\n\nAlso, you can pass parameters to events:\n\n```ruby\n  job = Job.new\n  job.run(:running, :defragmentation)\n```\n\nIn this case the `set_process` would be called with `:defagmentation` argument.\n\nIn case of an error during the event processing the error is rescued and passed to `:error`\ncallback, which can handle it or re-raise it for further propagation.\n\n### Guards\n\nLet's assume you want to allow particular transitions only if a defined condition is\ngiven. For this you can set up a guard per transition, which will run before actually\nrunning the transition. If the guard returns `false` the transition will be\ndenied (raising `AASM::InvalidTransition` or returning `false` itself):\n\n```ruby\nclass Job\n  include AASM\n\n  aasm do\n    state :sleeping, :initial => true\n    state :running\n    state :cleaning\n\n    event :run do\n      transitions :from => :sleeping, :to => :running\n    end\n\n    event :clean do\n      transitions :from => :running, :to => :cleaning\n    end\n\n    event :sleep do\n      transitions :from => :running, :to => :sleeping, :guard => :cleaning_needed?\n    end\n  end\n\n  def cleaning_needed?\n    false\n  end\n\nend\n\njob = Job.new\njob.run\njob.may_sleep?  # => false\njob.sleep       # => raises AASM::InvalidTransition\n```\n\n\n### ActiveRecord\n\nAASM comes with support for ActiveRecord and allows automatical persisting of the object's\nstate in the database.\n\n```ruby\nclass Job < ActiveRecord::Base\n  include AASM\n\n  aasm do # default column: aasm_state\n    state :sleeping, :initial => true\n    state :running\n\n    event :run do\n      transitions :from => :sleeping, :to => :running\n    end\n\n    event :sleep do\n      transitions :from => :running, :to => :sleeping\n    end\n  end\n\nend\n```\n\nYou can tell AASM to auto-save the object or leave it unsaved\n\n```ruby\njob = Job.new\njob.run   # not saved\njob.run!  # saved\n```\n\nSaving includes running all validations on the `Job` class. If you want make sure\nthe state gets saved without running validations (and thereby maybe persisting an\ninvalid object state), simply tell AASM to skip the validations:\n\n```ruby\nclass Job < ActiveRecord::Base\n  include AASM\n\n  aasm :skip_validation_on_save => true do\n    state :sleeping, :initial => true\n    state :running\n\n    event :run do\n      transitions :from => :sleeping, :to => :running\n    end\n\n    event :sleep do\n      transitions :from => :running, :to => :sleeping\n    end\n  end\n\nend\n```\n\n### Automatic Scopes\n\nAASM will automatically create scope methods for each state in the model.\n\n```ruby\nclass Job < ActiveRecord::Base\n  include AASM\n\n  aasm do\n    state :sleeping, :initial => true\n    state :running\n    state :cleaning\n  end\n\n  def sleeping\n    \"This method name is in already use\"\n  end\nend\n```\n\n```ruby\nclass JobsController < ApplicationController\n  def index\n    @running_jobs = jobs.running\n    @recent_cleaning_jobs = jobs.cleaning.where('created_at >=  ?', 3.days.ago)\n\n    # @sleeping_jobs = jobs.sleeping   #=> \"This method name is in already use\"\n  end\nend\n```\n\n### Transaction support\n\nSince version *3.0.13* AASM supports ActiveRecord transactions. So whenever a transition\ncallback or the state update fails, all changes to any database record are rolled back.\n\n### Column name & migration\n\nAs a default AASM uses the column `aasm_state` to store the states. You can override\nthis by defining your favorite column name, using `:column` like this:\n\n```ruby\nclass Job < ActiveRecord::Base\n  include AASM\n\n  aasm :column => 'my_state' do\n    ...\n  end\n\nend\n```\n\nWhatever column name is used, make sure to add a migration to provide this column\n(of type `string`):\n\n```ruby\nclass AddJobState < ActiveRecord::Migration\n  def self.up\n    add_column :jobs, :aasm_state, :string\n  end\n\n  def self.down\n    remove_column :jobs, :aasm_state\n  end\nend\n```\n\n### <a id=\"inspection\">Inspection\n\nAASM supports a couple of methods to find out which states or events are provided or permissible.\n\nGiven the `Job` class from above:\n\n```ruby\njob = Job.new\n\njob.aasm.states\n=> [:sleeping, :running, :cleaning]\n\njob.aasm.states(:permissible => true)\n=> [:running]\njob.run\njob.aasm.states(:permissible => true)\n=> [:cleaning, :sleeping]\n\njob.aasm.events\n=> [:run, :clean, :sleep]\n```\n\n\n\n## <a id=\"installation\">Installation ##\n\n### Manually from RubyGems.org ###\n\n```sh\n% gem install aasm\n```\n\n### Or if you are using Bundler ###\n\n```ruby\n# Gemfile\ngem 'aasm'\n```\n\n### Building your own gems ###\n\n```sh\n% rake build\n% sudo gem install pkg/aasm-x.y.z.gem\n```\n\n## Latest changes ##\n\nLook at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details.\n\n## Questions? ##\n\nFeel free to\n\n* [create an issue on GitHub](https://github.com/aasm/aasm/issues)\n* [ask a question on StackOverflow](http://stackoverflow.com) (tag with `aasm`)\n* send us a tweet [@aasm](http://twitter.com/aasm)\n\n## Authors ##\n\n* [Scott Barron](https://github.com/rubyist)\n* [Travis Tilley](https://github.com/ttilley)\n* [Thorsten Böttger](http://github.com/alto)\n\n\n## Warranty ##\n\nThis software is provided \"as is\" and without any express or\nimplied warranties, including, without limitation, the implied\nwarranties of merchantibility and fitness for a particular\npurpose.\n\n## License ##\n\nCopyright (c) 2006-2012 Scott Barron\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Rakefile",
    "content": "require 'bundler/gem_tasks'\n\nrequire 'rspec/core'\nrequire 'rspec/core/rake_task'\nRSpec::Core::RakeTask.new(:spec) do |spec|\n  spec.pattern = FileList['spec/**/*_spec.rb']\nend\n\nrequire 'rake/testtask'\nRake::TestTask.new(:test) do |test|\n  test.libs << 'lib' << 'test'\n  test.pattern = 'test/**/*_test.rb'\n  test.verbose = true\nend\n\nrequire 'rdoc/task'\nrequire 'aasm/version'\n\nRake::RDocTask.new do |rdoc|\n  rdoc.rdoc_dir = 'rdoc'\n  rdoc.title = \"aasm #{AASM::VERSION}\"\n  rdoc.rdoc_files.include('README*')\n  rdoc.rdoc_files.include('lib/**/*.rb')\nend\n\ntask :default => :spec\n"
  },
  {
    "path": "aasm.gemspec",
    "content": "# -*- encoding: utf-8 -*-\n$:.push File.expand_path(\"../lib\", __FILE__)\nrequire \"aasm/version\"\n\nGem::Specification.new do |s|\n  s.name        = \"aasm\"\n  s.version     = AASM::VERSION\n  s.authors     = [\"Scott Barron\", \"Scott Petersen\", \"Travis Tilley\", \"Thorsten Boettger\"]\n  s.email       = %q{scott@elitists.net, ttilley@gmail.com, aasm@mt7.de}\n  s.homepage    = %q{https://github.com/aasm/aasm}\n  s.summary     = %q{State machine mixin for Ruby objects}\n  s.description = %q{AASM is a continuation of the acts as state machine rails plugin, built for plain Ruby objects.}\n  s.date        = Time.now\n  s.licenses    = [\"MIT\"]\n\n  s.add_development_dependency 'activerecord', '3.2.12'\n  # s.add_development_dependency 'activerecord', '4.0.0.rc1'\n\n  s.add_development_dependency 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')\n  s.add_development_dependency 'rake'\n  s.add_development_dependency 'sdoc'\n  s.add_development_dependency 'rspec', '~> 2.0'\n  s.add_development_dependency 'rr'\n  s.add_development_dependency 'sqlite3'\n  s.add_development_dependency 'minitest'\n  # s.add_development_dependency 'debugger'\n  # s.add_development_dependency 'pry'\n  s.add_development_dependency 'ruby-debug-completion'\n  s.add_development_dependency 'coveralls'\n\n  s.files         = `git ls-files`.split(\"\\n\")\n  s.test_files    = `git ls-files -- {test,spec,features}/*`.split(\"\\n\")\n  s.executables   = `git ls-files -- bin/*`.split(\"\\n\").map{ |f| File.basename(f) }\n  s.require_paths = [\"lib\"]\nend\n"
  },
  {
    "path": "lib/aasm/aasm.rb",
    "content": "module AASM\n\n  def self.included(base) #:nodoc:\n    base.extend AASM::ClassMethods\n\n    # do not overwrite existing state machines, which could have been created by\n    # inheritance, see class method inherited\n    AASM::StateMachine[base] ||= AASM::StateMachine.new('')\n\n    AASM::Persistence.load_persistence(base)\n    super\n  end\n\n  module ClassMethods\n\n    # make sure inheritance (aka subclassing) works with AASM\n    def inherited(base)\n      AASM::StateMachine[base] = AASM::StateMachine[self].clone\n      super\n    end\n\n    # this is the entry point for all state and event definitions\n    def aasm(options={}, &block)\n      @aasm ||= AASM::Base.new(self, options)\n      @aasm.instance_eval(&block) if block # new DSL\n      @aasm\n    end\n\n    # TODO: maybe better: aasm.initial_state\n    def aasm_initial_state(set_state=nil)\n      if set_state\n        # deprecated way to set the value\n        AASM::StateMachine[self].initial_state = set_state\n      else\n        AASM::StateMachine[self].initial_state\n      end\n    end\n\n    # is this better?: aasm.states.name.from_states\n    def aasm_from_states_for_state(state, options={})\n      if options[:transition]\n        aasm.events[options[:transition]].transitions_to_state(state).flatten.map(&:from).flatten\n      else\n        aasm.events.map {|k,v| v.transitions_to_state(state)}.flatten.map(&:from).flatten\n      end\n    end\n\n    # deprecated\n    def aasm_initial_state=(state)\n      AASM::StateMachine[self].initial_state = state\n    end\n\n    # deprecated\n    def aasm_state(name, options={})\n      aasm.state(name, options)\n    end\n\n    # deprecated\n    def aasm_event(name, options = {}, &block)\n      aasm.event(name, options, &block)\n    end\n\n    # deprecated\n    def aasm_states\n      aasm.states\n    end\n\n    # deprecated\n    def aasm_events\n      aasm.events\n    end\n\n    # deprecated\n    def aasm_states_for_select\n      aasm.states_for_select\n    end\n\n    # aasm.event(:event_name).human?\n    def aasm_human_event_name(event) # event_name?\n      AASM::Localizer.new.human_event_name(self, event)\n    end\n  end # ClassMethods\n\n  def aasm\n    @aasm ||= AASM::InstanceBase.new(self)\n  end\n\n  # may be overwritten by persistence mixins\n  def aasm_read_state\n    # all the following lines behave like @current_state ||= aasm.enter_initial_state\n    current = aasm.instance_variable_get(\"@current_state\")\n    return current if current\n    aasm.instance_variable_set(\"@current_state\", aasm.enter_initial_state)\n  end\n\n  # may be overwritten by persistence mixins\n  def aasm_write_state(new_state)\n    true\n  end\n\n  # may be overwritten by persistence mixins\n  def aasm_write_state_without_persistence(new_state)\n    true\n  end\n\n  # deprecated\n  def aasm_current_state\n    # warn \"#aasm_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.state instead!\"\n    aasm.current_state\n  end\n\n  # deprecated\n  def aasm_enter_initial_state\n    # warn \"#aasm_enter_initial_state is deprecated and will be removed in version 3.2.0; please use #aasm.enter_initial_state instead!\"\n    aasm.enter_initial_state\n  end\n\n  # deprecated\n  def aasm_events_for_current_state\n    # warn \"#aasm_events_for_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.events instead!\"\n    aasm.events(aasm.current_state)\n  end\n\n  # deprecated\n  def aasm_permissible_events_for_current_state\n    # warn \"#aasm_permissible_events_for_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.permissible_events instead!\"\n    aasm.permissible_events\n  end\n\n  # deprecated\n  def aasm_events_for_state(state_name)\n    # warn \"#aasm_events_for_state(state_name) is deprecated and will be removed in version 3.2.0; please use #aasm.events(state_name) instead!\"\n    aasm.events(state_name)\n  end\n\n  # deprecated\n  def aasm_human_state\n    # warn \"#aasm_human_state is deprecated and will be removed in version 3.2.0; please use #aasm.human_state instead!\"\n    aasm.human_state\n  end\n\nprivate\n\n  def aasm_fire_event(event_name, options, *args)\n    event = self.class.aasm_events[event_name]\n    begin\n      old_state = aasm.state_object_for_name(aasm.current_state)\n      old_state.fire_callbacks(:exit, self)\n\n      # new event before callback\n      event.fire_callbacks(:before, self)\n\n      if new_state_name = event.fire(self, *args)\n        fired(event, old_state, new_state_name, options)\n      else\n        failed(event_name, old_state)\n      end\n    rescue StandardError => e\n      event.fire_callbacks(:error, self, e) || raise(e)\n    end\n  end\n\n  def fired(event, old_state, new_state_name, options)\n    persist = options[:persist]\n\n    new_state = aasm.state_object_for_name(new_state_name)\n\n    # new before_ callbacks\n    old_state.fire_callbacks(:before_exit, self)\n    new_state.fire_callbacks(:before_enter, self)\n\n    new_state.fire_callbacks(:enter, self)\n\n    persist_successful = true\n    if persist\n      persist_successful = aasm.set_current_state_with_persistence(new_state_name)\n      event.fire_callbacks(:success, self) if persist_successful\n    else\n      aasm.current_state = new_state_name\n    end\n\n    if persist_successful\n      old_state.fire_callbacks(:after_exit, self)\n      new_state.fire_callbacks(:after_enter, self)\n      event.fire_callbacks(:after, self)\n\n      self.aasm_event_fired(event.name, old_state.name, aasm.current_state) if self.respond_to?(:aasm_event_fired)\n    else\n      self.aasm_event_failed(event.name, old_state.name) if self.respond_to?(:aasm_event_failed)\n    end\n\n    persist_successful\n  end\n\n  def failed(event_name, old_state)\n    if self.respond_to?(:aasm_event_failed)\n      self.aasm_event_failed(event_name, old_state.name)\n    end\n\n    if AASM::StateMachine[self.class].config.whiny_transitions\n      raise AASM::InvalidTransition, \"Event '#{event_name}' cannot transition from '#{aasm.current_state}'\"\n    else\n      false\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/aasm/base.rb",
    "content": "module AASM\n  class Base\n\n    def initialize(clazz, options={}, &block)\n      @clazz = clazz\n      @state_machine = AASM::StateMachine[@clazz]\n      @state_machine.config.column = options[:column].to_sym if options[:column]\n\n      if options.key?(:whiny_transitions)\n        @state_machine.config.whiny_transitions = options[:whiny_transitions]\n      elsif @state_machine.config.whiny_transitions.nil?\n        @state_machine.config.whiny_transitions = true # this is the default, so let's cry\n      end\n\n      if options.key?(:skip_validation_on_save)\n        @state_machine.config.skip_validation_on_save = options[:skip_validation_on_save]\n      elsif @state_machine.config.skip_validation_on_save.nil?\n        @state_machine.config.skip_validation_on_save = false # this is the default, so don't store any new state if the model is invalid\n      end\n    end\n\n    def initial_state\n      @state_machine.initial_state\n    end\n\n    # define a state\n    def state(name, options={})\n      # @clazz.aasm_state(name, options)\n      @state_machine.add_state(name, @clazz, options)\n      @state_machine.initial_state = name if options[:initial] || !@state_machine.initial_state\n\n      @clazz.send(:define_method, \"#{name.to_s}?\") do\n        aasm.current_state == name\n      end\n\n      unless @clazz.const_defined?(\"STATE_#{name.to_s.upcase}\")\n        @clazz.const_set(\"STATE_#{name.to_s.upcase}\", name)\n      end\n    end\n\n    # define an event\n    def event(name, options={}, &block)\n      # @clazz.aasm_event(name, options, &block)\n\n      unless @state_machine.events.has_key?(name)\n        @state_machine.events[name] = AASM::Event.new(name, options, &block)\n      end\n\n      # an addition over standard aasm so that, before firing an event, you can ask\n      # may_event? and get back a boolean that tells you whether the guard method\n      # on the transition will let this happen.\n      @clazz.send(:define_method, \"may_#{name.to_s}?\") do |*args|\n        aasm.may_fire_event?(name, *args)\n      end\n\n      @clazz.send(:define_method, \"#{name.to_s}!\") do |*args|\n        aasm_fire_event(name, {:persist => true}, *args)\n      end\n\n      @clazz.send(:define_method, \"#{name.to_s}\") do |*args|\n        aasm_fire_event(name, {:persist => false}, *args)\n      end\n    end\n\n    def states\n      @state_machine.states\n    end\n\n    def events\n      @state_machine.events\n    end\n\n    def states_for_select\n      states.map { |state| state.for_select }\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/aasm/deprecated/aasm.rb",
    "content": "module AASM\n\n  module ClassMethods\n    def human_event_name(*args)\n      warn \"AASM.human_event_name is deprecated and will be removed in version 3.1.0; please use AASM.aasm_human_event_name instead!\"\n      aasm_human_event_name(*args)\n    end\n  end\n\n  def human_state\n    warn \"AASM#human_state is deprecated and will be removed in version 3.1.0; please use AASM#aasm_human_state instead!\"\n    aasm_human_state\n  end\n\nend\n"
  },
  {
    "path": "lib/aasm/errors.rb",
    "content": "module AASM\n  class InvalidTransition < RuntimeError; end\n  class UndefinedState < RuntimeError; end\nend\n"
  },
  {
    "path": "lib/aasm/event.rb",
    "content": "module AASM\n  class Event\n\n    attr_reader :name, :options\n\n    def initialize(name, options = {}, &block)\n      @name = name\n      @transitions = []\n      update(options, &block)\n    end\n\n    # a neutered version of fire - it doesn't actually fire the event, it just\n    # executes the transition guards to determine if a transition is even\n    # an option given current conditions.\n    def may_fire?(obj, to_state=nil, *args)\n      _fire(obj, true, to_state, *args) # true indicates test firing\n    end\n\n    def fire(obj, to_state=nil, *args)\n      _fire(obj, false, to_state, *args) # false indicates this is not a test (fire!)\n    end\n\n    def transitions_from_state?(state)\n      transitions_from_state(state).any?\n    end\n\n    def transitions_from_state(state)\n      @transitions.select { |t| t.from == state }\n    end\n\n    def transitions_to_state?(state)\n      transitions_to_state(state).any?\n    end\n\n    def transitions_to_state(state)\n      @transitions.select { |t| t.to == state }\n    end\n\n    # deprecated\n    def all_transitions\n      # warn \"Event#all_transitions is deprecated and will be removed in version 3.2.0; please use Event#transitions instead!\"\n      transitions\n    end\n\n    def fire_callbacks(callback_name, record, *args)\n      invoke_callbacks(@options[callback_name], record, args)\n    end\n\n    def ==(event)\n      if event.is_a? Symbol\n        name == event\n      else\n        name == event.name\n      end\n    end\n\n  private\n\n    def update(options = {}, &block)\n      @options = options\n      if block then\n        instance_eval(&block)\n      end\n      self\n    end\n\n    # Execute if test == false, otherwise return true/false depending on whether it would fire\n    def _fire(obj, test, to_state=nil, *args)\n      result = test ? false : nil\n      if @transitions.map(&:from).any?\n        transitions = @transitions.select { |t| t.from == obj.aasm_current_state }\n        return result if transitions.size == 0\n      else\n        transitions = @transitions\n      end\n\n      transitions.each do |transition|\n        next if to_state and !Array(transition.to).include?(to_state)\n        if transition.perform(obj, *args)\n          if test\n            result = true\n          else\n            result = to_state || Array(transition.to).first\n            transition.execute(obj, *args)\n          end\n\n          break\n        end\n      end\n      result\n    end\n\n    def invoke_callbacks(code, record, args)\n      case code\n        when Symbol, String\n          record.send(code, *args)\n          true\n        when Proc\n          record.instance_exec(*args, &code)\n          true\n        when Array\n          code.each {|a| invoke_callbacks(a, record, args)}\n          true\n        else\n          false\n      end\n    end\n\n    ## DSL interface\n    def transitions(trans_opts=nil)\n      if trans_opts # define new transitions\n        # Create a separate transition for each from state to the given state\n        Array(trans_opts[:from]).each do |s|\n          @transitions << AASM::Transition.new(trans_opts.merge({:from => s.to_sym}))\n        end\n        # Create a transition if to is specified without from (transitions from ANY state)\n        @transitions << AASM::Transition.new(trans_opts) if @transitions.empty? && trans_opts[:to]\n      end\n      @transitions\n    end\n\n    [:after, :before, :error, :success].each do |callback_name|\n      define_method callback_name do |*args, &block|\n        options[callback_name] = Array(options[callback_name])\n        options[callback_name] << block if block\n        options[callback_name] += Array(args)\n      end\n    end\n  end\nend # AASM\n"
  },
  {
    "path": "lib/aasm/instance_base.rb",
    "content": "module AASM\n  class InstanceBase\n\n    def initialize(instance)\n      @instance = instance\n    end\n\n    def current_state\n      @instance.aasm_read_state\n    end\n\n    def current_state=(state)\n      @instance.aasm_write_state_without_persistence(state)\n      @current_state = state\n    end\n\n    def enter_initial_state\n      state_name = determine_state_name(@instance.class.aasm_initial_state)\n      state_object = state_object_for_name(state_name)\n\n      state_object.fire_callbacks(:before_enter, @instance)\n      state_object.fire_callbacks(:enter, @instance)\n      self.current_state = state_name\n      state_object.fire_callbacks(:after_enter, @instance)\n\n      state_name\n    end\n\n    def human_state\n      AASM::Localizer.new.human_state_name(@instance.class, current_state)\n    end\n\n    def states(options={})\n      if options[:permissible]\n        # ugliness level 1000\n        transitions = @instance.class.aasm.events.values.map {|e| e.transitions_from_state(current_state) }\n        tos = transitions.map {|t| t[0] ? t[0].to : nil}.flatten.compact.map(&:to_sym).uniq\n        @instance.class.aasm.states.select {|s| tos.include?(s.name.to_sym)}\n      else\n        @instance.class.aasm.states\n      end\n    end\n\n    # QUESTION: shouldn't events and permissible_events be the same thing?\n    # QUESTION: shouldn't events return objects instead of strings?\n    def events(state=current_state)\n      events = @instance.class.aasm.events.values.select {|e| e.transitions_from_state?(state) }\n      events.map {|e| e.name}\n    end\n\n    # filters the results of events_for_current_state so that only those that\n    # are really currently possible (given transition guards) are shown.\n    # QUESTION: what about events.permissible ?\n    def permissible_events\n      events.select{ |e| @instance.send((\"may_\" + e.to_s + \"?\").to_sym) }\n    end\n\n    def state_object_for_name(name)\n      obj = @instance.class.aasm.states.find {|s| s == name}\n      raise AASM::UndefinedState, \"State :#{name} doesn't exist\" if obj.nil?\n      obj\n    end\n\n    def determine_state_name(state)\n      case state\n        when Symbol, String\n          state\n        when Proc\n          state.call(@instance)\n        else\n          raise NotImplementedError, \"Unrecognized state-type given.  Expected Symbol, String, or Proc.\"\n      end\n    end\n\n    def may_fire_event?(name, *args)\n      event = @instance.class.aasm.events[name]\n      event.may_fire?(@instance, *args)\n    end\n\n    def set_current_state_with_persistence(state)\n      save_success = @instance.aasm_write_state(state)\n      self.current_state = state if save_success\n      save_success\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/aasm/localizer.rb",
    "content": "module AASM\n  class Localizer\n    def human_event_name(klass, event)\n      checklist = ancestors_list(klass).inject([]) do |list, ancestor|\n        list << :\"#{i18n_scope(klass)}.events.#{i18n_klass(ancestor)}.#{event}\"\n        list\n      end\n      translate_queue(checklist) || I18n.translate(checklist.shift, :default => event.to_s.humanize)\n    end\n\n    def human_state_name(klass, state)\n      checklist = ancestors_list(klass).inject([]) do |list, ancestor|\n        list << item_for(klass, state, ancestor)\n        list << item_for(klass, state, ancestor, :old_style => true)\n        list\n      end\n      translate_queue(checklist) || I18n.translate(checklist.shift, :default => state.to_s.humanize)\n    end\n\n  private\n\n    def item_for(klass, state, ancestor, options={})\n      separator = options[:old_style] ? '.' : '/'\n      :\"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm_column}#{separator}#{state}\"\n    end\n\n    def translate_queue(checklist)\n      (0...(checklist.size-1)).each do |i|\n        begin\n          return I18n.translate(checklist.shift, :raise => true)\n        rescue I18n::MissingTranslationData\n          # that's okay\n        end\n      end\n      nil\n    end\n\n    # added for rails 2.x compatibility\n    def i18n_scope(klass)\n      klass.respond_to?(:i18n_scope) ? klass.i18n_scope : :activerecord\n    end\n\n    # added for rails < 3.0.3 compatibility\n    def i18n_klass(klass)\n      klass.model_name.respond_to?(:i18n_key) ? klass.model_name.i18n_key : klass.name.underscore\n    end\n\n    def ancestors_list(klass)\n      klass.ancestors.select do |ancestor|\n        ancestor.respond_to?(:model_name) unless ancestor == ActiveRecord::Base\n      end\n    end\n  end\nend # AASM\n"
  },
  {
    "path": "lib/aasm/persistence/active_record_persistence.rb",
    "content": "module AASM\n  module Persistence\n    module ActiveRecordPersistence\n      # This method:\n      #\n      # * extends the model with ClassMethods\n      # * includes InstanceMethods\n      #\n      # Adds\n      #\n      #   before_validation :aasm_ensure_initial_state, :on => :create\n      #\n      # As a result, it doesn't matter when you define your methods - the following 2 are equivalent\n      #\n      #   class Foo < ActiveRecord::Base\n      #     def aasm_write_state(state)\n      #       \"bar\"\n      #     end\n      #     include AASM\n      #   end\n      #\n      #   class Foo < ActiveRecord::Base\n      #     include AASM\n      #     def aasm_write_state(state)\n      #       \"bar\"\n      #     end\n      #   end\n      #\n      def self.included(base)\n        base.send(:include, AASM::Persistence::Base)\n        base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods\n        base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)\n\n        if ActiveRecord::VERSION::MAJOR >= 3\n          base.before_validation(:aasm_ensure_initial_state, :on => :create)\n        else\n          base.before_validation_on_create(:aasm_ensure_initial_state)\n        end\n      end\n\n      module ClassMethods\n\n        def find_in_state(number, state, *args)\n          with_state_scope state do\n            find(number, *args)\n          end\n        end\n\n        def count_in_state(state, *args)\n          with_state_scope state do\n            count(*args)\n          end\n        end\n\n        def calculate_in_state(state, *args)\n          with_state_scope state do\n            calculate(*args)\n          end\n        end\n\n        protected\n        def with_state_scope(state)\n          with_scope :find => {:conditions => [\"#{table_name}.#{aasm_column} = ?\", state.to_s]} do\n            yield if block_given?\n          end\n        end\n      end\n\n      module InstanceMethods\n\n        # Writes <tt>state</tt> to the state column and persists it to the database\n        #\n        #   foo = Foo.find(1)\n        #   foo.aasm_current_state # => :opened\n        #   foo.close!\n        #   foo.aasm_current_state # => :closed\n        #   Foo.find(1).aasm_current_state # => :closed\n        #\n        # NOTE: intended to be called from an event\n        def aasm_write_state(state)\n          old_value = read_attribute(self.class.aasm_column)\n          write_attribute(self.class.aasm_column, state.to_s)\n\n          success = if AASM::StateMachine[self.class].config.skip_validation_on_save\n            self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm_column => state.to_s) == 1\n          else\n            self.save\n          end\n          unless success\n            write_attribute(self.class.aasm_column, old_value)\n            return false\n          end\n\n          true\n        end\n\n        # Writes <tt>state</tt> to the state column, but does not persist it to the database\n        #\n        #   foo = Foo.find(1)\n        #   foo.aasm_current_state # => :opened\n        #   foo.close\n        #   foo.aasm_current_state # => :closed\n        #   Foo.find(1).aasm_current_state # => :opened\n        #   foo.save\n        #   foo.aasm_current_state # => :closed\n        #   Foo.find(1).aasm_current_state # => :closed\n        #\n        # NOTE: intended to be called from an event\n        def aasm_write_state_without_persistence(state)\n          write_attribute(self.class.aasm_column, state.to_s)\n        end\n\n      private\n\n        # Ensures that if the aasm_state column is nil and the record is new\n        # that the initial state gets populated before validation on create\n        #\n        #   foo = Foo.new\n        #   foo.aasm_state # => nil\n        #   foo.valid?\n        #   foo.aasm_state # => \"open\" (where :open is the initial state)\n        #\n        #\n        #   foo = Foo.find(:first)\n        #   foo.aasm_state # => 1\n        #   foo.aasm_state = nil\n        #   foo.valid?\n        #   foo.aasm_state # => nil\n        #\n        def aasm_ensure_initial_state\n          aasm.enter_initial_state if send(self.class.aasm_column).blank?\n        end\n\n        def aasm_fire_event(name, options, *args)\n          transaction do\n            super\n          end\n        end\n      end # InstanceMethods\n\n    end\n  end\nend\n"
  },
  {
    "path": "lib/aasm/persistence/base.rb",
    "content": "module AASM\n  module Persistence\n    module Base\n\n      def self.included(base) #:nodoc:\n        base.extend ClassMethods\n      end\n\n      # Returns the value of the aasm_column - called from <tt>aasm.current_state</tt>\n      #\n      # If it's a new record, and the aasm state column is blank it returns the initial state\n      # (example provided here for ActiveRecord, but it's true for Mongoid as well):\n      #\n      #   class Foo < ActiveRecord::Base\n      #     include AASM\n      #     aasm :column => :status do\n      #       state :opened\n      #       state :closed\n      #     end\n      #   end\n      #\n      #   foo = Foo.new\n      #   foo.current_state # => :opened\n      #   foo.close\n      #   foo.current_state # => :closed\n      #\n      #   foo = Foo.find(1)\n      #   foo.current_state # => :opened\n      #   foo.aasm_state = nil\n      #   foo.current_state # => nil\n      #\n      # NOTE: intended to be called from an event\n      #\n      # This allows for nil aasm states - be sure to add validation to your model\n      def aasm_read_state\n        state = send(self.class.aasm_column)\n        if new_record?\n          state.blank? ? aasm.determine_state_name(self.class.aasm_initial_state) : state.to_sym\n        else\n          state.nil? ? nil : state.to_sym\n        end\n      end\n\n      module ClassMethods\n        # Maps to the aasm_column in the database.  Defaults to \"aasm_state\".  You can write\n        # (example provided here for ActiveRecord, but it's true for Mongoid as well):\n        #\n        #   create_table :foos do |t|\n        #     t.string :name\n        #     t.string :aasm_state\n        #   end\n        #\n        #   class Foo < ActiveRecord::Base\n        #     include AASM\n        #   end\n        #\n        # OR:\n        #\n        #   create_table :foos do |t|\n        #     t.string :name\n        #     t.string :status\n        #   end\n        #\n        #   class Foo < ActiveRecord::Base\n        #     include AASM\n        #     aasm_column :status\n        #   end\n        #\n        # This method is both a getter and a setter\n        def aasm_column(column_name=nil)\n          if column_name\n            AASM::StateMachine[self].config.column = column_name.to_sym\n            # @aasm_column = column_name.to_sym\n          else\n            AASM::StateMachine[self].config.column ||= :aasm_state\n            # @aasm_column ||= :aasm_state\n          end\n          # @aasm_column\n          AASM::StateMachine[self].config.column\n        end\n      end # ClassMethods\n\n    end # Base\n  end # Persistence\n\n  class Base\n    # make sure to create a (named) scope for each state\n    def state_with_scope(name, *args)\n      state_without_scope(name, *args)\n      unless @clazz.respond_to?(name)\n        if @clazz.ancestors.map {|klass| klass.to_s}.include?(\"ActiveRecord::Base\")\n\n          conditions = {\"#{@clazz.table_name}.#{@clazz.aasm_column}\" => name.to_s}\n          if ActiveRecord::VERSION::MAJOR >= 4\n            @clazz.class_eval do\n              scope name, lambda { where(conditions) }\n            end\n          elsif ActiveRecord::VERSION::MAJOR >= 3\n            @clazz.class_eval do\n              scope name, where(conditions)\n            end\n          else\n            @clazz.class_eval do\n              named_scope name, :conditions => conditions\n            end\n          end\n        elsif @clazz.ancestors.map {|klass| klass.to_s}.include?(\"Mongoid::Document\")\n          scope_options = lambda { @clazz.send(:where, {@clazz.aasm_column.to_sym => name.to_s}) }\n          @clazz.send(:scope, name, scope_options)\n        end\n      end\n    end\n    alias_method :state_without_scope, :state\n    alias_method :state, :state_with_scope\n  end # Base\n\nend # AASM\n"
  },
  {
    "path": "lib/aasm/persistence/mongoid_persistence.rb",
    "content": "module AASM\n  module Persistence\n    module MongoidPersistence\n      # This method:\n      #\n      # * extends the model with ClassMethods\n      # * includes InstanceMethods\n      #\n      # Adds\n      #\n      #   before_validation :aasm_ensure_initial_state\n      #\n      # As a result, it doesn't matter when you define your methods - the following 2 are equivalent\n      #\n      #   class Foo\n      #     include Mongoid::Document\n      #     def aasm_write_state(state)\n      #       \"bar\"\n      #     end\n      #     include AASM\n      #   end\n      #\n      #   class Foo\n      #     include Mongoid::Document\n      #     include AASM\n      #     def aasm_write_state(state)\n      #       \"bar\"\n      #     end\n      #   end\n      #\n      def self.included(base)\n        base.send(:include, AASM::Persistence::Base)\n        base.extend AASM::Persistence::MongoidPersistence::ClassMethods\n        base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)\n\n        # Mongoid's Validatable gem dependency goes not have a before_validation_on_xxx hook yet.\n        # base.before_validation_on_create :aasm_ensure_initial_state\n        base.before_validation :aasm_ensure_initial_state\n      end\n\n      module ClassMethods\n\n        def find_in_state(number, state, *args)\n          with_state_scope state do\n            find(number, *args)\n          end\n        end\n\n        def count_in_state(state, *args)\n          with_state_scope state do\n            count(*args)\n          end\n        end\n\n        def with_state_scope(state)\n          with_scope where(aasm_column.to_sym => state.to_s) do\n            yield if block_given?\n          end\n        end\n\n      end\n\n      module InstanceMethods\n\n        # Writes <tt>state</tt> to the state column and persists it to the database\n        # using update_attribute (which bypasses validation)\n        #\n        #   foo = Foo.find(1)\n        #   foo.aasm_current_state # => :opened\n        #   foo.close!\n        #   foo.aasm_current_state # => :closed\n        #   Foo.find(1).aasm_current_state # => :closed\n        #\n        # NOTE: intended to be called from an event\n        def aasm_write_state(state)\n          old_value = read_attribute(self.class.aasm_column)\n          write_attribute(self.class.aasm_column, state.to_s)\n\n          unless self.save(:validate => false)\n            write_attribute(self.class.aasm_column, old_value)\n            return false\n          end\n\n          true\n        end\n\n        # Writes <tt>state</tt> to the state column, but does not persist it to the database\n        #\n        #   foo = Foo.find(1)\n        #   foo.aasm_current_state # => :opened\n        #   foo.close\n        #   foo.aasm_current_state # => :closed\n        #   Foo.find(1).aasm_current_state # => :opened\n        #   foo.save\n        #   foo.aasm_current_state # => :closed\n        #   Foo.find(1).aasm_current_state # => :closed\n        #\n        # NOTE: intended to be called from an event\n        def aasm_write_state_without_persistence(state)\n          write_attribute(self.class.aasm_column, state.to_s)\n        end\n\n      private\n\n        # Ensures that if the aasm_state column is nil and the record is new\n        # that the initial state gets populated before validation on create\n        #\n        #   foo = Foo.new\n        #   foo.aasm_state # => nil\n        #   foo.valid?\n        #   foo.aasm_state # => \"open\" (where :open is the initial state)\n        #\n        #\n        #   foo = Foo.find(:first)\n        #   foo.aasm_state # => 1\n        #   foo.aasm_state = nil\n        #   foo.valid?\n        #   foo.aasm_state # => nil\n        #\n        def aasm_ensure_initial_state\n          send(\"#{self.class.aasm_column}=\", aasm.enter_initial_state.to_s) if send(self.class.aasm_column).blank?\n        end\n      end # InstanceMethods\n\n      module NamedScopeMethods\n        def aasm_state_with_named_scope name, options = {}\n          aasm_state_without_named_scope name, options\n          self.named_scope name, :conditions => { \"#{table_name}.#{self.aasm_column}\" => name.to_s} unless self.respond_to?(name)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/aasm/persistence.rb",
    "content": "module AASM\n  module Persistence\n    class << self\n\n      def load_persistence(base)\n        # Use a fancier auto-loading thingy, perhaps.  When there are more persistence engines.\n        hierarchy = base.ancestors.map {|klass| klass.to_s}\n\n        if hierarchy.include?(\"ActiveRecord::Base\")\n          require_files_for(:active_record)\n          base.send(:include, AASM::Persistence::ActiveRecordPersistence)\n        elsif hierarchy.include?(\"Mongoid::Document\")\n          require_files_for(:mongoid)\n          base.send(:include, AASM::Persistence::MongoidPersistence)\n        end\n      end\n\n    private\n\n      def require_files_for(persistence)\n        ['base', \"#{persistence}_persistence\"].each do |file_name|\n          require File.join(File.dirname(__FILE__), 'persistence', file_name)\n        end\n      end\n\n    end # class << self\n  end\nend # AASM\n"
  },
  {
    "path": "lib/aasm/state.rb",
    "content": "module AASM\n  class State\n    attr_reader :name, :options\n\n    def initialize(name, clazz, options={})\n      @name = name\n      @clazz = clazz\n      update(options)\n    end\n\n    def ==(state)\n      if state.is_a? Symbol\n        name == state\n      else\n        name == state.name\n      end\n    end\n\n    def <=>(state)\n      if state.is_a? Symbol\n        name <=> state\n      else\n        name <=> state.name\n      end\n    end\n\n    def to_s\n      name.to_s\n    end\n\n    def fire_callbacks(action, record)\n      action = @options[action]\n      catch :halt_aasm_chain do\n        action.is_a?(Array) ?\n                action.each {|a| _fire_callbacks(a, record)} :\n                _fire_callbacks(action, record)\n      end\n    end\n\n    def display_name\n      @display_name ||= begin\n        if Module.const_defined?(:I18n)\n          localized_name\n        else\n          name.to_s.gsub(/_/, ' ').capitalize\n        end\n      end\n    end\n\n    def localized_name\n      AASM::Localizer.new.human_state_name(@clazz, self)\n    end\n\n    def for_select\n      [display_name, name.to_s]\n    end\n\n  private\n\n    def update(options = {})\n      if options.key?(:display) then\n        @display_name = options.delete(:display)\n      end\n      @options = options\n      self\n    end\n\n    def _fire_callbacks(action, record)\n      case action\n        when Symbol, String\n          record.send(action)\n        when Proc\n          action.call(record)\n      end\n    end\n\n  end\nend # AASM\n"
  },
  {
    "path": "lib/aasm/state_machine.rb",
    "content": "module AASM\n  class StateMachine\n\n    # the following two methods provide the storage of all state machines\n    def self.[](clazz)\n      (@machines ||= {})[clazz.to_s]\n    end\n\n    def self.[]=(clazz, machine)\n      (@machines ||= {})[clazz.to_s] = machine\n    end\n\n    attr_accessor :states, :events, :initial_state, :config\n    attr_reader :name\n\n    # QUESTION: what's the name for? [alto, 2012-11-28]\n    def initialize(name)\n      @name = name\n      @initial_state = nil\n      @states = []\n      @events = {}\n      @config = OpenStruct.new\n    end\n\n    # called internally by Ruby 1.9 after clone()\n    def initialize_copy(orig)\n      super\n      @states = @states.dup\n      @events = @events.dup\n    end\n\n    def add_state(name, clazz, options)\n      @states << AASM::State.new(name, clazz, options) unless @states.include?(name)\n    end\n\n  end # StateMachine\nend # AASM\n"
  },
  {
    "path": "lib/aasm/transition.rb",
    "content": "module AASM\n  class Transition\n    attr_reader :from, :to, :opts\n    alias_method :options, :opts\n\n    def initialize(opts)\n      @from, @to, @guard, @on_transition = opts[:from], opts[:to], opts[:guard], opts[:on_transition]\n      @opts = opts\n    end\n\n    # TODO: should be named allowed? or similar\n    def perform(obj, *args)\n      case @guard\n        when Symbol, String\n          obj.send(@guard, *args)\n        when Proc\n          @guard.call(obj, *args)\n        else\n          true\n      end\n    end\n\n    def execute(obj, *args)\n      @on_transition.is_a?(Array) ?\n              @on_transition.each {|ot| _execute(obj, ot, *args)} :\n              _execute(obj, @on_transition, *args)\n    end\n\n    def ==(obj)\n      @from == obj.from && @to == obj.to\n    end\n\n    def from?(value)\n      @from == value\n    end\n\n    private\n\n    def _execute(obj, on_transition, *args)\n      case on_transition\n      when Proc\n        on_transition.arity == 0 ? on_transition.call : on_transition.call(obj, *args)\n      when Symbol, String\n        obj.send(:method, on_transition.to_sym).arity == 0 ? obj.send(on_transition) : obj.send(on_transition, *args)\n      end\n    end\n\n  end\nend # AASM\n"
  },
  {
    "path": "lib/aasm/version.rb",
    "content": "module AASM\n  VERSION = \"3.0.19\"\nend\n"
  },
  {
    "path": "lib/aasm.rb",
    "content": "require 'ostruct'\n\n%w(\n    version\n    errors\n    base\n    instance_base\n    transition\n    event\n    state\n    localizer\n    state_machine\n    persistence\n    aasm\n  ).each { |file| require File.join(File.dirname(__FILE__), 'aasm', file) }\n\n# load the deprecated methods and modules\nDir[File.join(File.dirname(__FILE__), 'aasm', 'deprecated', '*.rb')].sort.each { |f| require File.expand_path(f) }\n"
  },
  {
    "path": "spec/database.yml",
    "content": "sqlite3:\n  adapter: sqlite3\n  database: spec/aasm.sqlite3.db\n"
  },
  {
    "path": "spec/en.yml",
    "content": "en:\n  activerecord:\n    events:\n      localizer_test_model:\n        close: \"Let's close it!\"\n\n    attributes:\n      localizer_test_model:\n        aasm_state/opened: \"It's open now!\"\n"
  },
  {
    "path": "spec/en_deprecated_style.yml",
    "content": "en:\n  activerecord:\n    events:\n      localizer_test_model:\n        close: \"Let's close it!\"\n\n    attributes:\n      localizer_test_model:\n        aasm_state:\n          opened: \"It's open now!\"\n"
  },
  {
    "path": "spec/models/active_record/api.rb",
    "content": "class DefaultState\n  attr_accessor :transient_store, :persisted_store\n  include AASM\n  aasm do\n    state :alpha, :initial => true\n    state :beta\n    state :gamma\n    event :release do\n      transitions :from => [:alpha, :beta, :gamma], :to => :beta\n    end\n  end\nend\n\nclass ProvidedState\n  attr_accessor :transient_store, :persisted_store\n  include AASM\n  aasm do\n    state :alpha, :initial => true\n    state :beta\n    state :gamma\n    event :release do\n      transitions :from => [:alpha, :beta, :gamma], :to => :beta\n    end\n  end\n\n  def aasm_read_state\n    :beta\n  end\n\n  def aasm_write_state(new_state)\n    @persisted_store = new_state\n  end\n\n  def aasm_write_state_without_persistence(new_state)\n    @transient_store = new_state\n  end\nend\n\nclass PersistedState < ActiveRecord::Base\n  attr_accessor :transient_store, :persisted_store\n  include AASM\n  aasm do\n    state :alpha, :initial => true\n    state :beta\n    state :gamma\n    event :release do\n      transitions :from => [:alpha, :beta, :gamma], :to => :beta\n    end\n  end\nend\n\nclass ProvidedAndPersistedState < ActiveRecord::Base\n  attr_accessor :transient_store, :persisted_store\n  include AASM\n  aasm do\n    state :alpha, :initial => true\n    state :beta\n    state :gamma\n    event :release do\n      transitions :from => [:alpha, :beta, :gamma], :to => :beta\n    end\n  end\n\n  def aasm_read_state\n    :gamma\n  end\n\n  def aasm_write_state(new_state)\n    @persisted_store = new_state\n  end\n\n  def aasm_write_state_without_persistence(new_state)\n    @transient_store = new_state\n  end\nend\n"
  },
  {
    "path": "spec/models/argument.rb",
    "content": "class Argument\n  include AASM\n  aasm do\n    state :invalid, :initial => true\n    state :valid\n\n    event :valid do\n      transitions :to => :valid, :from => [:invalid]\n    end\n  end\nend\n"
  },
  {
    "path": "spec/models/auth_machine.rb",
    "content": "class AuthMachine\n  include AASM\n\n  attr_accessor :activation_code, :activated_at, :deleted_at\n\n  aasm do\n    state :passive\n    state :pending, :initial => true, :enter => :make_activation_code\n    state :active,  :enter => :do_activate\n    state :suspended\n    state :deleted, :enter => :do_delete, :exit => :do_undelete\n    state :waiting\n\n    event :register do\n      transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| u.can_register? }\n    end\n\n    event :activate do\n      transitions :from => :pending, :to => :active\n    end\n\n    event :suspend do\n      transitions :from => [:passive, :pending, :active], :to => :suspended\n    end\n\n    event :delete do\n      transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted\n    end\n\n    # a dummy event that can never happen\n    event :unpassify do\n      transitions :from => :passive, :to => :active, :guard => Proc.new {|u| false }\n    end\n\n    event :unsuspend do\n      transitions :from => :suspended, :to => :active,  :guard => Proc.new {|u| u.has_activated? }\n      transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| u.has_activation_code? }\n      transitions :from => :suspended, :to => :passive\n    end\n\n    event :wait do\n      transitions :from => :suspended, :to => :waiting, :guard => :if_polite?\n    end\n  end\n\n  def initialize\n    # the AR backend uses a before_validate_on_create :aasm_ensure_initial_state\n    # lets do something similar here for testing purposes.\n    aasm.enter_initial_state\n  end\n\n  def make_activation_code\n    @activation_code = 'moo'\n  end\n\n  def do_activate\n    @activated_at = Time.now\n    @activation_code = nil\n  end\n\n  def do_delete\n    @deleted_at = Time.now\n  end\n\n  def do_undelete\n    @deleted_at = false\n  end\n\n  def can_register?\n    true\n  end\n\n  def has_activated?\n    !!@activated_at\n  end\n\n  def has_activation_code?\n    !!@activation_code\n  end\n\n  def if_polite?(phrase = nil)\n    phrase == :please\n  end\nend\n"
  },
  {
    "path": "spec/models/bar.rb",
    "content": "class Bar\n  include AASM\n\n  aasm do\n    state :read\n    state :ended\n\n    event :foo do\n      transitions :to => :ended, :from => [:read]\n    end\n  end\nend\n\nclass Baz < Bar\nend\n"
  },
  {
    "path": "spec/models/callback_new_dsl.rb",
    "content": "class CallbackNewDsl\n  include AASM\n\n  aasm do\n    state :open, :initial => true,\n      :before_enter => :before_enter_open,\n      :after_enter  => :after_enter_open,\n      :before_exit  => :before_exit_open,\n      :exit         => :exit_open,\n      :after_exit   => :after_exit_open\n\n    state :closed,\n      :before_enter => :before_enter_closed,\n      :enter        => :enter_closed,\n      :after_enter  => :after_enter_closed,\n      :before_exit  => :before_exit_closed,\n      :after_exit   => :after_exit_closed\n\n    event :close, :before => :before, :after => :after do\n      transitions :to => :closed, :from => [:open]\n    end\n\n    event :open, :before => :before, :after => :after do\n      transitions :to => :open, :from => :closed\n    end\n  end\n\n  def before_enter_open; end\n  def before_exit_open; end\n  def after_enter_open; end\n  def after_exit_open; end\n\n  def before_enter_closed; end\n  def before_exit_closed; end\n  def after_enter_closed; end\n  def after_exit_closed; end\n\n  def before; end\n  def after; end\n\n  def enter_closed; end\n  def exit_open; end\nend\n"
  },
  {
    "path": "spec/models/callback_old_dsl.rb",
    "content": "class CallbackOldDsl\n  include AASM\n\n  aasm_initial_state :open\n  aasm_state :open,\n    :before_enter => :before_enter_open,\n    :after_enter  => :after_enter_open,\n    :before_exit  => :before_exit_open,\n    :exit         => :exit_open,\n    :after_exit   => :after_exit_open\n  aasm_state :closed,\n    :before_enter => :before_enter_closed,\n    :enter        => :enter_closed,\n    :after_enter  => :after_enter_closed,\n    :before_exit  => :before_exit_closed,\n    :after_exit   => :after_exit_closed\n\n  aasm_event :close, :before => :before, :after => :after do\n    transitions :to => :closed, :from => [:open]\n  end\n\n  aasm_event :open, :before => :before, :after => :after do\n    transitions :to => :open, :from => :closed\n  end\n\n  def before_enter_open; end\n  def before_exit_open; end\n  def after_enter_open; end\n  def after_exit_open; end\n\n  def before_enter_closed; end\n  def before_exit_closed; end\n  def after_enter_closed; end\n  def after_exit_closed; end\n\n  def before; end\n  def after; end\n\n  def enter_closed; end\n  def exit_open; end\nend\n"
  },
  {
    "path": "spec/models/conversation.rb",
    "content": "class Conversation\n  include AASM\n\n  aasm do\n    state :needs_attention, :initial => true\n    state :read\n    state :closed\n    state :awaiting_response\n    state :junk\n\n    event :new_message do\n    end\n\n    event :view do\n      transitions :to => :read, :from => [:needs_attention]\n    end\n\n    event :reply do\n    end\n\n    event :close do\n      transitions :to => :closed, :from => [:read, :awaiting_response]\n    end\n\n    event :junk do\n      transitions :to => :junk, :from => [:read]\n    end\n\n    event :unjunk do\n    end\n  end\n\n  def initialize(persister)\n    @persister = persister\n  end\n\n\n  private\n  def aasm_read_state\n    @persister.read_state\n  end\n\n  def aasm_write_state(state)\n    @persister.write_state(state)\n  end\n\nend\n"
  },
  {
    "path": "spec/models/father.rb",
    "content": "require 'active_record'\n\nclass Father < ActiveRecord::Base\n  include AASM\n\n  aasm do\n    state :missing_details, :initial => true\n    state :pending_details_confirmation\n\n    event :add_details do\n      transitions :from => :missing_details, :to => :pending_details_confirmation\n    end\n  end\n\n  def update_state\n     if may_add_details?\n       add_details!\n     end\n  end\n\nend\n"
  },
  {
    "path": "spec/models/foo.rb",
    "content": "class Foo\n  include AASM\n  aasm do\n    state :open, :initial => true, :exit => :exit\n    state :closed, :enter => :enter\n\n    event :close, :success => :success_callback do\n      transitions :from => [:open], :to => [:closed]\n    end\n\n    event :null do\n      transitions :from => [:open], :to => :closed, :guard => :always_false\n    end\n  end\n\n  def always_false\n    false\n  end\n\n  def success_callback\n  end\n\n  def enter\n  end\n  def exit\n  end\nend\n\nclass FooTwo < Foo\n  include AASM\n  aasm do\n    state :foo\n  end\nend\n"
  },
  {
    "path": "spec/models/invalid_persistor.rb",
    "content": "require 'active_record'\n\nclass InvalidPersistor < ActiveRecord::Base\n  include AASM\n  aasm :column => :status, :skip_validation_on_save => true do\n    state :sleeping, :initial => true\n    state :running\n    event :run do\n      transitions :to => :running, :from => :sleeping\n    end\n    event :sleep do\n      transitions :to => :sleeping, :from => :running\n    end\n  end\n  validates_presence_of :name\nend\n"
  },
  {
    "path": "spec/models/mongoid/simple_mongoid.rb",
    "content": "class SimpleMongoid\n  include Mongoid::Document\n  include AASM\n\n  field :status, type: String\n\n  aasm_column :status\n  aasm_state :unknown_scope\n  aasm_state :new\nend\n"
  },
  {
    "path": "spec/models/mongoid/simple_new_dsl_mongoid.rb",
    "content": "class SimpleNewDslMongoid\n  include Mongoid::Document\n  include AASM\n\n  field :status, type: String\n\n  aasm :column => :status\n  aasm do\n    state :unknown_scope\n    state :new\n  end\nend\n"
  },
  {
    "path": "spec/models/not_auto_loaded/process.rb",
    "content": "module Models\n  class Process\n    include AASM\n\n    aasm_state :sleeping\n    aasm_state :running\n    aasm_state :suspended\n\n    aasm_event :start do\n      transitions :from => :sleeping, :to => :running\n    end\n\n    aasm_event :stop do\n      transitions :from => :running, :to => :suspended\n    end\n\n  end\nend\n\n"
  },
  {
    "path": "spec/models/parametrised_event.rb",
    "content": "class ParametrisedEvent\n  include AASM\n  aasm do\n    state :sleeping, :initial => true\n    state :showering\n    state :working\n    state :dating\n    state :prettying_up\n\n    event :wakeup do\n      transitions :from => :sleeping, :to => [:showering, :working]\n    end\n\n    event :dress do\n      transitions :from => :sleeping, :to => :working, :on_transition => :wear_clothes\n      transitions :from => :showering, :to => [:working, :dating], :on_transition => Proc.new { |obj, *args| obj.wear_clothes(*args) }\n      transitions :from => :showering, :to => :prettying_up, :on_transition => [:condition_hair, :fix_hair]\n    end\n  end\n\n  def wear_clothes(shirt_color, trouser_type)\n  end\n\n  def condition_hair\n  end\n\n  def fix_hair\n  end\nend\n"
  },
  {
    "path": "spec/models/persistence.rb",
    "content": "class Gate < ActiveRecord::Base\n  include AASM\n\n  # Fake this column for testing purposes\n  attr_accessor :aasm_state\n\n  aasm do\n    state :opened\n    state :closed\n\n    event :view do\n      transitions :to => :read, :from => [:needs_attention]\n    end\n  end\nend\n\nclass Reader < ActiveRecord::Base\n  include AASM\n\n  def aasm_read_state\n    \"fi\"\n  end\nend\n\nclass Writer < ActiveRecord::Base\n  def aasm_write_state(state)\n    \"fo\"\n  end\n  include AASM\nend\n\nclass Transient < ActiveRecord::Base\n  def aasm_write_state_without_persistence(state)\n    \"fum\"\n  end\n  include AASM\nend\n\nclass Simple < ActiveRecord::Base\n  include AASM\n  aasm_column :status\n  aasm_state :unknown_scope\n  aasm_state :new\nend\n\nclass SimpleNewDsl < ActiveRecord::Base\n  include AASM\n  aasm :column => :status\n  aasm do\n    state :unknown_scope\n    state :new\n  end\nend\n\nclass Derivate < Simple\nend\n\nclass DerivateNewDsl < SimpleNewDsl\nend\n\nclass Thief < ActiveRecord::Base\n  if ActiveRecord::VERSION::MAJOR >= 3\n    self.table_name = 'thieves'\n  else\n    set_table_name \"thieves\"\n  end\n  include AASM\n  aasm_initial_state  Proc.new { |thief| thief.skilled ? :rich : :jailed }\n  aasm_state          :rich\n  aasm_state          :jailed\n  attr_accessor :skilled, :aasm_state\nend\n"
  },
  {
    "path": "spec/models/process_with_new_dsl.rb",
    "content": "class ProcessWithNewDsl\n  include AASM\n\n  def self.state(*args)\n    raise \"wrong state method\"\n  end\n\n  attr_accessor :flagged\n\n  aasm do\n    state :sleeping, :initial => true\n    state :running, :after_enter => :flag\n    state :suspended\n\n    event :start do\n      transitions :from => :sleeping, :to => :running\n    end\n    event :stop do\n      transitions :from => :running, :to => :suspended\n    end\n  end\n\n  def flag\n    self.flagged = true\n  end\n\n  def self.event(*args)\n    raise \"wrong event method\"\n  end\n\nend\n"
  },
  {
    "path": "spec/models/silencer.rb",
    "content": "class Silencer\n  include AASM\n\n  aasm :whiny_transitions => false do\n    state :silent, :initial => true\n    state :crying\n    state :smiling\n\n    event :cry do\n      transitions :from => :silent, :to => :crying\n    end\n\n    event :smile do\n      transitions :from => :crying, :to => :smiling\n    end\n\n    event :smile_any do\n      transitions :to => :smiling\n    end\n  end\n\nend\n"
  },
  {
    "path": "spec/models/son.rb",
    "content": "class Son < Father\n  include AASM\nend\n"
  },
  {
    "path": "spec/models/sub_classing.rb",
    "content": "class SubClassing < Silencer\n  \nend"
  },
  {
    "path": "spec/models/this_name_better_not_be_in_use.rb",
    "content": "class ThisNameBetterNotBeInUse\n  include AASM\n\n  aasm do\n    state :initial\n    state :symbol\n    state :string\n    state :array\n    state :proc\n  end\nend\n"
  },
  {
    "path": "spec/models/transactor.rb",
    "content": "require 'active_record'\nclass Transactor < ActiveRecord::Base\n\n  belongs_to :worker\n\n  include AASM\n  aasm :column => :status do\n    state :sleeping, :initial => true\n    state :running, :before_enter => :start_worker, :after_enter => :fail\n\n    event :run do\n      transitions :to => :running, :from => :sleeping\n    end\n  end\n\nprivate\n\n  def start_worker\n    worker.update_attribute(:status, 'running')\n  end\n\n  def fail\n    raise StandardError.new('failed on purpose')\n  end\n\nend\n"
  },
  {
    "path": "spec/models/validator.rb",
    "content": "require 'active_record'\n\nclass Validator < ActiveRecord::Base\n  include AASM\n  aasm :column => :status do\n    state :sleeping, :initial => true\n    state :running\n    event :run do\n      transitions :to => :running, :from => :sleeping\n    end\n    event :sleep do\n      transitions :to => :sleeping, :from => :running\n    end\n  end\n  validates_presence_of :name\nend\n"
  },
  {
    "path": "spec/models/worker.rb",
    "content": "class Worker < ActiveRecord::Base\nend\n"
  },
  {
    "path": "spec/schema.rb",
    "content": "ActiveRecord::Schema.define(:version => 0) do\n\n  %w{gates readers writers transients simples simple_new_dsls thieves localizer_test_models persisted_states provided_and_persisted_states}.each do |table_name|\n    create_table table_name, :force => true do |t|\n      t.string \"aasm_state\"\n    end\n  end\n\n  create_table \"validators\", :force => true do |t|\n    t.string \"name\"\n    t.string \"status\"\n  end\n\n  create_table \"transactors\", :force => true do |t|\n    t.string \"name\"\n    t.string \"status\"\n    t.integer \"worker_id\"\n  end\n\n  create_table \"workers\", :force => true do |t|\n    t.string \"name\"\n    t.string \"status\"\n  end\n\n  create_table \"invalid_persistors\", :force => true do |t|\n    t.string \"name\"\n    t.string \"status\"\n  end\n\n  create_table \"fathers\", :force => true do |t|\n    t.string \"aasm_state\"\n    t.string \"type\"\n  end\n\nend\n"
  },
  {
    "path": "spec/spec_helper.rb",
    "content": "$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))\n$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))\nrequire 'aasm'\n\nrequire 'rspec'\nrequire 'rspec/autorun'\n\nrequire 'coveralls'\nCoveralls.wear!\n\n# require 'ruby-debug'; Debugger.settings[:autoeval] = true; debugger; rubys_debugger = 'annoying'\n# require 'ruby-debug/completion'\n# require 'pry'\n\ndef load_schema\n  config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))\n  ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + \"/debug.log\")\n  ActiveRecord::Base.establish_connection(config['sqlite3'])\n  load(File.dirname(__FILE__) + \"/schema.rb\")\nend\n\n# custom spec helpers\nDir[File.dirname(__FILE__) + \"/spec_helpers/**/*.rb\"].sort.each { |f| require File.expand_path(f) }\n\n# example model classes\nDir[File.dirname(__FILE__) + \"/models/*.rb\"].sort.each { |f| require File.expand_path(f) }\n"
  },
  {
    "path": "spec/unit/api_spec.rb",
    "content": "require 'spec_helper'\nrequire 'models/active_record/api.rb'\n\ndescribe \"reading the current state\" do\n  it \"uses the AASM default\" do\n    DefaultState.new.aasm.current_state.should eql :alpha\n  end\n\n  it \"uses the provided method\" do\n    ProvidedState.new.aasm.current_state.should eql :beta\n  end\n\n  it \"uses the persistence storage\" do\n    PersistedState.new.aasm.current_state.should eql :alpha\n  end\n\n  it \"uses the provided method even if persisted\" do\n    ProvidedAndPersistedState.new.aasm.current_state.should eql :gamma\n  end\nend\n\ndescribe \"writing and persisting the current state\" do\n  it \"uses the AASM default\" do\n    o = DefaultState.new\n    o.release!\n    o.persisted_store.should be_nil\n  end\n\n  it \"uses the provided method\" do\n    o = ProvidedState.new\n    o.release!\n    o.persisted_store.should eql :beta\n  end\n\n  it \"uses the persistence storage\" do\n    o = PersistedState.new\n    o.release!\n    o.persisted_store.should be_nil\n  end\n\n  it \"uses the provided method even if persisted\" do\n    o = ProvidedAndPersistedState.new\n    o.release!\n    o.persisted_store.should eql :beta\n  end\nend\n\ndescribe \"writing the current state without persisting it\" do\n  it \"uses the AASM default\" do\n    o = DefaultState.new\n    o.release\n    o.transient_store.should be_nil\n  end\n\n  it \"uses the provided method\" do\n    o = ProvidedState.new\n    o.release\n    o.transient_store.should eql :beta\n  end\n\n  it \"uses the persistence storage\" do\n    o = PersistedState.new\n    o.release\n    o.transient_store.should be_nil\n  end\n\n  it \"uses the provided method even if persisted\" do\n    o = ProvidedAndPersistedState.new\n    o.release\n    o.transient_store.should eql :beta\n  end\nend\n"
  },
  {
    "path": "spec/unit/callbacks_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe 'callbacks for the old DSL' do\n  let(:callback) {CallbackOldDsl.new}\n\n  it \"should get close callbacks\" do\n    callback.should_receive(:exit_open).once.ordered\n    callback.should_receive(:before).once.ordered\n    callback.should_receive(:before_exit_open).once.ordered                   # these should be before the state changes\n    callback.should_receive(:before_enter_closed).once.ordered\n    callback.should_receive(:enter_closed).once.ordered\n    callback.should_receive(:aasm_write_state).once.ordered.and_return(true)  # this is when the state changes\n    callback.should_receive(:after_exit_open).once.ordered                    # these should be after the state changes\n    callback.should_receive(:after_enter_closed).once.ordered\n    callback.should_receive(:after).once.ordered\n\n    callback.close!\n  end\nend\n\ndescribe 'callbacks for the new DSL' do\n  let(:callback) {CallbackNewDsl.new}\n\n  it \"be called in order\" do\n    callback.should_receive(:exit_open).once.ordered\n    callback.should_receive(:before).once.ordered\n    callback.should_receive(:before_exit_open).once.ordered                   # these should be before the state changes\n    callback.should_receive(:before_enter_closed).once.ordered\n    callback.should_receive(:enter_closed).once.ordered\n    callback.should_receive(:aasm_write_state).once.ordered.and_return(true)  # this is when the state changes\n    callback.should_receive(:after_exit_open).once.ordered                    # these should be after the state changes\n    callback.should_receive(:after_enter_closed).once.ordered\n    callback.should_receive(:after).once.ordered\n\n    callback.close!\n  end\nend\n\ndescribe 'event callbacks' do\n  describe \"with an error callback defined\" do\n    before do\n      class Foo\n        aasm_event :safe_close, :success => :success_callback, :error => :error_callback do\n          transitions :to => :closed, :from => [:open]\n        end\n      end\n\n      @foo = Foo.new\n    end\n\n    it \"should run error_callback if an exception is raised and error_callback defined\" do\n      def @foo.error_callback(e); end\n\n      @foo.stub!(:enter).and_raise(e=StandardError.new)\n      @foo.should_receive(:error_callback).with(e)\n\n      @foo.safe_close!\n    end\n\n    it \"should raise NoMethodError if exceptionis raised and error_callback is declared but not defined\" do\n      @foo.stub!(:enter).and_raise(StandardError)\n      lambda{@foo.safe_close!}.should raise_error(NoMethodError)\n    end\n\n    it \"should propagate an error if no error callback is declared\" do\n        @foo.stub!(:enter).and_raise(\"Cannot enter safe\")\n        lambda{@foo.close!}.should raise_error(StandardError, \"Cannot enter safe\")\n    end\n  end\n\n  describe \"with aasm_event_fired defined\" do\n    before do\n      @foo = Foo.new\n      def @foo.aasm_event_fired(event, from, to); end\n    end\n\n    it 'should call it for successful bang fire' do\n      @foo.should_receive(:aasm_event_fired).with(:close, :open, :closed)\n      @foo.close!\n    end\n\n    it 'should call it for successful non-bang fire' do\n      @foo.should_receive(:aasm_event_fired)\n      @foo.close\n    end\n\n    it 'should not call it for failing bang fire' do\n      @foo.aasm.stub!(:set_current_state_with_persistence).and_return(false)\n      @foo.should_not_receive(:aasm_event_fired)\n      @foo.close!\n    end\n  end\n\n  describe \"with aasm_event_failed defined\" do\n    before do\n      @foo = Foo.new\n      def @foo.aasm_event_failed(event, from); end\n    end\n\n    it 'should call it when transition failed for bang fire' do\n      @foo.should_receive(:aasm_event_failed).with(:null, :open)\n      lambda {@foo.null!}.should raise_error(AASM::InvalidTransition)\n    end\n\n    it 'should call it when transition failed for non-bang fire' do\n      @foo.should_receive(:aasm_event_failed).with(:null, :open)\n      lambda {@foo.null}.should raise_error(AASM::InvalidTransition)\n    end\n\n    it 'should not call it if persist fails for bang fire' do\n      @foo.aasm.stub!(:set_current_state_with_persistence).and_return(false)\n      @foo.should_receive(:aasm_event_failed)\n      @foo.close!\n    end\n  end\nend\n"
  },
  {
    "path": "spec/unit/complex_example_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe 'on initialization' do\n  let(:auth) {AuthMachine.new}\n\n  it 'should be in the pending state' do\n    auth.aasm_current_state.should == :pending\n  end\n\n  it 'should have an activation code' do\n    auth.has_activation_code?.should be_true\n    auth.activation_code.should_not be_nil\n  end\nend\n\ndescribe 'when being unsuspended' do\n  let(:auth) {AuthMachine.new}\n\n  it 'should be able to be unsuspended' do\n    auth.activate!\n    auth.suspend!\n    auth.may_unsuspend?.should be_true\n  end\n\n  it 'should not be able to be unsuspended into active' do\n    auth.suspend!\n    auth.may_unsuspend?(:active).should_not be_true\n  end\n\n  it 'should be able to be unsuspended into active if polite' do\n    auth.suspend!\n    auth.may_wait?(:waiting, :please).should be_true\n    auth.wait!(nil, :please)\n  end\n\n  it 'should not be able to be unsuspended into active if not polite' do\n    auth.suspend!\n    auth.may_wait?(:waiting).should_not be_true\n    auth.may_wait?(:waiting, :rude).should_not be_true\n    lambda {auth.wait!(nil, :rude)}.should raise_error(AASM::InvalidTransition)\n    lambda {auth.wait!}.should raise_error(AASM::InvalidTransition)\n  end\n\n  it 'should not be able to be unpassified' do\n    auth.activate!\n    auth.suspend!\n    auth.unsuspend!\n\n    auth.may_unpassify?.should_not be_true\n    lambda {auth.unpassify!}.should raise_error(AASM::InvalidTransition)\n  end\n\n  it 'should be active if previously activated' do\n    auth.activate!\n    auth.suspend!\n    auth.unsuspend!\n\n    auth.aasm_current_state.should == :active\n  end\n\n  it 'should be pending if not previously activated, but an activation code is present' do\n    auth.suspend!\n    auth.unsuspend!\n\n    auth.aasm_current_state.should == :pending\n  end\n\n  it 'should be passive if not previously activated and there is no activation code' do\n    auth.activation_code = nil\n    auth.suspend!\n    auth.unsuspend!\n\n    auth.aasm_current_state.should == :passive\n  end\nend\n"
  },
  {
    "path": "spec/unit/event_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe 'adding an event' do\n  let(:event) do\n    AASM::Event.new(:close_order, {:success => :success_callback}) do\n      before :before_callback\n      after :after_callback\n      transitions :to => :closed, :from => [:open, :received]\n    end\n  end\n\n  it 'should set the name' do\n    event.name.should == :close_order\n  end\n\n  it 'should set the success callback' do\n    event.options[:success].should == :success_callback\n  end\n\n  it 'should set the after callback' do\n    event.options[:after].should == [:after_callback]\n  end\n\n  it 'should set the before callback' do\n    event.options[:before].should == [:before_callback]\n  end\n\n  it 'should create transitions' do\n    transitions = event.all_transitions\n    transitions[0].from.should == :open\n    transitions[0].to.should == :closed\n    transitions[1].from.should == :received\n    transitions[1].to.should == :closed\n  end\nend\n\ndescribe 'transition inspection' do\n  let(:event) do\n    AASM::Event.new(:run) do\n      transitions :to => :running, :from => :sleeping\n    end\n  end\n\n  it 'should support inspecting transitions from other states' do\n    event.transitions_from_state(:sleeping).map(&:to).should == [:running]\n    event.transitions_from_state?(:sleeping).should be_true\n\n    event.transitions_from_state(:cleaning).map(&:to).should == []\n    event.transitions_from_state?(:cleaning).should be_false\n  end\n\n  it 'should support inspecting transitions to other states' do\n    event.transitions_to_state(:running).map(&:from).should == [:sleeping]\n    event.transitions_to_state?(:running).should be_true\n\n    event.transitions_to_state(:cleaning).map(&:to).should == []\n    event.transitions_to_state?(:cleaning).should be_false\n  end\nend\n\ndescribe 'firing an event' do\n  it 'should return nil if the transitions are empty' do\n    obj = mock('object')\n    obj.stub!(:aasm_current_state)\n\n    event = AASM::Event.new(:event)\n    event.fire(obj).should be_nil\n  end\n\n  it 'should return the state of the first matching transition it finds' do\n    event = AASM::Event.new(:event) do\n      transitions :to => :closed, :from => [:open, :received]\n    end\n\n    obj = mock('object')\n    obj.stub!(:aasm_current_state).and_return(:open)\n\n    event.fire(obj).should == :closed\n  end\n\n  it 'should call the guard with the params passed in' do\n    event = AASM::Event.new(:event) do\n      transitions :to => :closed, :from => [:open, :received], :guard => :guard_fn\n    end\n\n    obj = mock('object')\n    obj.stub!(:aasm_current_state).and_return(:open)\n    obj.should_receive(:guard_fn).with('arg1', 'arg2').and_return(true)\n\n    event.fire(obj, nil, 'arg1', 'arg2').should == :closed\n  end\n\nend\n\ndescribe 'should fire callbacks' do\n  describe 'success' do\n    it \"if it's a symbol\" do\n      ThisNameBetterNotBeInUse.instance_eval {\n        aasm_event :with_symbol, :success => :symbol_success_callback do\n          transitions :to => :symbol, :from => [:initial]\n        end\n      }\n\n      model = ThisNameBetterNotBeInUse.new\n      model.should_receive(:symbol_success_callback)\n      model.with_symbol!\n    end\n\n    it \"if it's a string\" do\n      ThisNameBetterNotBeInUse.instance_eval {\n        aasm_event :with_string, :success => 'string_success_callback' do\n          transitions :to => :string, :from => [:initial]\n        end\n      }\n\n      model = ThisNameBetterNotBeInUse.new\n      model.should_receive(:string_success_callback)\n      model.with_string!\n    end\n\n    it \"if passed an array of strings and/or symbols\" do\n      ThisNameBetterNotBeInUse.instance_eval {\n        aasm_event :with_array, :success => [:success_callback1, 'success_callback2'] do\n          transitions :to => :array, :from => [:initial]\n        end\n      }\n\n      model = ThisNameBetterNotBeInUse.new\n      model.should_receive(:success_callback1)\n      model.should_receive(:success_callback2)\n      model.with_array!\n    end\n\n    it \"if passed an array of strings and/or symbols and/or procs\" do\n      ThisNameBetterNotBeInUse.instance_eval {\n        aasm_event :with_array_including_procs, :success => [:success_callback1, 'success_callback2', lambda { proc_success_callback }] do\n          transitions :to => :array, :from => [:initial]\n        end\n      }\n\n      model = ThisNameBetterNotBeInUse.new\n      model.should_receive(:success_callback1)\n      model.should_receive(:success_callback2)\n      model.should_receive(:proc_success_callback)\n      model.with_array_including_procs!\n    end\n\n    it \"if it's a proc\" do\n      ThisNameBetterNotBeInUse.instance_eval {\n        aasm_event :with_proc, :success => lambda { proc_success_callback } do\n          transitions :to => :proc, :from => [:initial]\n        end\n      }\n\n      model = ThisNameBetterNotBeInUse.new\n      model.should_receive(:proc_success_callback)\n      model.with_proc!\n    end\n  end\n\n  describe 'after' do\n    it \"if they set different ways\" do\n      ThisNameBetterNotBeInUse.instance_eval do\n        aasm_event :with_afters, :after => :do_one_thing_after do\n          after do\n            do_another_thing_after_too\n          end\n          after do\n            do_third_thing_at_last\n          end\n          transitions :to => :proc, :from => [:initial]\n        end\n      end\n\n      model = ThisNameBetterNotBeInUse.new\n      model.should_receive(:do_one_thing_after).once.ordered\n      model.should_receive(:do_another_thing_after_too).once.ordered\n      model.should_receive(:do_third_thing_at_last).once.ordered\n      model.with_afters!\n    end\n  end\n\n  describe 'before' do\n    it \"if it's a proc\" do\n      ThisNameBetterNotBeInUse.instance_eval do\n        aasm_event :before_as_proc do\n          before do\n            do_something_before\n          end\n          transitions :to => :proc, :from => [:initial]\n        end\n      end\n\n      model = ThisNameBetterNotBeInUse.new\n      model.should_receive(:do_something_before).once\n      model.before_as_proc!\n    end\n  end\n\n  it 'in right order' do\n    ThisNameBetterNotBeInUse.instance_eval do\n      aasm_event :in_right_order, :after => :do_something_after do\n        before do\n          do_something_before\n        end\n        transitions :to => :proc, :from => [:initial]\n      end\n    end\n\n    model = ThisNameBetterNotBeInUse.new\n    model.should_receive(:do_something_before).once.ordered\n    model.should_receive(:do_something_after).once.ordered\n    model.in_right_order!\n  end\nend\n\ndescribe 'parametrised events' do\n  let(:pe) {ParametrisedEvent.new}\n\n  it 'should transition to specified next state (sleeping to showering)' do\n    pe.wakeup!(:showering)\n    pe.aasm_current_state.should == :showering\n  end\n\n  it 'should transition to specified next state (sleeping to working)' do\n    pe.wakeup!(:working)\n    pe.aasm_current_state.should == :working\n  end\n\n  it 'should transition to default (first or showering) state' do\n    pe.wakeup!\n    pe.aasm_current_state.should == :showering\n  end\n\n  it 'should transition to default state when on_transition invoked' do\n    pe.dress!(nil, 'purple', 'dressy')\n    pe.aasm_current_state.should == :working\n  end\n\n  it 'should call on_transition method with args' do\n    pe.wakeup!(:showering)\n    pe.should_receive(:wear_clothes).with('blue', 'jeans')\n    pe.dress!(:working, 'blue', 'jeans')\n  end\n\n  it 'should call on_transition proc' do\n    pe.wakeup!(:showering)\n    pe.should_receive(:wear_clothes).with('purple', 'slacks')\n    pe.dress!(:dating, 'purple', 'slacks')\n  end\n\n  it 'should call on_transition with an array of methods' do\n    pe.wakeup!(:showering)\n    pe.should_receive(:condition_hair)\n    pe.should_receive(:fix_hair)\n    pe.dress!(:prettying_up)\n  end\nend\n\ndescribe 'event firing without persistence' do\n  it 'should attempt to persist if aasm_write_state is defined' do\n    foo = Foo.new\n    def foo.aasm_write_state; end\n    foo.should be_open\n\n    foo.should_receive(:aasm_write_state_without_persistence)\n    foo.close\n  end\nend\n"
  },
  {
    "path": "spec/unit/initial_state_spec.rb",
    "content": "require 'spec_helper'\n\nclass Banker\n  include AASM\n  aasm do\n    state :retired\n    state :selling_bad_mortgages\n  end\n  aasm_initial_state  Proc.new { |banker| banker.rich? ? :retired : :selling_bad_mortgages }\n  RICH = 1_000_000\n  attr_accessor :balance\n  def initialize(balance = 0); self.balance = balance; end\n  def rich?; self.balance >= RICH; end\nend\n\ndescribe 'initial states' do\n  let(:bar) {Bar.new}\n\n  it 'should use the first state defined if no initial state is given' do\n    bar.aasm_current_state.should == :read\n    # bar.aasm.current_state.should == :read # not yet supported\n  end\n\n  it 'should determine initial state from the Proc results' do\n    Banker.new(Banker::RICH - 1).aasm_current_state.should == :selling_bad_mortgages\n    Banker.new(Banker::RICH + 1).aasm_current_state.should == :retired\n  end\nend\n"
  },
  {
    "path": "spec/unit/inspection_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe 'inspection for common cases' do\n  it 'should support the old DSL' do\n    Foo.should respond_to(:aasm_states)\n    Foo.aasm_states.should include(:open)\n    Foo.aasm_states.should include(:closed)\n\n    Foo.should respond_to(:aasm_initial_state)\n    Foo.aasm_initial_state.should == :open\n\n    Foo.should respond_to(:aasm_events)\n    Foo.aasm_events.should include(:close)\n    Foo.aasm_events.should include(:null)\n  end\n\n  it 'should support the new DSL' do\n    Foo.aasm.should respond_to(:states)\n    Foo.aasm.states.should include(:open)\n    Foo.aasm.states.should include(:closed)\n\n    Foo.aasm.should respond_to(:initial_state)\n    Foo.aasm.initial_state.should == :open\n\n    Foo.aasm.should respond_to(:events)\n    Foo.aasm.events.should include(:close)\n    Foo.aasm.events.should include(:null)\n  end\n\n  context \"instance level inspection\" do\n    let(:foo) { Foo.new }\n    let(:two) { FooTwo.new }\n\n    it \"delivers all states\" do\n      states = foo.aasm.states\n      states.should include(:open)\n      states.should include(:closed)\n\n      states = foo.aasm.states(:permissible => true)\n      states.should include(:closed)\n      states.should_not include(:open)\n\n      foo.close\n      foo.aasm.states(:permissible => true).should be_empty\n    end\n\n    it \"delivers all states for subclasses\" do\n      states = two.aasm.states\n      states.should include(:open)\n      states.should include(:closed)\n      states.should include(:foo)\n\n      states = two.aasm.states(:permissible => true)\n      states.should include(:closed)\n      states.should_not include(:open)\n\n      two.close\n      two.aasm.states(:permissible => true).should be_empty\n    end\n\n    it \"delivers all events\" do\n      events = foo.aasm.events\n      events.should include(:close)\n      events.should include(:null)\n      foo.close\n      foo.aasm.events.should be_empty\n    end\n  end\n\n  it 'should list states in the order they have been defined' do\n    Conversation.aasm.states.should == [:needs_attention, :read, :closed, :awaiting_response, :junk]\n  end\nend\n\ndescribe \"special cases\" do\n  it \"should support valid a state name\" do\n    Argument.aasm_states.should include(:invalid)\n    Argument.aasm_states.should include(:valid)\n\n    argument = Argument.new\n    argument.invalid?.should be_true\n    argument.aasm_current_state.should == :invalid\n\n    argument.valid!\n    argument.valid?.should be_true\n    argument.aasm_current_state.should == :valid\n  end\nend\n\ndescribe :aasm_states_for_select do\n  it \"should return a select friendly array of states\" do\n    Foo.should respond_to(:aasm_states_for_select)\n    Foo.aasm_states_for_select.should == [['Open', 'open'], ['Closed', 'closed']]\n  end\nend\n\ndescribe :aasm_from_states_for_state do\n  it \"should return all from states for a state\" do\n    AuthMachine.should respond_to(:aasm_from_states_for_state)\n    froms = AuthMachine.aasm_from_states_for_state(:active)\n    [:pending, :passive, :suspended].each {|from| froms.should include(from)}\n  end\n\n  it \"should return from states for a state for a particular transition only\" do\n    froms = AuthMachine.aasm_from_states_for_state(:active, :transition => :unsuspend)\n    [:suspended].each {|from| froms.should include(from)}\n  end\nend\n\ndescribe 'permissible events' do\n  let(:foo) {Foo.new}\n\n  it 'work' do\n    foo.aasm.permissible_events.should include(:close)\n    foo.aasm.permissible_events.should_not include(:null)\n  end\nend\n"
  },
  {
    "path": "spec/unit/localizer_spec.rb",
    "content": "require 'spec_helper'\nrequire 'active_record'\nrequire 'logger'\nrequire 'i18n'\n\nload_schema\n\nclass LocalizerTestModel < ActiveRecord::Base\n  include AASM\n\n  attr_accessor :aasm_state\n\n  aasm_initial_state :opened\n  aasm_state :opened\n  aasm_state :closed\n\n  aasm_event :close\n  aasm_event :open\nend\n\ndescribe 'localized state names' do\n  before(:all) do\n    I18n.load_path << 'spec/en.yml'\n    I18n.default_locale = :en\n    I18n.reload!\n  end\n\n  after(:all) do\n    I18n.load_path.clear\n  end\n\n  it 'should localize' do\n    LocalizerTestModel.aasm.states.detect {|s| s == :opened}.localized_name.should == \"It's open now!\"\n  end\n\n  it 'should use fallback' do\n    LocalizerTestModel.aasm.states.detect {|s| s == :closed}.localized_name.should == 'Closed'\n  end\nend\n\ndescribe AASM::Localizer, \"new style\" do\n  before(:all) do\n    I18n.load_path << 'spec/en.yml'\n    I18n.default_locale = :en\n    I18n.reload!\n  end\n\n  after(:all) do\n    I18n.load_path.clear\n  end\n\n  let (:foo_opened) { LocalizerTestModel.new }\n  let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed  } }\n\n  context 'aasm_human_state' do\n    it 'should return translated state value' do\n      foo_opened.aasm_human_state.should == \"It's open now!\"\n    end\n\n    it 'should return humanized value if not localized' do\n      foo_closed.aasm_human_state.should == \"Closed\"\n    end\n  end\n\n  context 'aasm_human_event_name' do\n    it 'should return translated event name' do\n      LocalizerTestModel.aasm_human_event_name(:close).should == \"Let's close it!\"\n    end\n\n    it 'should return humanized event name' do\n      LocalizerTestModel.aasm_human_event_name(:open).should == \"Open\"\n    end\n  end\nend\n\ndescribe AASM::Localizer, \"deprecated style\" do\n  before(:all) do\n    I18n.load_path << 'spec/en_deprecated_style.yml'\n    I18n.default_locale = :en\n    I18n.reload!\n  end\n\n  after(:all) do\n    I18n.load_path.clear\n  end\n\n  let (:foo_opened) { LocalizerTestModel.new }\n  let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed  } }\n\n  context 'aasm_human_state' do\n    it 'should return translated state value' do\n      foo_opened.aasm_human_state.should == \"It's open now!\"\n    end\n\n    it 'should return humanized value if not localized' do\n      foo_closed.aasm_human_state.should == \"Closed\"\n    end\n  end\n\n  context 'aasm_human_event_name' do\n    it 'should return translated event name' do\n      LocalizerTestModel.aasm_human_event_name(:close).should == \"Let's close it!\"\n    end\n\n    it 'should return humanized event name' do\n      LocalizerTestModel.aasm_human_event_name(:open).should == \"Open\"\n    end\n  end\nend\n"
  },
  {
    "path": "spec/unit/memory_leak_spec.rb",
    "content": "# require 'spec_helper'\n\n# describe \"state machines\" do\n\n#   def number_of_objects(clazz)\n#     ObjectSpace.each_object(clazz) {}\n#   end\n\n#   def machines\n#     AASM::StateMachine.instance_variable_get(\"@machines\")\n#   end\n\n#   it \"should be created without memory leak\" do\n#     machines_count = machines.size\n#     state_count = number_of_objects(AASM::State)\n#     event_count = number_of_objects(AASM::Event)\n#     puts \"event_count = #{event_count}\"\n#     transition_count = number_of_objects(AASM::Transition)\n\n#     load File.expand_path(File.dirname(__FILE__) + '/../models/not_auto_loaded/process.rb')\n#     machines.size.should == machines_count + 1                                                  # + Process\n#     number_of_objects(Models::Process).should == 0\n#     number_of_objects(AASM::State).should == state_count + 3                 # + Process\n#     puts \"event_count = #{number_of_objects(AASM::Event)}\"\n#     number_of_objects(AASM::Event).should == event_count + 2                 # + Process\n#     number_of_objects(AASM::Transition).should == transition_count + 2  # + Process\n\n#     Models.send(:remove_const, \"Process\") if Models.const_defined?(\"Process\")\n#     load File.expand_path(File.dirname(__FILE__) + '/../models/not_auto_loaded/process.rb')\n#     machines.size.should == machines_count + 1                                                  # + Process\n#     number_of_objects(AASM::State).should == state_count + 3                 # + Process\n#     # ObjectSpace.each_object(AASM::Event) {|o| puts o.inspect}\n#     puts \"event_count = #{number_of_objects(AASM::Event)}\"\n#     number_of_objects(AASM::Event).should == event_count + 2                 # + Process\n#     number_of_objects(AASM::Transition).should == transition_count + 2  # + Process\n#   end\n\n# end\n"
  },
  {
    "path": "spec/unit/new_dsl_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe \"the new dsl\" do\n\n  let(:process) {ProcessWithNewDsl.new}\n\n  it 'should not conflict with other event or state methods' do\n    lambda {ProcessWithNewDsl.state}.should raise_error(RuntimeError, \"wrong state method\")\n    lambda {ProcessWithNewDsl.event}.should raise_error(RuntimeError, \"wrong event method\")\n  end\n\nend\n"
  },
  {
    "path": "spec/unit/persistence/active_record_persistence_spec.rb",
    "content": "require 'active_record'\nrequire 'logger'\nrequire 'spec_helper'\n\nload_schema\n\n# if you want to see the statements while running the spec enable the following line\n# ActiveRecord::Base.logger = Logger.new(STDERR)\n\nshared_examples_for \"aasm model\" do\n  it \"should include persistence mixins\" do\n    klass.included_modules.should be_include(AASM::Persistence::ActiveRecordPersistence)\n    klass.included_modules.should be_include(AASM::Persistence::ActiveRecordPersistence::InstanceMethods)\n  end\nend\n\ndescribe \"instance methods\" do\n  let(:gate) {Gate.new}\n\n  it \"should respond to aasm persistence methods\" do\n    gate.should respond_to(:aasm_read_state)\n    gate.should respond_to(:aasm_write_state)\n    gate.should respond_to(:aasm_write_state_without_persistence)\n  end\n\n  it \"should return the initial state when new and the aasm field is nil\" do\n    gate.aasm_current_state.should == :opened\n  end\n\n  it \"should return the aasm column when new and the aasm field is not nil\" do\n    gate.aasm_state = \"closed\"\n    gate.aasm_current_state.should == :closed\n  end\n\n  it \"should return the aasm column when not new and the aasm_column is not nil\" do\n    gate.stub!(:new_record?).and_return(false)\n    gate.aasm_state = \"state\"\n    gate.aasm_current_state.should == :state\n  end\n\n  it \"should allow a nil state\" do\n    gate.stub!(:new_record?).and_return(false)\n    gate.aasm_state = nil\n    gate.aasm_current_state.should be_nil\n  end\n\n  it \"should call aasm_ensure_initial_state on validation before create\" do\n    gate.should_receive(:aasm_ensure_initial_state).and_return(true)\n    gate.valid?\n  end\n\n  it \"should not call aasm_ensure_initial_state on validation before update\" do\n    gate.stub!(:new_record?).and_return(false)\n    gate.should_not_receive(:aasm_ensure_initial_state)\n    gate.valid?\n  end\n\nend\n\ndescribe 'subclasses' do\n  it \"should have the same states as its parent class\" do\n    Derivate.aasm_states.should == Simple.aasm_states\n  end\n\n  it \"should have the same events as its parent class\" do\n    Derivate.aasm_events.should == Simple.aasm_events\n  end\n\n  it \"should have the same column as its parent class\" do\n    Derivate.aasm_column.should == :status\n  end\n\n  it \"should have the same column as its parent even for the new dsl\" do\n    SimpleNewDsl.aasm_column.should == :status\n    DerivateNewDsl.aasm_column.should == :status\n  end\nend\n\ndescribe \"named scopes with the old DSL\" do\n\n  context \"Does not already respond_to? the scope name\" do\n    it \"should add a scope\" do\n      Simple.should respond_to(:unknown_scope)\n      SimpleNewDsl.unknown_scope.is_a?(ActiveRecord::Relation).should be_true\n    end\n  end\n\n  context \"Already respond_to? the scope name\" do\n    it \"should not add a scope\" do\n      Simple.should respond_to(:new)\n      Simple.new.class.should == Simple\n    end\n  end\n\nend\n\ndescribe \"named scopes with the new DSL\" do\n\n  context \"Does not already respond_to? the scope name\" do\n    it \"should add a scope\" do\n      SimpleNewDsl.should respond_to(:unknown_scope)\n      SimpleNewDsl.unknown_scope.is_a?(ActiveRecord::Relation).should be_true\n    end\n  end\n\n  context \"Already respond_to? the scope name\" do\n    it \"should not add a scope\" do\n      SimpleNewDsl.should respond_to(:new)\n      SimpleNewDsl.new.class.should == SimpleNewDsl\n    end\n  end\n\nend\n\ndescribe 'initial states' do\n\n  it 'should support conditions' do\n    Thief.new(:skilled => true).aasm_current_state.should == :rich\n    Thief.new(:skilled => false).aasm_current_state.should == :jailed\n  end\nend\n\ndescribe 'transitions with persistence' do\n\n  it \"should work for valid models\" do\n    valid_object = Validator.create(:name => 'name')\n    valid_object.should be_sleeping\n    valid_object.status = :running\n    valid_object.should be_running\n  end\n\n  it 'should not store states for invalid models' do\n    validator = Validator.create(:name => 'name')\n    validator.should be_valid\n    validator.should be_sleeping\n\n    validator.name = nil\n    validator.should_not be_valid\n    validator.run!.should be_false\n    validator.should be_sleeping\n\n    validator.reload\n    validator.should_not be_running\n    validator.should be_sleeping\n\n    validator.name = 'another name'\n    validator.should be_valid\n    validator.run!.should be_true\n    validator.should be_running\n\n    validator.reload\n    validator.should be_running\n    validator.should_not be_sleeping\n  end\n\n  it 'should store states for invalid models if configured' do\n    persistor = InvalidPersistor.create(:name => 'name')\n    persistor.should be_valid\n    persistor.should be_sleeping\n\n    persistor.name = nil\n    persistor.should_not be_valid\n    persistor.run!.should be_true\n    persistor.should be_running\n\n    persistor = InvalidPersistor.find(persistor.id)\n    persistor.valid?\n    persistor.should be_valid\n    persistor.should be_running\n    persistor.should_not be_sleeping\n\n    persistor.reload\n    persistor.should be_running\n    persistor.should_not be_sleeping\n  end\n\n  describe 'transactions' do\n    it 'should rollback all changes' do\n      worker = Worker.create!(:name => 'worker', :status => 'sleeping')\n      transactor = Transactor.create!(:name => 'transactor', :worker => worker)\n      transactor.should be_sleeping\n      worker.status.should == 'sleeping'\n\n      lambda {transactor.run!}.should raise_error(StandardError, 'failed on purpose')\n      transactor.should be_running\n      worker.reload.status.should == 'sleeping'\n    end\n  end\n\nend\n"
  },
  {
    "path": "spec/unit/persistence/mongoid_persistance_spec.rb",
    "content": "describe 'mongoid', :if => Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3') do\n# describe 'mongoid' do\n\n  before(:all) do\n    require 'mongoid'\n    require 'logger'\n    require 'spec_helper'\n    Dir[File.dirname(__FILE__) + \"/../../models/mongoid/*.rb\"].sort.each { |f| require File.expand_path(f) }\n\n    # if you want to see the statements while running the spec enable the following line\n    # Mongoid.logger = Logger.new(STDERR)\n\n    DATABASE_NAME = \"mongoid_#{Process.pid}\"\n\n    Mongoid.configure do |config|\n      config.connect_to DATABASE_NAME\n    end\n  end\n\n  after do\n    Mongoid.purge!\n  end\n\n  describe \"named scopes with the old DSL\" do\n\n    context \"Does not already respond_to? the scope name\" do\n      it \"should add a scope\" do\n        SimpleMongoid.should respond_to(:unknown_scope)\n        SimpleMongoid.unknown_scope.class.should == Mongoid::Criteria\n      end\n    end\n\n    context \"Already respond_to? the scope name\" do\n      it \"should not add a scope\" do\n        SimpleMongoid.should respond_to(:new)\n        SimpleMongoid.new.class.should == SimpleMongoid\n      end\n    end\n\n  end\n\n  describe \"named scopes with the new DSL\" do\n\n    context \"Does not already respond_to? the scope name\" do\n      it \"should add a scope\" do\n        SimpleNewDslMongoid.should respond_to(:unknown_scope)\n        SimpleNewDslMongoid.unknown_scope.class.should == Mongoid::Criteria\n      end\n    end\n\n    context \"Already respond_to? the scope name\" do\n      it \"should not add a scope\" do\n        SimpleNewDslMongoid.should respond_to(:new)\n        SimpleNewDslMongoid.new.class.should == SimpleNewDslMongoid\n      end\n    end\n\n  end\n\n  describe \"#find_in_state\" do\n\n    let!(:model)    { SimpleNewDslMongoid.create!(:status => :unknown_scope) }\n    let!(:model_id) { model._id }\n\n    it \"should respond to method\" do\n      SimpleNewDslMongoid.should respond_to(:find_in_state)\n    end\n\n    it \"should find the model when given the correct scope and model id\" do\n      SimpleNewDslMongoid.find_in_state(model_id, 'unknown_scope').class.should == SimpleNewDslMongoid\n      SimpleNewDslMongoid.find_in_state(model_id, 'unknown_scope').should == model\n    end\n\n    it \"should raise DocumentNotFound error when given incorrect scope\" do\n      expect {SimpleNewDslMongoid.find_in_state(model_id, 'new')}.to raise_error Mongoid::Errors::DocumentNotFound\n    end\n\n    it \"should raise DocumentNotFound error when given incorrect model id\" do\n      expect {SimpleNewDslMongoid.find_in_state('bad_id', 'unknown_scope')}.to raise_error Mongoid::Errors::DocumentNotFound\n    end\n\n  end\n\n  describe \"#count_in_state\" do\n\n    before do\n      3.times { SimpleNewDslMongoid.create!(:status => :unknown_scope) }\n    end\n\n    it \"should respond to method\" do\n      SimpleNewDslMongoid.should respond_to(:count_in_state)\n    end\n\n    it \"should return n for a scope with n records persisted\" do\n      SimpleNewDslMongoid.count_in_state('unknown_scope').class.should == Fixnum\n      SimpleNewDslMongoid.count_in_state('unknown_scope').should == 3\n    end\n\n    it \"should return zero for a scope without records persisted\" do\n      SimpleNewDslMongoid.count_in_state('new').class.should == Fixnum\n      SimpleNewDslMongoid.count_in_state('new').should == 0\n    end\n\n  end\n\n  describe \"#with_state_scope\" do\n\n    before do\n      3.times { SimpleNewDslMongoid.create!(:status => :unknown_scope) }\n      2.times { SimpleNewDslMongoid.create!(:status => :new) }\n    end\n\n    it \"should respond to method\" do\n      SimpleNewDslMongoid.should respond_to(:with_state_scope)\n    end\n\n    it \"should correctly process block\" do\n      SimpleNewDslMongoid.with_state_scope('unknown_scope') do\n        SimpleNewDslMongoid.count\n      end.should == 3\n      SimpleNewDslMongoid.with_state_scope('new') do\n        SimpleNewDslMongoid.count\n      end.should == 2\n    end\n\n  end\nend\n"
  },
  {
    "path": "spec/unit/simple_example_spec.rb",
    "content": "require 'spec_helper'\n\nclass Payment\n  include AASM\n  aasm do\n    state :initialised, :initial => true\n    state :filled_out\n    state :authorised\n\n    event :fill_out do\n      transitions :from => :initialised, :to => :filled_out\n    end\n    event :authorise do\n      transitions :from => :filled_out, :to => :authorised\n    end\n  end\nend\n\ndescribe 'state machine' do\n  let(:payment) {Payment.new}\n\n  it 'starts with an initial state' do\n    payment.aasm_current_state.should == :initialised\n    # payment.aasm.current_state.should == :initialised # not yet supported\n    payment.should respond_to(:initialised?)\n    payment.should be_initialised\n  end\n\n  it 'allows transitions to other states' do\n    payment.should respond_to(:fill_out)\n    payment.should respond_to(:fill_out!)\n    payment.fill_out!\n    payment.should respond_to(:filled_out?)\n    payment.should be_filled_out\n\n    payment.should respond_to(:authorise)\n    payment.should respond_to(:authorise!)\n    payment.authorise\n    payment.should respond_to(:authorised?)\n    payment.should be_authorised\n  end\n\n  it 'denies transitions to other states' do\n    lambda {payment.authorise}.should raise_error(AASM::InvalidTransition)\n    lambda {payment.authorise!}.should raise_error(AASM::InvalidTransition)\n    payment.fill_out\n    lambda {payment.fill_out}.should raise_error(AASM::InvalidTransition)\n    lambda {payment.fill_out!}.should raise_error(AASM::InvalidTransition)\n    payment.authorise\n    lambda {payment.fill_out}.should raise_error(AASM::InvalidTransition)\n    lambda {payment.fill_out!}.should raise_error(AASM::InvalidTransition)\n  end\n\n  it 'defines constants for each state name' do\n    Payment::STATE_INITIALISED.should eq(:initialised)\n    Payment::STATE_FILLED_OUT.should eq(:filled_out)\n    Payment::STATE_AUTHORISED.should eq(:authorised)\n  end\nend\n"
  },
  {
    "path": "spec/unit/state_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe AASM::State do\n  before(:each) do\n    @name    = :astate\n    @options = { :crazy_custom_key => 'key' }\n  end\n\n  def new_state(options={})\n    AASM::State.new(@name, Conversation, @options.merge(options))\n  end\n\n  it 'should set the name' do\n    state = new_state\n    state.name.should == :astate\n  end\n\n  it 'should set the display_name from name' do\n    new_state.display_name.should == 'Astate'\n  end\n\n  it 'should set the display_name from options' do\n    new_state(:display => \"A State\").display_name.should == 'A State'\n  end\n\n  it 'should set the options and expose them as options' do\n    new_state.options.should == @options\n  end\n\n  it 'should be equal to a symbol of the same name' do\n    new_state.should == :astate\n  end\n\n  it 'should be equal to a State of the same name' do\n    new_state.should == new_state\n  end\n\n  it 'should send a message to the record for an action if the action is present as a symbol' do\n    state = new_state(:entering => :foo)\n\n    record = mock('record')\n    record.should_receive(:foo)\n\n    state.fire_callbacks(:entering, record)\n  end\n\n  it 'should send a message to the record for an action if the action is present as a string' do\n    state = new_state(:entering => 'foo')\n\n    record = mock('record')\n    record.should_receive(:foo)\n\n    state.fire_callbacks(:entering, record)\n  end\n\n  it 'should send a message to the record for each action' do\n    state = new_state(:entering => [:a, :b, \"c\", lambda {|r| r.foobar }])\n\n    record = mock('record')\n    record.should_receive(:a)\n    record.should_receive(:b)\n    record.should_receive(:c)\n    record.should_receive(:foobar)\n\n    state.fire_callbacks(:entering, record)\n  end\n\n  it \"should stop calling actions if one of them raises :halt_aasm_chain\" do\n    state = new_state(:entering => [:a, :b, :c])\n\n    record = mock('record')\n    record.should_receive(:a)\n    record.should_receive(:b).and_throw(:halt_aasm_chain)\n    record.should_not_receive(:c)\n\n    state.fire_callbacks(:entering, record)\n  end\n\n  it 'should call a proc, passing in the record for an action if the action is present' do\n    state = new_state(:entering => Proc.new {|r| r.foobar})\n\n    record = mock('record')\n    record.should_receive(:foobar)\n\n    state.fire_callbacks(:entering, record)\n  end\nend\n"
  },
  {
    "path": "spec/unit/subclassing_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe 'subclassing' do\n  let(:son) {Son.new}\n\n  it 'should have the parent states' do\n    Foo.aasm_states.each do |state|\n      FooTwo.aasm_states.should include(state)\n    end\n    Baz.aasm_states.should == Bar.aasm_states\n  end\n\n  it 'should not add the child states to the parent machine' do\n    Foo.aasm_states.should_not include(:foo)\n  end\n\n  it \"should have the same events as its parent\" do\n    Baz.aasm_events.should == Bar.aasm_events\n  end\n\n  it 'should know how to respond to `may_add_details?`' do\n    son.may_add_details?.should be_true\n  end\n\n  it 'should not break if I call Son#update_state' do\n    son.update_state\n    son.aasm_current_state.should == :pending_details_confirmation\n  end\n  \nend\n\n"
  },
  {
    "path": "spec/unit/transition_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe 'transitions' do\n\n  it 'should raise an exception when whiny' do\n    process = ProcessWithNewDsl.new\n    lambda { process.stop! }.should raise_error(AASM::InvalidTransition)\n    process.should be_sleeping\n  end\n\n  it 'should not raise an exception when not whiny' do\n    silencer = Silencer.new\n    silencer.smile!.should be_false\n    silencer.should be_silent\n  end\n\n  it 'should not raise an exception when superclass not whiny' do\n    sub = SubClassing.new\n    sub.smile!.should be_false\n    sub.should be_silent\n  end\n\n  it 'should not raise an exception when from is nil even if whiny' do\n    silencer = Silencer.new\n    silencer.smile_any!.should be_true\n    silencer.should be_smiling\n  end\n\nend\n\ndescribe AASM::Transition do\n  it 'should set from, to, and opts attr readers' do\n    opts = {:from => 'foo', :to => 'bar', :guard => 'g'}\n    st = AASM::Transition.new(opts)\n\n    st.from.should == opts[:from]\n    st.to.should == opts[:to]\n    st.opts.should == opts\n  end\n\n  it 'should pass equality check if from and to are the same' do\n    opts = {:from => 'foo', :to => 'bar', :guard => 'g'}\n    st = AASM::Transition.new(opts)\n\n    obj = mock('object')\n    obj.stub!(:from).and_return(opts[:from])\n    obj.stub!(:to).and_return(opts[:to])\n\n    st.should == obj\n  end\n\n  it 'should fail equality check if from are not the same' do\n    opts = {:from => 'foo', :to => 'bar', :guard => 'g'}\n    st = AASM::Transition.new(opts)\n\n    obj = mock('object')\n    obj.stub!(:from).and_return('blah')\n    obj.stub!(:to).and_return(opts[:to])\n\n    st.should_not == obj\n  end\n\n  it 'should fail equality check if to are not the same' do\n    opts = {:from => 'foo', :to => 'bar', :guard => 'g'}\n    st = AASM::Transition.new(opts)\n\n    obj = mock('object')\n    obj.stub!(:from).and_return(opts[:from])\n    obj.stub!(:to).and_return('blah')\n\n    st.should_not == obj\n  end\nend\n\ndescribe AASM::Transition, '- when performing guard checks' do\n  it 'should return true of there is no guard' do\n    opts = {:from => 'foo', :to => 'bar'}\n    st = AASM::Transition.new(opts)\n\n    st.perform(nil).should be_true\n  end\n\n  it 'should call the method on the object if guard is a symbol' do\n    opts = {:from => 'foo', :to => 'bar', :guard => :test}\n    st = AASM::Transition.new(opts)\n\n    obj = mock('object')\n    obj.should_receive(:test)\n\n    st.perform(obj)\n  end\n\n  it 'should call the method on the object if guard is a string' do\n    opts = {:from => 'foo', :to => 'bar', :guard => 'test'}\n    st = AASM::Transition.new(opts)\n\n    obj = mock('object')\n    obj.should_receive(:test)\n\n    st.perform(obj)\n  end\n\n  it 'should call the proc passing the object if the guard is a proc' do\n    opts = {:from => 'foo', :to => 'bar', :guard => Proc.new {|o| o.test}}\n    st = AASM::Transition.new(opts)\n\n    obj = mock('object')\n    obj.should_receive(:test)\n\n    st.perform(obj)\n  end\nend\n\ndescribe AASM::Transition, '- when executing the transition with a Proc' do\n  it 'should call a Proc on the object with args' do\n    opts = {:from => 'foo', :to => 'bar', :on_transition => Proc.new {|o| o.test}}\n    st = AASM::Transition.new(opts)\n    args = {:arg1 => '1', :arg2 => '2'}\n    obj = mock('object')\n\n    opts[:on_transition].should_receive(:call).with(any_args)\n\n    st.execute(obj, args)\n  end\n\n  it 'should call a Proc on the object without args' do\n    opts = {:from => 'foo', :to => 'bar', :on_transition => Proc.new {||}}\n    st = AASM::Transition.new(opts)\n    args = {:arg1 => '1', :arg2 => '2'}\n    obj = mock('object')\n\n    opts[:on_transition].should_receive(:call).with(no_args)\n\n    st.execute(obj, args)\n  end\nend\n\ndescribe AASM::Transition, '- when executing the transition with an :on_transtion method call' do\n  it 'should accept a String for the method name' do\n    opts = {:from => 'foo', :to => 'bar', :on_transition => 'test'}\n    st = AASM::Transition.new(opts)\n    args = {:arg1 => '1', :arg2 => '2'}\n    obj = mock('object')\n\n    obj.should_receive(:test)\n\n    st.execute(obj, args)\n  end\n\n  it 'should accept a Symbol for the method name' do\n    opts = {:from => 'foo', :to => 'bar', :on_transition => :test}\n    st = AASM::Transition.new(opts)\n    args = {:arg1 => '1', :arg2 => '2'}\n    obj = mock('object')\n\n    obj.should_receive(:test)\n\n    st.execute(obj, args)\n  end\n\n  it 'should pass args if the target method accepts them' do\n    opts = {:from => 'foo', :to => 'bar', :on_transition => :test}\n    st = AASM::Transition.new(opts)\n    args = {:arg1 => '1', :arg2 => '2'}\n    obj = mock('object')\n\n    obj.class.class_eval do\n      define_method(:test) {|*args| 'success'}\n    end\n\n    return_value = st.execute(obj, args)\n\n    return_value.should == 'success'\n  end\n\n  it 'should NOT pass args if the target method does NOT accept them' do\n    opts = {:from => 'foo', :to => 'bar', :on_transition => :test}\n    st = AASM::Transition.new(opts)\n    args = {:arg1 => '1', :arg2 => '2'}\n    obj = mock('object')\n\n    obj.class.class_eval do\n      define_method(:test) {|*args| 'success'}\n    end\n\n    return_value = st.execute(obj, args)\n\n    return_value.should == 'success'\n  end\n\nend\n"
  }
]