state-handler 0.0.3 → 0.1.1

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/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- state-handler (0.0.2)
4
+ state-handler (0.0.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ [![Build Status](https://secure.travis-ci.org/fatum/state-handler.png)](http://travis-ci.org/fatum/state-handler)
2
+
3
+ # StateHandler
4
+
5
+ This is a gem for adding state-based behavior for objects.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'state-handler'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install state-handler
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
32
+
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
data/examples/response.rb CHANGED
@@ -5,11 +5,17 @@ require 'ostruct'
5
5
  require 'state-handler'
6
6
 
7
7
  class ResponseHandler
8
- include StateHandler::Mixin
8
+ include StateHandler::Mixing
9
9
 
10
- code 200 => :success
11
- code 404 => :not_found
12
- code 401 => :unauthorized
10
+ group :success do
11
+ code 200 => :success
12
+ code 302 => :already_added
13
+ end
14
+
15
+ group :pass do
16
+ code 404 => :not_found
17
+ code 401 => :unauthorized
18
+ end
13
19
 
14
20
  match /5\d\d/ => :error
15
21
  end
data/lib/state-handler.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'state-handler/version'
2
- require 'state-handler/mixin'
2
+ require 'state-handler/mixing'
3
3
 
4
4
  module StateHandler
5
5
  class UnexpectedState < Exception
@@ -1,16 +1,18 @@
1
1
  module StateHandler
2
- module Mixin
2
+ module Mixing
3
3
  def self.included(base)
4
4
  base.extend ClassMethods
5
- base.class_attribute :mapping, :patterns
6
- base.mapping, base.patterns = {}, {}
5
+ %w{mapping patterns groups}.each do |attr|
6
+ base.class_attribute attr.to_sym
7
+ base.send "#{attr}=", {}
8
+ end
7
9
  end
8
10
 
9
11
  attr_reader :response
10
12
 
11
13
  def initialize(response, &block)
12
14
  raise ArgumentError unless response.respond_to?(:code)
13
- @response, @blocks = response, {}
15
+ @response, @blocks, @excludes = response, {}, {}
14
16
  exec(&block) if block_given?
15
17
  end
16
18
 
@@ -18,19 +20,33 @@ module StateHandler
18
20
  # map blocks
19
21
  yield(self)
20
22
 
21
- if state
23
+ if state && @blocks[state]
22
24
  @blocks[state].call
23
- else
25
+ end
26
+
27
+ if self.class.patterns
24
28
  self.class.patterns.each do |s, regex|
25
29
  @blocks[s].call if @response.code.to_s =~ regex
26
30
  end
27
31
  end
32
+
33
+ if self.class.groups
34
+ self.class.groups.each do |group, states|
35
+ @blocks[group].call if states.include?(state) && @blocks[group]
36
+ end
37
+ end
38
+
39
+ @excludes.each { |s, callback| callback.call unless s == state }
28
40
  end
29
41
 
30
42
  def at(*args, &block)
31
43
  args.each { |s| @blocks[s.to_sym] = block }
32
44
  end
33
45
 
46
+ def ex(*args, &block)
47
+ args.each { |s| @excludes[s.to_sym] = block }
48
+ end
49
+
34
50
  def state
35
51
  self.class.mapping.keys.each.find { |state| find_mapped(state) }
36
52
  end
@@ -54,6 +70,7 @@ module StateHandler
54
70
  end
55
71
  end
56
72
 
73
+ private
57
74
  module ClassMethods
58
75
  def class_attribute(*attrs)
59
76
  attrs.each do |name|
@@ -72,6 +89,8 @@ module StateHandler
72
89
  end
73
90
 
74
91
  def map(&block)
92
+ # TODO: refactor
93
+ # Create Dsl class
75
94
  class_eval(&block)
76
95
  end
77
96
 
@@ -79,11 +98,30 @@ module StateHandler
79
98
  self.patterns[regexp.values.first] = regexp.keys.first
80
99
  end
81
100
 
101
+ def method_missing
102
+ end
103
+
82
104
  def code(*codes, &block)
83
105
  if codes.first.kind_of?(Hash)
84
- self.mapping[codes.first.values.first] = codes.first.keys.first
106
+ create(codes.first.values.first, codes.first.keys.first)
85
107
  elsif block_given?
86
- self.mapping[yield] = codes
108
+ create(yield, codes)
109
+ end
110
+ end
111
+
112
+ def group(name, &block)
113
+ @current_group = name.to_sym
114
+ class_eval(&block)
115
+ @current_group = nil
116
+ end
117
+
118
+ private
119
+ def create(state, value)
120
+ raise ArgumentError, "State '#{state}' already defined" if self.mapping[state]
121
+ self.mapping[state] = value
122
+ if @current_group
123
+ self.groups[@current_group] ||= []
124
+ self.groups[@current_group] << state
87
125
  end
88
126
  end
89
127
  end
@@ -1,3 +1,3 @@
1
1
  module StateHandler
2
- VERSION = '0.0.3'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -6,13 +6,16 @@ describe StateHandler::Mixing do
6
6
  include StateHandler::Mixing
7
7
 
8
8
  map do
9
- code 200 => :enabled
10
- code 400 => :false
11
-
12
- match /5\d\d/ => :error
9
+ group :success do
10
+ code 200 => :enabled
11
+ code 400 => :false
12
+ end
13
13
 
14
- code 401, 402 do
15
- :bad_params
14
+ group :errors do
15
+ match /5\d\d/ => :error
16
+ code 401, 402 do
17
+ :bad_params
18
+ end
16
19
  end
17
20
  end
18
21
  end
@@ -24,6 +27,47 @@ describe StateHandler::Mixing do
24
27
  end
25
28
  end
26
29
  end
30
+
31
+ describe "#exclude" do
32
+ it "should call valid block" do
33
+ expect {
34
+ DummyResponse.new(OpenStruct.new(:code => 400)) do |r|
35
+ r.ex :bad_params do
36
+ raise ArgumentError
37
+ end
38
+ end
39
+ }.should raise_error(ArgumentError)
40
+ end
41
+
42
+ it "should not call block" do
43
+ expect {
44
+ DummyResponse.new(OpenStruct.new(:code => 401)) do |r|
45
+ r.ex :bad_params do
46
+ raise ArgumentError
47
+ end
48
+ end
49
+ }.should_not raise_error
50
+ end
51
+ end
52
+
53
+ describe "fails" do
54
+ context "when handler not matched" do
55
+ it "should do nothing" do
56
+ expect {
57
+ DummyResponse.new(OpenStruct.new(:code => 4001)) { }
58
+ }.should_not raise_error
59
+ end
60
+ end
61
+
62
+ context "when no handlers" do
63
+ it "should do nothing" do
64
+ expect {
65
+ DummyResponse.new(OpenStruct.new(:code => 401)) { }
66
+ }.should_not raise_error
67
+ end
68
+ end
69
+ end
70
+
27
71
  subject {
28
72
  DuplicateDeclarationResponse.new(response_struct)
29
73
  DummyResponse.new(response_struct)
@@ -45,6 +89,30 @@ describe StateHandler::Mixing do
45
89
  }.should raise_error(ExecException)
46
90
  end
47
91
 
92
+ describe "#group" do
93
+ let(:response_struct) { OpenStruct.new(:code => 200) }
94
+
95
+ it "should call block from excluded group :errors" do
96
+ expect {
97
+ subject.exec do |r|
98
+ r.ex :errors do
99
+ raise ExecException
100
+ end
101
+ end
102
+ }.should raise_error(ExecException)
103
+ end
104
+
105
+ it "should call block mapped to group :success" do
106
+ expect {
107
+ subject.exec do |r|
108
+ r.success do
109
+ raise ExecException
110
+ end
111
+ end
112
+ }.should raise_error(ExecException)
113
+ end
114
+ end
115
+
48
116
  describe "#match" do
49
117
  let(:response_struct) { OpenStruct.new(:code => 500) }
50
118
  it "should call matched block" do
@@ -80,7 +148,6 @@ describe StateHandler::Mixing do
80
148
 
81
149
  describe "#codes" do
82
150
  let(:response_struct) { OpenStruct.new(:code => 401) }
83
-
84
151
  its(:bad_params?) { should be_true }
85
152
  end
86
153
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: state-handler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-18 00:00:00.000000000 Z
12
+ date: 2012-05-16 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: !ruby/object:Gem::Requirement
16
+ requirement: &70195101020240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,15 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
24
+ version_requirements: *70195101020240
30
25
  - !ruby/object:Gem::Dependency
31
26
  name: rspec
32
- requirement: !ruby/object:Gem::Requirement
27
+ requirement: &70195101018660 !ruby/object:Gem::Requirement
33
28
  none: false
34
29
  requirements:
35
30
  - - ! '>='
@@ -37,15 +32,10 @@ dependencies:
37
32
  version: '0'
38
33
  type: :development
39
34
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '0'
35
+ version_requirements: *70195101018660
46
36
  - !ruby/object:Gem::Dependency
47
37
  name: timecop
48
- requirement: !ruby/object:Gem::Requirement
38
+ requirement: &70195101006480 !ruby/object:Gem::Requirement
49
39
  none: false
50
40
  requirements:
51
41
  - - ! '>='
@@ -53,12 +43,7 @@ dependencies:
53
43
  version: '0'
54
44
  type: :development
55
45
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
46
+ version_requirements: *70195101006480
62
47
  description: State handler per object params
63
48
  email: fatumka@gmail.com
64
49
  executables: []
@@ -67,12 +52,14 @@ extra_rdoc_files: []
67
52
  files:
68
53
  - .gitignore
69
54
  - .rspec
55
+ - .travis.yml
70
56
  - Gemfile
71
57
  - Gemfile.lock
72
- - README
58
+ - README.md
59
+ - Rakefile
73
60
  - examples/response.rb
74
61
  - lib/state-handler.rb
75
- - lib/state-handler/mixin.rb
62
+ - lib/state-handler/mixing.rb
76
63
  - lib/state-handler/version.rb
77
64
  - spec/lib/state-handler/mixing_spec.rb
78
65
  - spec/spec_helper.rb
@@ -97,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
84
  version: '0'
98
85
  requirements: []
99
86
  rubyforge_project:
100
- rubygems_version: 1.8.24
87
+ rubygems_version: 1.8.10
101
88
  signing_key:
102
89
  specification_version: 3
103
90
  summary: State handler per object params
data/README DELETED
File without changes