pipa-statelogic 0.0.2

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/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,13 @@
1
+ Statelogic
2
+ ==========
3
+
4
+ Introduction goes here.
5
+
6
+
7
+ Example
8
+ =======
9
+
10
+ Example goes here.
11
+
12
+
13
+ Copyright (c) 2009 Igor Gunko, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the statelogic plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the statelogic plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'Statelogic'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
@@ -0,0 +1 @@
1
+ require 'statelogic'
data/lib/statelogic.rb ADDED
@@ -0,0 +1 @@
1
+ # undisturbed void
@@ -0,0 +1,88 @@
1
+ require 'statelogic/callbacks_ext'
2
+
3
+ module Statelogic
4
+ module ActiveRecord
5
+ def self.included(other)
6
+ other.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ DEFAULT_OPTIONS = {:attribute => :state}.freeze
11
+
12
+ class StateScopeHelper
13
+ CALLBACKS = ::ActiveRecord::Callbacks::CALLBACKS.map(&:to_sym).to_set
14
+ MACROS_PATTERN = /\Avalidates_/
15
+
16
+ def initialize(cl, state, config)
17
+ @class, @state, @config, @conditions = cl, state, config, state.map {|x| :"#{x}?"}
18
+ end
19
+
20
+ def validates_transition_to(*states)
21
+ attr = @config[:attribute]
22
+ options = states.extract_options!.update(
23
+ :in => states,
24
+ :if => [:"#{attr}_changed?", :"was_#{@state}?"]
25
+ )
26
+ @class.validates_inclusion_of(attr, options)
27
+ end
28
+
29
+ alias transitions_to validates_transition_to
30
+
31
+ def method_missing(method, *args, &block)
32
+ if CALLBACKS.include?(method) || method.to_s =~ MACROS_PATTERN
33
+ options = args.last
34
+ args.push(options = {}) unless options.is_a?(Hash)
35
+ options[:if] = Array(options[:if]).unshift(@conditions)
36
+ @class.send(method, *args, &block)
37
+ else
38
+ super
39
+ end
40
+ end
41
+ end
42
+
43
+ class ConfigHelper
44
+ def initialize(cl, config)
45
+ @class, @config = cl, config
46
+ end
47
+
48
+ def initial_state(name, options = {}, &block)
49
+ state(name, options.update(:initial => true), &block)
50
+ end
51
+
52
+ def state(name, options = {}, &block)
53
+ attr = @config[:attribute]
54
+ attr_was = :"#{attr}_was"
55
+ @class.class_eval do
56
+ define_method("#{name}?") { send(attr) == name }
57
+ define_method("was_#{name}?") { send(attr_was) == name }
58
+ end
59
+
60
+ StateScopeHelper.new(@class, name, @config).instance_eval(&block)
61
+
62
+ @config[:states] << name
63
+ @config[:initial] << name if options[:initial]
64
+ end
65
+ end
66
+
67
+ def statelogic(options = {}, &block)
68
+ options = DEFAULT_OPTIONS.merge(options)
69
+ attr = options[:attribute] = options[:attribute].to_sym
70
+
71
+ options[:states], options[:initial] = [], Array(options[:initial])
72
+
73
+ ConfigHelper.new(self, options).instance_eval(&block)
74
+
75
+ initial = options[:initial]
76
+ validates_inclusion_of attr, :in => initial.to_set, :on => :create unless initial.blank?
77
+ #validates_inclusion_of attr, :in => options[:states].to_set
78
+
79
+ const = attr.to_s.pluralize.upcase
80
+ const_set(const, options[:states].freeze.each(&:freeze)) unless const_defined?(const)
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ class ActiveRecord::Base
87
+ include Statelogic::ActiveRecord
88
+ end
@@ -0,0 +1,6 @@
1
+ class ActiveSupport::Callbacks::Callback
2
+ def should_run_callback?(*args)
3
+ [options[:if]].flatten.compact.all? { |a| evaluate_method(a, *args) } &&
4
+ ![options[:unless]].flatten.compact.any? { |a| evaluate_method(a, *args) }
5
+ end
6
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'statelogic'
2
+ require 'statelogic/activerecord'
@@ -0,0 +1,12 @@
1
+ class Test::Unit::TestCase
2
+ def self.should_not_require_attributes(*attributes)
3
+ get_options!(attributes)
4
+ klass = model_class
5
+
6
+ attributes.each do |attribute|
7
+ should "not require #{attribute} to be set" do
8
+ assert_good_value(klass, attribute, nil)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+
3
+ unpaid:
4
+ state: unpaid
5
+
6
+ ready:
7
+ state: ready
8
+
9
+ redeemed:
10
+ state: redeemed
11
+
12
+ suspended:
13
+ state: suspended
data/test/schema.rb ADDED
@@ -0,0 +1,8 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table 'orders', :force => true do |t|
3
+ t.column 'state', :text
4
+ t.column 'redeemed_at', :datetime
5
+ t.column 'txref', :string
6
+ t.references :facility
7
+ end
8
+ end
@@ -0,0 +1,81 @@
1
+ require 'test_helper'
2
+
3
+ class Order < ActiveRecord::Base
4
+ statelogic do
5
+ initial_state 'unpaid' do
6
+ transitions_to 'ready', 'suspended'
7
+ end
8
+ state 'ready' do
9
+ transitions_to 'redeemed', 'suspended'
10
+ validates_presence_of :txref
11
+ end
12
+ state 'redeemed' do
13
+ transitions_to 'suspended'
14
+ validates_presence_of :txref, :redeemed_at, :facility_id
15
+ end
16
+ state 'suspended' do
17
+ transitions_to 'unpaid', 'ready', 'redeemed'
18
+ end
19
+ end
20
+ end
21
+
22
+ class OrderTest < ActiveSupport::TestCase
23
+ fixtures :orders
24
+
25
+ should_require_attributes :state, :message => default_error_message(:inclusion)
26
+
27
+ context 'A fresh order' do
28
+ setup do
29
+ @order = Order.new
30
+ end
31
+
32
+ should_allow_values_for :state, 'unpaid'
33
+ should_not_allow_values_for :state, 'ready', 'redeemed', 'suspended', 'screwed_up',
34
+ :message => default_error_message(:inclusion)
35
+ should_not_require_attributes :txref, :redeemed_at, :facility_id
36
+ end
37
+
38
+ context 'An unpaid order' do
39
+ setup do
40
+ @order = orders(:unpaid)
41
+ end
42
+
43
+ should_allow_values_for :state, 'unpaid', 'ready', 'suspended'
44
+ should_not_allow_values_for :state, 'redeemed', 'screwed_up',
45
+ :message => default_error_message(:inclusion)
46
+ should_not_require_attributes :txref, :redeemed_at, :facility_id
47
+ end
48
+
49
+ context 'A ready order' do
50
+ setup do
51
+ @order = orders(:ready)
52
+ end
53
+
54
+ should_allow_values_for :state, 'ready', 'redeemed', 'suspended'
55
+ should_not_allow_values_for :state, 'unpaid', 'screwed_up',
56
+ :message => default_error_message(:inclusion)
57
+ should_require_attributes :txref
58
+ should_not_require_attributes :redeemed_at, :facility_id
59
+ end
60
+
61
+ context 'A redeemed order' do
62
+ setup do
63
+ @order = orders(:redeemed)
64
+ end
65
+
66
+ should_allow_values_for :state, 'redeemed', 'suspended'
67
+ should_not_allow_values_for :state, 'unpaid', 'ready', 'screwed_up',
68
+ :message => default_error_message(:inclusion)
69
+ should_require_attributes :txref, :redeemed_at, :facility_id
70
+ end
71
+
72
+ context 'A suspended order' do
73
+ setup do
74
+ @order = orders(:suspended)
75
+ end
76
+
77
+ should_allow_values_for :state, 'suspended', 'redeemed', 'ready', 'unpaid'
78
+ should_not_allow_values_for :state, 'screwed_up', :message => default_error_message(:inclusion)
79
+ should_not_require_attributes :txref, :redeemed_at, :facility_id
80
+ end
81
+ end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_support'
4
+ require 'active_support/test_case'
5
+ require 'active_record'
6
+ require 'shoulda/active_record'
7
+ require 'active_record/fixtures'
8
+ require 'statelogic/activerecord'
9
+
10
+ require 'shoulda_macros/statelogic'
11
+
12
+ ActiveSupport::TestCase.fixture_path = 'test/fixtures'
13
+
14
+ ActiveRecord::Base.configurations = {
15
+ 'test' => {:adapter => 'sqlite3', :dbfile => ':memory:'}
16
+ }
17
+ ActiveRecord::Base.establish_connection(:test)
18
+
19
+ load 'schema.rb'
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pipa-statelogic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Igor Gunko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-06 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.2.2
23
+ version:
24
+ description: Statelogic does kinda this and that... you know.
25
+ email: tekmon@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README.rdoc
32
+ - MIT-LICENSE
33
+ files:
34
+ - README.rdoc
35
+ - MIT-LICENSE
36
+ - Rakefile
37
+ - lib/statelogic.rb
38
+ - lib/pipa-statelogic.rb
39
+ - lib/statelogic/activerecord.rb
40
+ - lib/statelogic/callbacks_ext.rb
41
+ - rails/init.rb
42
+ has_rdoc: true
43
+ homepage: http://github.com/pipa/statelogic
44
+ post_install_message:
45
+ rdoc_options:
46
+ - --line-numbers
47
+ - --inline-source
48
+ - --main
49
+ - README.rdoc
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.2.0
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: Another state machine for ActiveRecord
71
+ test_files:
72
+ - test/statelogic_test.rb
73
+ - test/test_helper.rb
74
+ - test/schema.rb
75
+ - test/fixtures/orders.yml
76
+ - shoulda_macros/statelogic.rb