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 +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +32 -0
- data/Rakefile +7 -0
- data/examples/response.rb +10 -4
- data/lib/state-handler.rb +1 -1
- data/lib/state-handler/{mixin.rb → mixing.rb} +46 -8
- data/lib/state-handler/version.rb +1 -1
- data/spec/lib/state-handler/mixing_spec.rb +74 -7
- metadata +13 -26
- data/README +0 -0
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
[](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
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::
|
8
|
+
include StateHandler::Mixing
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
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,16 +1,18 @@
|
|
1
1
|
module StateHandler
|
2
|
-
module
|
2
|
+
module Mixing
|
3
3
|
def self.included(base)
|
4
4
|
base.extend ClassMethods
|
5
|
-
|
6
|
-
|
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
|
-
|
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
|
-
|
106
|
+
create(codes.first.values.first, codes.first.keys.first)
|
85
107
|
elsif block_given?
|
86
|
-
|
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
|
@@ -6,13 +6,16 @@ describe StateHandler::Mixing do
|
|
6
6
|
include StateHandler::Mixing
|
7
7
|
|
8
8
|
map do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
group :success do
|
10
|
+
code 200 => :enabled
|
11
|
+
code 400 => :false
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
:
|
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.
|
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-
|
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:
|
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:
|
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:
|
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/
|
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.
|
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
|