transitions 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +5 -0
- data/lib/transitions/state.rb +26 -1
- data/lib/transitions/version.rb +1 -1
- data/lib/transitions.rb +3 -7
- data/test/db/create_db.rb +3 -0
- data/test/helper.rb +1 -0
- data/test/test_active_record.rb +29 -12
- data/test/test_state.rb +49 -20
- data/transitions.gemspec +1 -0
- metadata +26 -15
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,8 @@ | |
| 1 | 
            +
            # 0.0.18 (2012-05-18)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * (troessner) Remove `define_state_query_method` from public API
         | 
| 4 | 
            +
            * (troessner) Do not override existing methods when defining state query methods but warn the user.
         | 
| 5 | 
            +
             | 
| 1 6 | 
             
            # 0.0.17 (2012-05-02):
         | 
| 2 7 |  | 
| 3 8 | 
             
            * (zmillman) Add write_state_without_persistence.
         | 
    
        data/lib/transitions/state.rb
    CHANGED
    
    | @@ -27,7 +27,7 @@ module Transitions | |
| 27 27 | 
             
                def initialize(name, options = {})
         | 
| 28 28 | 
             
                  @name = name
         | 
| 29 29 | 
             
                  if machine = options.delete(:machine)
         | 
| 30 | 
            -
                     | 
| 30 | 
            +
                    define_state_query_method(machine)
         | 
| 31 31 | 
             
                  end
         | 
| 32 32 | 
             
                  update(options)
         | 
| 33 33 | 
             
                end
         | 
| @@ -63,5 +63,30 @@ module Transitions | |
| 63 63 | 
             
                  @options = options
         | 
| 64 64 | 
             
                  self
         | 
| 65 65 | 
             
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                private
         | 
| 68 | 
            +
                def define_state_query_method(machine)
         | 
| 69 | 
            +
                  method_name, state_name = "#{@name}?", @name # Instance vars are out of scope when calling define_method below, so we use local variables.
         | 
| 70 | 
            +
                  if method_already_defined_on_recipient?(machine, method_name)
         | 
| 71 | 
            +
                    override_warning method_name
         | 
| 72 | 
            +
                  else
         | 
| 73 | 
            +
                    machine.klass.send :define_method, method_name do
         | 
| 74 | 
            +
                      current_state.to_s == state_name.to_s
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def method_already_defined_on_recipient?(machine, method_name)
         | 
| 80 | 
            +
                  machine.klass.new.respond_to?(method_name)
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def override_warning(method_name)
         | 
| 84 | 
            +
                  warning = "Transitions: Can not define method #{method_name} because it is already defined, please rename either the existing method or the state."
         | 
| 85 | 
            +
                  if Rails && Rails.logger
         | 
| 86 | 
            +
                    Rails.logger.warn warning
         | 
| 87 | 
            +
                  else
         | 
| 88 | 
            +
                    puts warning
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
                end
         | 
| 66 91 | 
             
              end
         | 
| 67 92 | 
             
            end
         | 
    
        data/lib/transitions/version.rb
    CHANGED
    
    
    
        data/lib/transitions.rb
    CHANGED
    
    | @@ -32,7 +32,7 @@ module Transitions | |
| 32 32 |  | 
| 33 33 | 
             
              module ClassMethods
         | 
| 34 34 | 
             
                def inherited(klass)
         | 
| 35 | 
            -
                  super
         | 
| 35 | 
            +
                  super # Make sure we call other callbacks possibly defined upstream the ancestor chain.
         | 
| 36 36 | 
             
                  klass.state_machines = state_machines
         | 
| 37 37 | 
             
                end
         | 
| 38 38 |  | 
| @@ -40,6 +40,7 @@ module Transitions | |
| 40 40 | 
             
                  @state_machines ||= {}
         | 
| 41 41 | 
             
                end
         | 
| 42 42 |  | 
| 43 | 
            +
                # The only reason we need this method is for the inherited callback.
         | 
| 43 44 | 
             
                def state_machines=(value)
         | 
| 44 45 | 
             
                  @state_machines = value ? value.dup : nil
         | 
| 45 46 | 
             
                end
         | 
| @@ -57,18 +58,13 @@ module Transitions | |
| 57 58 | 
             
                def available_states(name = :default)
         | 
| 58 59 | 
             
                  state_machines[name].states.map(&:name).sort_by {|x| x.to_s}
         | 
| 59 60 | 
             
                end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                def define_state_query_method(state_name)
         | 
