state-handler 0.0.3 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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