message_router 0.0.1 → 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/Gemfile.lock +12 -20
- data/Guardfile +1 -1
- data/README.rdoc +8 -8
- data/Rakefile +14 -23
- data/lib/message_router.rb +17 -6
- data/lib/message_router/matcher.rb +4 -4
- data/lib/message_router/version.rb +1 -1
- data/spec/message_router_spec.rb +31 -18
- metadata +4 -5
- data/.document +0 -5
data/Gemfile.lock
CHANGED
@@ -1,34 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
message_router (0.0.
|
4
|
+
message_router (0.0.2)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
8
8
|
specs:
|
9
|
-
configuration (1.2.0)
|
10
9
|
diff-lcs (1.1.2)
|
11
10
|
growl (1.0.3)
|
12
|
-
guard (0.
|
13
|
-
open_gem (~> 1.4.2)
|
11
|
+
guard (0.5.1)
|
14
12
|
thor (~> 0.14.6)
|
15
|
-
guard-rspec (0.
|
16
|
-
guard (>= 0.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
rspec (2.5.0)
|
25
|
-
rspec-core (~> 2.5.0)
|
26
|
-
rspec-expectations (~> 2.5.0)
|
27
|
-
rspec-mocks (~> 2.5.0)
|
28
|
-
rspec-core (2.5.1)
|
29
|
-
rspec-expectations (2.5.0)
|
13
|
+
guard-rspec (0.4.0)
|
14
|
+
guard (>= 0.4.0)
|
15
|
+
rb-fsevent (0.4.2)
|
16
|
+
rspec (2.6.0)
|
17
|
+
rspec-core (~> 2.6.0)
|
18
|
+
rspec-expectations (~> 2.6.0)
|
19
|
+
rspec-mocks (~> 2.6.0)
|
20
|
+
rspec-core (2.6.4)
|
21
|
+
rspec-expectations (2.6.0)
|
30
22
|
diff-lcs (~> 1.1.2)
|
31
|
-
rspec-mocks (2.
|
23
|
+
rspec-mocks (2.6.0)
|
32
24
|
thor (0.14.6)
|
33
25
|
|
34
26
|
PLATFORMS
|
data/Guardfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
|
-
guard 'rspec', :version => 2, :notification => true do
|
4
|
+
guard 'rspec', :version => 2, :cli => '--colour', :notification => true do
|
5
5
|
watch(%r{^spec/.+_spec\.rb})
|
6
6
|
watch(%r{^lib/(.+)\.rb}) { |m| "spec/message_router_spec.rb" }
|
7
7
|
watch(/^spec\/spec_helper.rb/) { "spec" }
|
data/README.rdoc
CHANGED
@@ -44,14 +44,14 @@ This is a contrived example for a Twitter message router, but it gives you an id
|
|
44
44
|
|
45
45
|
And now some irb action.
|
46
46
|
|
47
|
-
>> TwitterRouter.new(
|
48
|
-
=> "pleased to meet you"
|
49
|
-
>> TwitterRouter.new(
|
50
|
-
=> "how do you do brad"
|
51
|
-
>> TwitterRouter.new(
|
52
|
-
=> "STOP SHOUTING WITH NUMBERS!"
|
53
|
-
>> TwitterRouter.new(
|
54
|
-
=> "STOP SHOUTING WITHOUT NUMBERS!"
|
47
|
+
>> TwitterRouter.new(:body => 'hi dude').dispatch
|
48
|
+
=> {:body => "pleased to meet you"}
|
49
|
+
>> TwitterRouter.new(:body => 'hi brad').dispatch
|
50
|
+
=> {:body => "how do you do brad"}
|
51
|
+
>> TwitterRouter.new(:body => 'HI BRAD 90').dispatch
|
52
|
+
=> {:body => "STOP SHOUTING WITH NUMBERS!"}
|
53
|
+
>> TwitterRouter.new(:body => 'HI BRAD').dispatch
|
54
|
+
=> {:body => "STOP SHOUTING WITHOUT NUMBERS!"}
|
55
55
|
|
56
56
|
== License
|
57
57
|
|
data/Rakefile
CHANGED
@@ -1,27 +1,18 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
|
-
|
2
|
+
require 'rspec/core/rake_task'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
# spec.spec_files = FileList['spec/**/*_spec.rb']
|
7
|
-
# end
|
4
|
+
desc 'Default: run specs.'
|
5
|
+
task :default => :spec
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
|
7
|
+
desc "Run specs"
|
8
|
+
RSpec::Core::RakeTask.new do |t|
|
9
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
10
|
+
# Put spec opts in a file named .rspec in root
|
11
|
+
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
22
|
-
|
23
|
-
# rdoc.rdoc_dir = 'rdoc'
|
24
|
-
# rdoc.title = "message_router #{version}"
|
25
|
-
# rdoc.rdoc_files.include('README*')
|
26
|
-
# rdoc.rdoc_files.include('lib/**/*.rb')
|
27
|
-
# end
|
13
|
+
desc "Generate code coverage"
|
14
|
+
RSpec::Core::RakeTask.new(:coverage) do |t|
|
15
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
16
|
+
t.rcov = true
|
17
|
+
t.rcov_opts = ['--exclude', 'spec']
|
18
|
+
end
|
data/lib/message_router.rb
CHANGED
@@ -27,20 +27,20 @@ class MessageRouter
|
|
27
27
|
routes.push proc
|
28
28
|
end
|
29
29
|
|
30
|
-
def dispatch(
|
31
|
-
new(
|
30
|
+
def dispatch(*args)
|
31
|
+
new(*args).dispatch
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
attr_accessor :message, :halted_value
|
36
36
|
|
37
|
-
def initialize(
|
38
|
-
@message =
|
37
|
+
def initialize(*args)
|
38
|
+
@message = normalize_arguments(*args)
|
39
39
|
end
|
40
40
|
|
41
|
-
def halt(val=nil)
|
41
|
+
def halt(val=nil, opts={})
|
42
42
|
@halted = true
|
43
|
-
@halted_value = val
|
43
|
+
@halted_value = normalize_arguments(val, opts)
|
44
44
|
end
|
45
45
|
|
46
46
|
def halted?
|
@@ -59,4 +59,15 @@ class MessageRouter
|
|
59
59
|
end
|
60
60
|
return nil # If nothing is matched, we get here and we should return a nil
|
61
61
|
end
|
62
|
+
|
63
|
+
def default_key
|
64
|
+
:body
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
# Make our router accept the first argument as the default message key, then optional keys last.
|
69
|
+
def normalize_arguments(message=nil, opts={})
|
70
|
+
message = opts.merge(:body => message) unless message.is_a? Hash and opts.empty?
|
71
|
+
message
|
72
|
+
end
|
62
73
|
end
|
@@ -25,11 +25,11 @@ class MessageRouter
|
|
25
25
|
|
26
26
|
def call(router)
|
27
27
|
if match = match(router.message)
|
28
|
-
router.instance_exec(*match[self.class.
|
28
|
+
router.instance_exec(*match[self.class.default_key], &block)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def self.
|
32
|
+
def self.default_key
|
33
33
|
:body
|
34
34
|
end
|
35
35
|
|
@@ -38,11 +38,11 @@ class MessageRouter
|
|
38
38
|
|
39
39
|
def normalize_params(*args)
|
40
40
|
if args.size == 2
|
41
|
-
args.last.merge(self.class.
|
41
|
+
args.last.merge(self.class.default_key => args.first)
|
42
42
|
elsif args.size == 1 and args.first.is_a?(Hash)
|
43
43
|
args.first
|
44
44
|
elsif args.size == 1
|
45
|
-
{ self.class.
|
45
|
+
{ self.class.default_key => args.first }
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
data/spec/message_router_spec.rb
CHANGED
@@ -30,14 +30,14 @@ describe MessageRouter::Matcher do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should default matcher param to :body" do
|
33
|
-
MessageRouter::Matcher.
|
33
|
+
MessageRouter::Matcher.default_key.should eql(:body)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe MessageRouter do
|
38
38
|
class CrazyTimesRouter < MessageRouter
|
39
39
|
match /^crazy$/ do
|
40
|
-
"factory blow out sales are awesome"
|
40
|
+
halt "factory blow out sales are awesome"
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -45,25 +45,25 @@ describe MessageRouter do
|
|
45
45
|
class TwitterRouter < MessageRouter
|
46
46
|
context :all_caps_with_numbers do |funny_word, high_def_resolution|
|
47
47
|
match /FUNNYWORD/i do
|
48
|
-
"#{funny_word}-#{high_def_resolution}"
|
48
|
+
halt "#{funny_word}-#{high_def_resolution}"
|
49
49
|
end
|
50
50
|
|
51
51
|
# All caps without numbers... but in a proc
|
52
52
|
context Proc.new{|r| r.message[:body] =~ /^[A-Z\s]+$/ } do
|
53
53
|
match /.+/ do
|
54
|
-
"STOP SHOUTING WITHOUT NUMBERS!"
|
54
|
+
halt "STOP SHOUTING WITHOUT NUMBERS!"
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
match /.+/ do
|
59
|
-
"STOP SHOUTING WITH NUMBERS!"
|
59
|
+
halt "STOP SHOUTING WITH NUMBERS!"
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
63
|
mount CrazyTimesRouter
|
64
64
|
|
65
65
|
match /hi dude/ do
|
66
|
-
"pleased to meet you"
|
66
|
+
halt "pleased to meet you"
|
67
67
|
end
|
68
68
|
|
69
69
|
match /hi halt (\w+)/ do |word|
|
@@ -75,11 +75,11 @@ describe MessageRouter do
|
|
75
75
|
end
|
76
76
|
|
77
77
|
match /hi (\w+)/ do |name|
|
78
|
-
"how do you do #{name}"
|
78
|
+
halt "how do you do #{name}"
|
79
79
|
end
|
80
80
|
|
81
81
|
match /hola (\w+) (\w+)/, :from => 'bradgessler' do |first_name, last_name|
|
82
|
-
"hello #{first_name} #{last_name} in spanish"
|
82
|
+
halt "hello #{first_name} #{last_name} in spanish"
|
83
83
|
end
|
84
84
|
|
85
85
|
private
|
@@ -90,53 +90,66 @@ describe MessageRouter do
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
+
def dispatch(*args)
|
94
|
+
reply = TwitterRouter.dispatch(*args)
|
95
|
+
reply ? reply[:body] : nil
|
96
|
+
end
|
97
|
+
|
93
98
|
it "should return nil if there are no matches" do
|
94
|
-
|
99
|
+
dispatch("bums").should be_nil
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should have default key" do
|
103
|
+
TwitterRouter.new.default_key.should eql(:body)
|
95
104
|
end
|
96
105
|
|
97
106
|
context "mounted router" do
|
98
107
|
it "should process message" do
|
99
|
-
|
108
|
+
dispatch("crazy").should eql("factory blow out sales are awesome")
|
100
109
|
end
|
101
110
|
end
|
102
111
|
|
103
112
|
context "should halt" do
|
104
113
|
it "without value" do
|
105
|
-
|
114
|
+
dispatch("hi halt").should be_nil
|
106
115
|
end
|
107
116
|
|
108
117
|
it "with value" do
|
109
|
-
|
118
|
+
dispatch("hi halt narf").should eql("narf")
|
110
119
|
end
|
111
120
|
end
|
112
121
|
|
113
122
|
context "default matcher" do
|
114
123
|
it "should capture regexps" do
|
115
|
-
|
124
|
+
dispatch('hi dude').should eql('pleased to meet you')
|
116
125
|
end
|
117
126
|
|
118
127
|
it "should pass regexp captures through blocks" do
|
119
|
-
|
128
|
+
dispatch('hi brad').should eql("how do you do brad")
|
120
129
|
end
|
121
130
|
end
|
122
131
|
|
123
132
|
context "hash matcher" do
|
124
133
|
it "should capture with default matcher" do
|
125
|
-
|
134
|
+
dispatch('hola jeannette gessler', :from => 'bradgessler').should eql("hello jeannette gessler in spanish")
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should capture with an explicit hash" do
|
138
|
+
dispatch(:body => 'hola jeannette gessler', :from => 'bradgessler').should eql("hello jeannette gessler in spanish")
|
126
139
|
end
|
127
140
|
end
|
128
141
|
|
129
142
|
context "context" do
|
130
143
|
it "should handle contexts and non-proc conditions" do
|
131
|
-
|
144
|
+
dispatch('HI BRAD 90').should eql("STOP SHOUTING WITH NUMBERS!")
|
132
145
|
end
|
133
146
|
|
134
147
|
it "should handle nested contexts and proc conditions" do
|
135
|
-
|
148
|
+
dispatch('HI BRAD').should eql("STOP SHOUTING WITHOUT NUMBERS!")
|
136
149
|
end
|
137
150
|
|
138
151
|
it "should pass arguments into contexts" do
|
139
|
-
|
152
|
+
dispatch('FUNNYWORD').should eql("Zeldzamar-1080")
|
140
153
|
end
|
141
154
|
end
|
142
155
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: message_router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brad Gessler
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-08-02 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -29,7 +29,6 @@ extensions: []
|
|
29
29
|
extra_rdoc_files: []
|
30
30
|
|
31
31
|
files:
|
32
|
-
- .document
|
33
32
|
- .gitignore
|
34
33
|
- .rvmrc
|
35
34
|
- Gemfile
|