| 62 | 
            -
                  name = "#{state_name}?"
         | 
| 63 | 
            -
                  undef_method(name) if method_defined?(name)
         | 
| 64 | 
            -
                  define_method(name) { current_state.to_s == %(#{state_name}) }
         | 
| 65 | 
            -
                end
         | 
| 66 61 | 
             
              end
         | 
| 67 62 |  | 
| 68 63 | 
             
              def self.included(base)
         | 
| 69 64 | 
             
                base.extend(ClassMethods)
         | 
| 70 65 | 
             
              end
         | 
| 71 66 |  | 
| 67 | 
            +
              # TODO Do we need this method really? Also, it's not a beauty, refactor at least.
         | 
| 72 68 | 
             
              def current_state(name = nil, new_state = nil, persist = false)
         | 
| 73 69 | 
             
                sm   = self.class.state_machine(name)
         | 
| 74 70 | 
             
                ivar = sm.current_state_variable
         | 
    
        data/test/db/create_db.rb
    CHANGED
    
    
    
        data/test/helper.rb
    CHANGED
    
    
    
        data/test/test_active_record.rb
    CHANGED
    
    | @@ -1,6 +1,8 @@ | |
| 1 1 | 
             
            require "helper"
         | 
| 2 2 | 
             
            require 'active_support/core_ext/module/aliasing'
         | 
| 3 3 |  | 
| 4 | 
            +
            # TODO Tests here are quite messy, clean up.
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
            ActiveRecord::Base.establish_connection(:adapter  => "sqlite3", :database => ":memory:")
         | 
| 5 7 |  | 
| 6 8 | 
             
            class CreateTrafficLights < ActiveRecord::Migration
         | 
| @@ -188,34 +190,49 @@ class TestNewActiveRecord < TestActiveRecord | |
| 188 190 |  | 
| 189 191 | 
             
            end
         | 
| 190 192 |  | 
| 193 | 
            +
            class CreateBunnies < ActiveRecord::Migration
         | 
| 194 | 
            +
              def self.up
         | 
| 195 | 
            +
                create_table(:bunnies) do |t|
         | 
| 196 | 
            +
                  t.string :state
         | 
| 197 | 
            +
                end
         | 
| 198 | 
            +
              end
         | 
| 199 | 
            +
            end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
            CreateBunnies.migrate(:up)
         | 
| 202 | 
            +
             | 
| 203 | 
            +
            class Bunny < ActiveRecord::Base
         | 
| 204 | 
            +
              include ActiveModel::Transitions
         | 
| 205 | 
            +
             | 
| 206 | 
            +
              state_machine :auto_scopes => true do
         | 
| 207 | 
            +
                state :hobbling
         | 
| 208 | 
            +
              end
         | 
| 209 | 
            +
            end
         | 
| 210 | 
            +
             | 
| 191 211 | 
             
            class TestScopes < Test::Unit::TestCase
         | 
| 192 | 
            -
               | 
| 193 | 
            -
                 | 
| 194 | 
            -
                 | 
| 195 | 
            -
                assert_equal TrafficLight.off.first, @light
         | 
| 196 | 
            -
                assert TrafficLight.red.empty?
         | 
| 212 | 
            +
              def setup
         | 
| 213 | 
            +
                create_database
         | 
| 214 | 
            +
                @bunny = Bunny.create!
         | 
| 197 215 | 
             
              end
         | 
| 198 216 |  | 
| 199 217 | 
             
              test "scopes exist" do
         | 
| 200 | 
            -
                assert_respond_to  | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 218 | 
            +
                assert_respond_to Bunny, :hobbling
         | 
| 219 | 
            +
              end
         | 
| 220 | 
            +
             | 
| 221 | 
            +
              test "scope returns correct object" do
         | 
| 222 | 
            +
                assert_equal Bunny.hobbling.first, @bunny
         | 
| 204 223 | 
             
              end
         | 
| 205 224 |  | 
| 206 225 | 
             
              test 'scopes are only generated if we explicitly say so' do
         | 
| 207 226 | 
             
                assert_not_respond_to LightBulb, :off
         | 
| 208 | 
            -
                assert_not_respond_to LightBulb, :on
         | 
| 209 227 | 
             
              end
         | 
| 210 228 |  | 
| 211 229 | 
             
              test 'scope generation raises an exception if we try to overwrite an existing method' do
         | 
| 212 230 | 
             
                assert_raise(Transitions::InvalidMethodOverride) {
         | 
| 213 | 
            -
                  class  | 
| 231 | 
            +
                  class TrafficLight < ActiveRecord::Base
         | 
| 214 232 | 
             
                    include ActiveModel::Transitions
         | 
| 215 233 |  | 
| 216 234 | 
             
                    state_machine :auto_scopes => true do
         | 
| 217 235 | 
             
                      state :new
         | 
| 218 | 
            -
                      state :broken
         | 
| 219 236 | 
             
                    end
         | 
| 220 237 | 
             
                  end
         | 
| 221 238 | 
             
                }
         | 
    
        data/test/test_state.rb
    CHANGED
    
    | @@ -1,50 +1,50 @@ | |
| 1 1 | 
             
            require "helper"
         | 
| 2 2 |  | 
| 3 | 
            -
            class StateTestSubject
         | 
| 4 | 
            -
              include Transitions
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              state_machine do
         | 
| 7 | 
            -
              end
         | 
| 8 | 
            -
            end
         | 
| 9 | 
            -
             | 
| 10 3 | 
             
            class TestState < Test::Unit::TestCase
         | 
| 11 4 | 
             
              def setup
         | 
| 5 | 
            +
                @state_test_subject = Class.new do
         | 
| 6 | 
            +
                  include Transitions
         | 
| 7 | 
            +
                  state_machine do
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                end
         | 
| 12 10 | 
             
                @state_name = :astate
         | 
| 13 | 
            -
                @machine =  | 
| 14 | 
            -
                @options = { : | 
| 11 | 
            +
                @machine = @state_test_subject.state_machine
         | 
| 12 | 
            +
                @options = { :machine => @machine, :custom_key => :my_key }
         | 
| 13 | 
            +
                @state   = Transitions::State.new(@state_name, @options)
         | 
| 15 14 | 
             
              end
         | 
| 16 15 |  | 
| 17 | 
            -
              def  | 
| 18 | 
            -
                 | 
| 16 | 
            +
              def new_state_name
         | 
| 17 | 
            +
                Random.alphanumeric(16)
         | 
| 19 18 | 
             
              end
         | 
| 20 19 |  | 
| 21 20 | 
             
              test "sets the name" do
         | 
| 22 | 
            -
                assert_equal :astate,  | 
| 21 | 
            +
                assert_equal :astate, @state.name
         | 
| 23 22 | 
             
              end
         | 
| 24 23 |  | 
| 25 24 | 
             
              test "sets the display_name from name" do
         | 
| 26 | 
            -
                assert_equal "Astate",  | 
| 25 | 
            +
                assert_equal "Astate", @state.display_name
         | 
| 27 26 | 
             
              end
         | 
| 28 27 |  | 
| 29 28 | 
             
              test "sets the display_name from options" do
         | 
| 30 | 
            -
                assert_equal "A State",  | 
| 29 | 
            +
                assert_equal "A State", Transitions::State.new(new_state_name, @options.merge(:display => "A State")).display_name
         | 
| 31 30 | 
             
              end
         | 
| 32 31 |  | 
| 33 32 | 
             
              test "sets the options and expose them as options" do
         | 
| 34 33 | 
             
                @options.delete(:machine)
         | 
| 35 | 
            -
                 | 
| 34 | 
            +
                state = Transitions::State.new new_state_name, @options
         | 
| 35 | 
            +
                assert_equal @options, state.options
         | 
| 36 36 | 
             
              end
         | 
| 37 37 |  | 
| 38 38 | 
             
              test "equals a symbol of the same name" do
         | 
| 39 | 
            -
                assert_equal  | 
| 39 | 
            +
                assert_equal @state, :astate
         | 
| 40 40 | 
             
              end
         | 
| 41 41 |  | 
| 42 42 | 
             
              test "equals a State of the same name" do
         | 
| 43 | 
            -
                assert_equal  | 
| 43 | 
            +
                assert_equal @state, @state
         | 
| 44 44 | 
             
              end
         | 
| 45 45 |  | 
| 46 46 | 
             
              test "should send a message to the record for an action if the action is present as a symbol" do
         | 
| 47 | 
            -
                state =  | 
| 47 | 
            +
                state = Transitions::State.new new_state_name, @options.merge(:entering => :foo)
         | 
| 48 48 |  | 
| 49 49 | 
             
                record = stub
         | 
| 50 50 | 
             
                record.expects(:foo)
         | 
| @@ -53,7 +53,7 @@ class TestState < Test::Unit::TestCase | |
| 53 53 | 
             
              end
         | 
| 54 54 |  | 
| 55 55 | 
             
              test "should send a message to the record for an action if the action is present as a string" do
         | 
| 56 | 
            -
                state =  | 
| 56 | 
            +
                state = Transitions::State.new new_state_name, @options.merge(:entering => "foo")
         | 
| 57 57 |  | 
| 58 58 | 
             
                record = stub
         | 
| 59 59 | 
             
                record.expects(:foo)
         | 
| @@ -62,7 +62,7 @@ class TestState < Test::Unit::TestCase | |
| 62 62 | 
             
              end
         | 
| 63 63 |  | 
| 64 64 | 
             
              test "should call a proc, passing in the record for an action if the action is present" do
         | 
| 65 | 
            -
                state =  | 
| 65 | 
            +
                state = Transitions::State.new new_state_name, @options.merge(:entering => Proc.new {|r| r.foobar})
         | 
| 66 66 |  | 
| 67 67 | 
             
                record = stub
         | 
| 68 68 | 
             
                record.expects(:foobar)
         | 
| @@ -70,3 +70,32 @@ class TestState < Test::Unit::TestCase | |
| 70 70 | 
             
                state.call_action(:entering, record)
         | 
| 71 71 | 
             
              end
         | 
| 72 72 | 
             
            end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            class StateOverrideMethodTestSubject
         | 
| 75 | 
            +
              include Transitions
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              state_machine do
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              def a_state_name?; :foo; end
         | 
| 81 | 
            +
            end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
             | 
| 84 | 
            +
            class TestStateQueryOverrideMethod < Test::Unit::TestCase
         | 
| 85 | 
            +
              def setup
         | 
| 86 | 
            +
                @state_name = 'a_state_name'
         | 
| 87 | 
            +
                @machine = StateOverrideMethodTestSubject.state_machine
         | 
| 88 | 
            +
                @options = { :machine => @machine }
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              test "warn on creation when we try to overwrite an existing method" do
         | 
| 92 | 
            +
                # TODO
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
              test "should not override an already existing method" do
         | 
| 96 | 
            +
                Transitions::State.new :dummy, @options
         | 
| 97 | 
            +
                expected_result = :foo
         | 
| 98 | 
            +
                actual_result   = StateOverrideMethodTestSubject.new.a_state_name?
         | 
| 99 | 
            +
                assert_equal expected_result, actual_result
         | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
            end
         | 
    
        data/transitions.gemspec
    CHANGED
    
    | @@ -18,6 +18,7 @@ Gem::Specification.new do |s| | |
| 18 18 | 
             
              s.add_development_dependency "test-unit", "~> 2.2"
         | 
| 19 19 | 
             
              s.add_development_dependency "mocha"
         | 
| 20 20 | 
             
              s.add_development_dependency "rake"
         | 
| 21 | 
            +
              s.add_development_dependency "random_data"
         | 
| 21 22 | 
             
              s.add_development_dependency "sqlite3"
         | 
| 22 23 | 
             
              s.add_development_dependency "activerecord", "~> 3"
         | 
| 23 24 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: transitions
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.18
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -10,11 +10,11 @@ authors: | |
| 10 10 | 
             
            autorequire: 
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date: 2012-05- | 
| 13 | 
            +
            date: 2012-05-18 00:00:00.000000000Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: bundler
         | 
| 17 | 
            -
              requirement: & | 
| 17 | 
            +
              requirement: &76418870 !ruby/object:Gem::Requirement
         | 
| 18 18 | 
             
                none: false
         | 
| 19 19 | 
             
                requirements:
         | 
| 20 20 | 
             
                - - ~>
         | 
| @@ -22,10 +22,10 @@ dependencies: | |
| 22 22 | 
             
                    version: '1'
         | 
| 23 23 | 
             
              type: :development
         | 
| 24 24 | 
             
              prerelease: false
         | 
| 25 | 
            -
              version_requirements: * | 
| 25 | 
            +
              version_requirements: *76418870
         | 
| 26 26 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 27 27 | 
             
              name: test-unit
         | 
| 28 | 
            -
              requirement: & | 
| 28 | 
            +
              requirement: &76418470 !ruby/object:Gem::Requirement
         | 
| 29 29 | 
             
                none: false
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 31 | 
             
                - - ~>
         | 
| @@ -33,10 +33,10 @@ dependencies: | |
| 33 33 | 
             
                    version: '2.2'
         | 
| 34 34 | 
             
              type: :development
         | 
| 35 35 | 
             
              prerelease: false
         | 
| 36 | 
            -
              version_requirements: * | 
| 36 | 
            +
              version_requirements: *76418470
         | 
| 37 37 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 38 38 | 
             
              name: mocha
         | 
| 39 | 
            -
              requirement: & | 
| 39 | 
            +
              requirement: &76418120 !ruby/object:Gem::Requirement
         | 
| 40 40 | 
             
                none: false
         | 
| 41 41 | 
             
                requirements:
         | 
| 42 42 | 
             
                - - ! '>='
         | 
| @@ -44,10 +44,10 @@ dependencies: | |
| 44 44 | 
             
                    version: '0'
         | 
| 45 45 | 
             
              type: :development
         | 
| 46 46 | 
             
              prerelease: false
         | 
| 47 | 
            -
              version_requirements: * | 
| 47 | 
            +
              version_requirements: *76418120
         | 
| 48 48 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 49 49 | 
             
              name: rake
         | 
| 50 | 
            -
              requirement: & | 
| 50 | 
            +
              requirement: &76417650 !ruby/object:Gem::Requirement
         | 
| 51 51 | 
             
                none: false
         | 
| 52 52 | 
             
                requirements:
         | 
| 53 53 | 
             
                - - ! '>='
         | 
| @@ -55,10 +55,21 @@ dependencies: | |
| 55 55 | 
             
                    version: '0'
         | 
| 56 56 | 
             
              type: :development
         | 
| 57 57 | 
             
              prerelease: false
         | 
| 58 | 
            -
              version_requirements: * | 
| 58 | 
            +
              version_requirements: *76417650
         | 
| 59 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 60 | 
            +
              name: random_data
         | 
| 61 | 
            +
              requirement: &76417170 !ruby/object:Gem::Requirement
         | 
| 62 | 
            +
                none: false
         | 
| 63 | 
            +
                requirements:
         | 
| 64 | 
            +
                - - ! '>='
         | 
| 65 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 66 | 
            +
                    version: '0'
         | 
| 67 | 
            +
              type: :development
         | 
| 68 | 
            +
              prerelease: false
         | 
| 69 | 
            +
              version_requirements: *76417170
         | 
| 59 70 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 60 71 | 
             
              name: sqlite3
         | 
| 61 | 
            -
              requirement: & | 
| 72 | 
            +
              requirement: &76416820 !ruby/object:Gem::Requirement
         | 
| 62 73 | 
             
                none: false
         | 
| 63 74 | 
             
                requirements:
         | 
| 64 75 | 
             
                - - ! '>='
         | 
| @@ -66,10 +77,10 @@ dependencies: | |
| 66 77 | 
             
                    version: '0'
         | 
| 67 78 | 
             
              type: :development
         | 
| 68 79 | 
             
              prerelease: false
         | 
| 69 | 
            -
              version_requirements: * | 
| 80 | 
            +
              version_requirements: *76416820
         | 
| 70 81 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 71 82 | 
             
              name: activerecord
         | 
| 72 | 
            -
              requirement: & | 
| 83 | 
            +
              requirement: &76416030 !ruby/object:Gem::Requirement
         | 
| 73 84 | 
             
                none: false
         | 
| 74 85 | 
             
                requirements:
         | 
| 75 86 | 
             
                - - ~>
         | 
| @@ -77,7 +88,7 @@ dependencies: | |
| 77 88 | 
             
                    version: '3'
         | 
| 78 89 | 
             
              type: :development
         | 
| 79 90 | 
             
              prerelease: false
         | 
| 80 | 
            -
              version_requirements: * | 
| 91 | 
            +
              version_requirements: *76416030
         | 
| 81 92 | 
             
            description: Lightweight state machine extracted from ActiveModel
         | 
| 82 93 | 
             
            email: timo.roessner@googlemail.com
         | 
| 83 94 | 
             
            executables: []
         | 
| @@ -129,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 129 140 | 
             
                  version: '0'
         | 
| 130 141 | 
             
                  segments:
         | 
| 131 142 | 
             
                  - 0
         | 
| 132 | 
            -
                  hash: - | 
| 143 | 
            +
                  hash: -1015670387
         | 
| 133 144 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 134 145 | 
             
              none: false
         | 
| 135 146 | 
             
              requirements:
         |