adhearsion 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gitignore +10 -0
  2. data/CHANGELOG +8 -0
  3. data/README.markdown +33 -0
  4. data/Rakefile +28 -68
  5. data/adhearsion.gemspec +19 -133
  6. data/app_generators/ahn/templates/Gemfile +0 -4
  7. data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +4 -16
  8. data/lib/adhearsion/cli.rb +17 -0
  9. data/lib/adhearsion/component_manager/component_tester.rb +1 -3
  10. data/lib/adhearsion/component_manager/spec_framework.rb +4 -10
  11. data/lib/adhearsion/foundation/object.rb +10 -0
  12. data/lib/adhearsion/version.rb +1 -1
  13. data/spec/ahn_command_spec.rb +284 -0
  14. data/spec/component_manager_spec.rb +292 -0
  15. data/spec/constants_spec.rb +8 -0
  16. data/spec/drb_spec.rb +65 -0
  17. data/spec/fixtures/dialplan.rb +3 -0
  18. data/spec/foundation/event_socket_spec.rb +168 -0
  19. data/spec/host_definitions_spec.rb +79 -0
  20. data/spec/initialization_spec.rb +163 -0
  21. data/spec/initializer/configuration_spec.rb +270 -0
  22. data/spec/initializer/loading_spec.rb +149 -0
  23. data/spec/initializer/paths_spec.rb +74 -0
  24. data/spec/logging_spec.rb +86 -0
  25. data/spec/relationship_properties_spec.rb +54 -0
  26. data/spec/silence.rb +10 -0
  27. data/spec/spec_helper.rb +101 -0
  28. data/spec/voip/asterisk/agi_server_spec.rb +473 -0
  29. data/spec/voip/asterisk/ami/ami_spec.rb +549 -0
  30. data/spec/voip/asterisk/ami/lexer/ami_fixtures.yml +30 -0
  31. data/spec/voip/asterisk/ami/lexer/lexer_story +291 -0
  32. data/spec/voip/asterisk/ami/lexer/lexer_story.rb +241 -0
  33. data/spec/voip/asterisk/ami/lexer/story_helper.rb +124 -0
  34. data/spec/voip/asterisk/ami/old_tests.rb +204 -0
  35. data/spec/voip/asterisk/ami/super_manager/super_manager_story +25 -0
  36. data/spec/voip/asterisk/ami/super_manager/super_manager_story.rb +15 -0
  37. data/spec/voip/asterisk/ami/super_manager/super_manager_story_helper.rb +5 -0
  38. data/spec/voip/asterisk/commands_spec.rb +2179 -0
  39. data/spec/voip/asterisk/config_file_generators/agents_spec.rb +251 -0
  40. data/spec/voip/asterisk/config_file_generators/queues_spec.rb +323 -0
  41. data/spec/voip/asterisk/config_file_generators/voicemail_spec.rb +306 -0
  42. data/spec/voip/asterisk/config_manager_spec.rb +127 -0
  43. data/spec/voip/asterisk/menu_command/calculated_match_spec.rb +109 -0
  44. data/spec/voip/asterisk/menu_command/matchers_spec.rb +97 -0
  45. data/spec/voip/call_routing_spec.rb +125 -0
  46. data/spec/voip/dialplan_manager_spec.rb +468 -0
  47. data/spec/voip/dsl/dialing_dsl_spec.rb +270 -0
  48. data/spec/voip/dsl/dispatcher_spec.rb +82 -0
  49. data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
  50. data/spec/voip/dsl/parser_spec.rb +69 -0
  51. data/spec/voip/freeswitch/basic_connection_manager_spec.rb +39 -0
  52. data/spec/voip/freeswitch/inbound_connection_manager_spec.rb +39 -0
  53. data/spec/voip/freeswitch/oes_server_spec.rb +9 -0
  54. data/spec/voip/numerical_string_spec.rb +61 -0
  55. data/spec/voip/phone_number_spec.rb +45 -0
  56. data/theatre-spec/dsl_examples/dynamic_stomp.rb +7 -0
  57. data/theatre-spec/dsl_examples/simple_before_call.rb +7 -0
  58. data/theatre-spec/dsl_spec.rb +43 -0
  59. data/theatre-spec/invocation_spec.rb +167 -0
  60. data/theatre-spec/namespace_spec.rb +125 -0
  61. data/theatre-spec/spec_helper.rb +37 -0
  62. data/theatre-spec/spec_helper_spec.rb +28 -0
  63. data/theatre-spec/theatre_class_spec.rb +150 -0
  64. metadata +171 -34
@@ -0,0 +1,30 @@
1
+ :login:
2
+ :standard:
3
+ :client:
4
+ Action: Login
5
+ Username: :string
6
+ Secret: :string
7
+ Events: {one_of: ["on", "off"]}
8
+ :success:
9
+ Response: Success
10
+ Message: Authentication accepted
11
+ :fail:
12
+ Response: Error
13
+ Message: Authentication failed
14
+
15
+ :errors:
16
+ :missing_action:
17
+ Response: Error
18
+ Message: Missing action in request
19
+
20
+ :pong:
21
+ :with_action_id:
22
+ ActionID: 1287381.1238
23
+ Response: Pong
24
+ :without_action_id:
25
+ Response: Pong
26
+ :with_extra_keys:
27
+ ActionID: 1287381.1238
28
+ Response: Pong
29
+ Blah: This is something arbitrary
30
+ Blahhh: something else arbitrary
@@ -0,0 +1,291 @@
1
+ Story: Lexing AMI
2
+
3
+ As an Adhearsion user
4
+ I want to lex the AMI protocol
5
+ So that I can control Asterisk asynchronously
6
+
7
+ UNCERTAINTIES:
8
+ - Are there any pairs with non-unique keys? Could Hash be blowing stuff away?
9
+
10
+ WHEN DOING INTEGRATION TESTS:
11
+ - Try sending it an originate with a bad priority, a timeout of -1... and other improper stuff.
12
+
13
+ Scenario: Lexing only the initial AMI version header
14
+
15
+ Given a new lexer
16
+ And a version header for AMI 1.0
17
+
18
+ When the buffer is lexed
19
+
20
+ Then the protocol should have lexed without syntax errors
21
+ And the version should be set to 1.0
22
+
23
+ Scenario: Lexing the initial AMI header and a login attempt
24
+
25
+ Given a new lexer
26
+ And a version header for AMI 1.0
27
+ And a normal login success with events
28
+
29
+ When the buffer is lexed
30
+
31
+ Then the protocol should have lexed without syntax errors
32
+ And 1 message should have been received
33
+
34
+ Scenario: Lexing the initial AMI header and then a Response:Follows section
35
+
36
+ Given a new lexer
37
+ And a version header for AMI 1.0
38
+ And a multi-line Response:Follows body of ragel_description
39
+
40
+ When the buffer is lexed
41
+
42
+ Then the protocol should have lexed without syntax errors
43
+ And the 'follows' body of 1 message received should equal ragel_description
44
+
45
+ Scenario: Lexing a Response:Follows section with no body
46
+
47
+ Given a new lexer
48
+ And a version header for AMI 1.0
49
+ And a multi-line Response:Follows body of empty_String
50
+
51
+ When the buffer is lexed
52
+
53
+ Then the protocol should have lexed without syntax errors
54
+ And the 'follows' body of 1 message received should equal empty_string
55
+
56
+ Scenario: Lexing a multi-line Response:Follows simulating the "core show channels" command
57
+
58
+ Given a new lexer
59
+ And a version header for AMI 1.0
60
+ Given a multi-line Response:Follows body of show_channels_from_wayne
61
+
62
+ When the buffer is lexed
63
+
64
+ Then the protocol should have lexed without syntax errors
65
+ And the 'follows' body of 1 message received should equal show_channels_from_wayne
66
+
67
+ Scenario: Lexing a multi-line Response:Follows simulating the "core show uptime" command
68
+
69
+ Given a new lexer
70
+ And a version header for AMI 1.0
71
+ Given a multi-line Response:Follows response simulating uptime
72
+
73
+ When the buffer is lexed
74
+
75
+ Then the protocol should have lexed without syntax errors
76
+ And the first message received should have the key "System uptime" with value "46 minutes, 30 seconds"
77
+
78
+
79
+ Scenario: Lexing a Response:Follows section which has a colon not on the first line
80
+
81
+ Given a new lexer
82
+ And a multi-line Response:Follows body of with_colon_after_first_line
83
+
84
+ When the buffer is lexed
85
+
86
+ Then the protocol should have lexed without syntax errors
87
+ And 1 message should have been received
88
+ And the 'follows' body of 1 message received should equal with_colon_after_first_line
89
+
90
+ Scenario: Lexing an immediate response with a colon in it.
91
+
92
+ Given a new lexer
93
+ And an immediate response with text "markq has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime), W:0, C:0, A:0, SL:0.0% within 0s\r\n No Members\r\n No Callers\r\n\r\n\r\n\r\n"
94
+
95
+ When the buffer is lexed
96
+
97
+ Then the protocol should have lexed without syntax errors
98
+ And 1 message should have been received
99
+ And 1 message should be an immediate response with text "markq has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime), W:0, C:0, A:0, SL:0.0% within 0s\r\n No Members\r\n No Callers"
100
+
101
+ Scenario: Lexing the initial AMI header and then an "Authentication Required" error.
102
+
103
+ Given a new lexer
104
+ And a version header for AMI 1.0
105
+ And an Authentication Required error
106
+
107
+ When the buffer is lexed
108
+
109
+ Then the protocol should have lexed without syntax errors
110
+
111
+ Scenario: Lexing the initial AMI header and then a Response:Follows section
112
+
113
+ Given a new lexer
114
+ And a version header for AMI 1.0
115
+ And a multi-line Response:Follows body of ragel_description
116
+ And a multi-line Response:Follows body of ragel_description
117
+
118
+ When the buffer is lexed
119
+
120
+ Then the protocol should have lexed without syntax errors
121
+ And the 'follows' body of 2 messages received should equal ragel_description
122
+
123
+ Scenario: Lexing a stanza without receiving an AMI header
124
+
125
+ Given a new lexer
126
+ And a normal login success with events
127
+
128
+ When the buffer is lexed
129
+
130
+ Then the protocol should have lexed without syntax errors
131
+ And 1 message should have been received
132
+
133
+ Scenario: Receiving an immediate response as soon as the socket is opened
134
+
135
+ Given a new lexer
136
+ And an immediate response with text "Immediate responses are so ridiculous"
137
+
138
+ When the buffer is lexed
139
+
140
+ Then the protocol should have lexed with no syntax errors
141
+ And 1 message should have been received
142
+ And 1 message should be an immediate response with text "Immediate responses are so ridiculous"
143
+
144
+ Scenario: Receiving an immediate message surrounded by real messages
145
+
146
+ Given a new lexer
147
+ And a normal login success with events
148
+ And an immediate response with text "No queues have been created."
149
+ And a normal login success with events
150
+
151
+ When the buffer is lexed
152
+
153
+ Then the protocol should have lexed without syntax errors
154
+ And 3 messages should have been received
155
+ And 1 message should be an immediate response with text "No queues have been created."
156
+
157
+ Scenario: Receiving a Pong after a simulated login
158
+
159
+ Given a new lexer
160
+ And a version header for AMI 1.0
161
+ And a normal login success with events
162
+ And a Pong response with an ActionID of randomness
163
+
164
+ When the buffer is lexed
165
+
166
+ Then the protocol should have lexed without syntax errors
167
+ And 2 messages should have been received
168
+
169
+ Scenario: Ten Pong responses in a row
170
+
171
+ Given a new lexer
172
+ And 5 Pong responses without an ActionID
173
+ And 5 Pong responses with an ActionID of randomness
174
+
175
+ When the buffer is lexed
176
+
177
+ Then the protocol should have lexed without syntax errors
178
+ And 10 messages should have been received
179
+
180
+ Scenario: A Pong with an ActionID
181
+
182
+ Given a new lexer
183
+ And a Pong response with an ActionID of 1224469850.61673
184
+
185
+ When the buffer is lexed
186
+
187
+ Then the first message received should have a key "ActionID" with value "1224469850.61673"
188
+
189
+ Scenario: A response containing a floating point value
190
+
191
+ Given a new lexer
192
+ And a custom stanza named "call"
193
+ And the custom stanza named "call" has key "ActionID" with value "1224469850.61673"
194
+ And the custom stanza named "call" has key "Uniqueid" with value "1173223225.10309"
195
+
196
+ When the custom stanza named "call" is added to the buffer
197
+ And the buffer is lexed
198
+
199
+ Then the 1st message received should have a key "Uniqueid" with value "1173223225.10309"
200
+
201
+ Scenario: Receiving a message with custom key/value pairs
202
+
203
+ Given a new lexer
204
+ And a custom stanza named "person"
205
+ And the custom stanza named "person" has key "ActionID" with value "1224469850.61673"
206
+ And the custom stanza named "person" has key "Name" with value "Jay Phillips"
207
+ And the custom stanza named "person" has key "Age" with value "21"
208
+ And the custom stanza named "person" has key "Location" with value "San Francisco, CA"
209
+ And the custom stanza named "person" has key "x-header" with value "<FooBAR>"
210
+ And the custom stanza named "person" has key "Channel" with value "IAX2/127.0.0.1/4569-9904"
211
+ And the custom stanza named "person" has key "I have spaces" with value "i have trailing padding "
212
+
213
+ When the custom stanza named "person" is added to the buffer
214
+ And the buffer is lexed
215
+
216
+ Then the protocol should have lexed without syntax errors
217
+ And the first message received should have a key "Name" with value "Jay Phillips"
218
+ And the first message received should have a key "ActionID" with value "1224469850.61673"
219
+ And the first message received should have a key "Name" with value "Jay Phillips"
220
+ And the first message received should have a key "Age" with value "21"
221
+ And the first message received should have a key "Location" with value "San Francisco, CA"
222
+ And the first message received should have a key "x-header" with value "<FooBAR>"
223
+ And the first message received should have a key "Channel" with value "IAX2/127.0.0.1/4569-9904"
224
+ And the first message received should have a key "I have spaces" with value "i have trailing padding "
225
+
226
+ Scenario: Executing a stanza that was partially received
227
+
228
+ Given a new lexer
229
+ And a normal login success with events split into two pieces
230
+
231
+ When the buffer is lexed
232
+
233
+ Then the protocol should have lexed without syntax errors
234
+ And 1 message should have been received
235
+
236
+ Scenario: Receiving an AMI error followed by a normal event
237
+
238
+ Given a new lexer
239
+ And an AMI error whose message is "Missing action in request"
240
+ And a normal login success with events
241
+
242
+ When the buffer is lexed
243
+
244
+ Then the protocol should have lexed without syntax errors
245
+ And 1 AMI error should have been received
246
+ And the 1st AMI error should have the message "Missing action in request"
247
+ And 1 message should have been received
248
+
249
+ Scenario: Lexing an immediate response
250
+
251
+ Given a new lexer
252
+ And a normal login success with events
253
+ And an immediate response with text "Yes, plain English is sent sometimes over AMI."
254
+ And a normal login success with events
255
+
256
+ When the buffer is lexed
257
+
258
+ Then the protocol should have lexed without syntax errors
259
+ And 3 messages should have been received
260
+ And 1 message should be an immediate response with text "Yes, plain English is sent sometimes over AMI."
261
+
262
+ Scenario: Lexing an AMI event
263
+
264
+ Given a new lexer
265
+ And a custom event with name "NewChannelEvent" identified by "this_event"
266
+ And a custom header for event identified by "this_event" whose key is "Foo" and value is "Bar"
267
+ And a custom header for event identified by "this_event" whose key is "Channel" and value is "IAX2/127.0.0.1:4569-9904"
268
+ And a custom header for event identified by "this_event" whose key is "AppData" and value is "agi://localhost"
269
+
270
+ When the custom event identified by "this_event" is added to the buffer
271
+ And the buffer is lexed
272
+
273
+ Then the protocol should have lexed without syntax errors
274
+ And 1 event should have been received
275
+ And the 1st event should have the name "NewChannelEvent"
276
+ And the 1st event should have key "Foo" with value "Bar"
277
+ And the 1st event should have key "Channel" with value "IAX2/127.0.0.1:4569-9904"
278
+ And the 1st event should have key "AppData" with value "agi://localhost"
279
+
280
+ Scenario: Lexing an immediate packet with a colon in it (syntax error)
281
+
282
+ Given a new lexer
283
+ And syntactically invalid immediate_packet_with_colon
284
+ And a stanza break
285
+
286
+ When the buffer is lexed
287
+
288
+ Then 0 messages should have been received
289
+ And the protocol should have lexed with 1 syntax error
290
+ And the syntax error fixture named immediate_packet_with_colon should have been encountered
291
+
@@ -0,0 +1,241 @@
1
+ require File.dirname(__FILE__) + "/story_helper"
2
+
3
+ class IntrospectiveManagerStreamLexer < Adhearsion::VoIP::Asterisk::Manager::AbstractAsteriskManagerInterfaceStreamLexer
4
+
5
+ attr_reader :received_messages, :syntax_errors, :ami_errors
6
+ def initialize(*args)
7
+ super
8
+ @received_messages = []
9
+ @syntax_errors = []
10
+ @ami_errors = []
11
+ end
12
+
13
+ def message_received(message=@current_message)
14
+ @received_messages << message
15
+ end
16
+
17
+ def error_received(error_message)
18
+ @ami_errors << error_message
19
+ end
20
+
21
+ def syntax_error_encountered(ignored_chunk)
22
+ @syntax_errors << ignored_chunk
23
+ end
24
+
25
+ end
26
+
27
+ steps_for :ami_lexer do
28
+
29
+ ########################################
30
+ #### GIVEN
31
+ ########################################
32
+
33
+ Given "a new lexer" do
34
+ @lexer = IntrospectiveManagerStreamLexer.new
35
+ @custom_stanzas = {}
36
+ @custom_events = {}
37
+
38
+ @GivenPong = lambda do |with_or_without, action_id, number|
39
+ number = number == "a" ? 1 : number.to_i
40
+ data = case with_or_without
41
+ when "with" then "Response: Pong\r\nActionID: #{action_id}\r\n\r\n"
42
+ when "without" then "Response: Pong\r\n\r\n"
43
+ else raise "Do not recognize preposition #{with_or_without.inspect}. Should be either 'with' or 'without'"
44
+ end
45
+ number.times do
46
+ @lexer << data
47
+ end
48
+ end
49
+ end
50
+
51
+ Given "a version header for AMI $version" do |version|
52
+ @lexer << "Asterisk Call Manager/1.0\r\n"
53
+ end
54
+
55
+ Given "a normal login success with events" do
56
+ @lexer << fixture('login/standard/success')
57
+ end
58
+
59
+ Given "a normal login success with events split into two pieces" do
60
+ stanza = fixture('login/standard/success')
61
+ @lexer << stanza[0...3]
62
+ @lexer << stanza[3..-1]
63
+ end
64
+
65
+ Given "a stanza break" do
66
+ @lexer << "\r\n\r\n"
67
+ end
68
+
69
+ Given "a multi-line Response:Follows body of $method_name" do |method_name|
70
+ multi_line_response_body = send(:follows_body_text, method_name)
71
+
72
+ multi_line_response = format_newlines(<<-RESPONSE + "\r\n") % multi_line_response_body
73
+ Response: Follows\r
74
+ Privilege: Command\r
75
+ ActionID: 123123\r
76
+ %s\r
77
+ --END COMMAND--\r\n\r
78
+ RESPONSE
79
+
80
+ @lexer << multi_line_response
81
+ end
82
+
83
+ Given "a multi-line Response:Follows response simulating uptime" do |method_name|
84
+ uptime_response = "Response: Follows\r
85
+ Privilege: Command\r
86
+ System uptime: 46 minutes, 30 seconds\r
87
+ --END COMMAND--\r\n\r\n"
88
+ @lexer << uptime_response
89
+ end
90
+
91
+ Given "syntactically invalid $name" do |name|
92
+ @lexer << send(:syntax_error_data, name)
93
+ end
94
+
95
+ Given "$number Pong responses? with an ActionID of $action_id" do |number, action_id|
96
+ @GivenPong.call "with", action_id, number
97
+ end
98
+
99
+ Given "$number Pong responses? without an ActionID" do |number|
100
+ @GivenPong.call "without", Time.now.to_f, number
101
+ end
102
+
103
+ Given 'a custom stanza named "$name"' do |name|
104
+ @custom_stanzas[name] = "Response: Success\r\n"
105
+ end
106
+
107
+ Given 'the custom stanza named "$name" has key "$key" with value "$value"' do |name,key,value|
108
+ @custom_stanzas[name] << "#{key}: #{value}\r\n"
109
+ end
110
+
111
+ Given 'an AMI error whose message is "$message"' do |message|
112
+ @lexer << "Response: Error\r\nMessage: #{message}\r\n\r\n"
113
+ end
114
+
115
+ Given 'an immediate response with text "$text"' do |text|
116
+ @lexer << "#{text}\r\n\r\n"
117
+ end
118
+
119
+ Given 'a custom event with name "$event_name" identified by "$identifier"' do |event_name, identifer|
120
+ @custom_events[identifer] = {:Event => event_name }
121
+ end
122
+
123
+ Given 'a custom header for event identified by "$identifier" whose key is "$key" and value is "$value"' do |identifier, key, value|
124
+ @custom_events[identifier][key] = value
125
+ end
126
+
127
+ Given "an Authentication Required error" do
128
+ @lexer << "Response: Error\r\nActionID: BPJeKqW2-SnVg-PyFs-vkXT-7AWVVPD0N3G7\r\nMessage: Authentication Required\r\n\r\n"
129
+ end
130
+
131
+ Given "a follows packet with a colon in it" do
132
+ @lexer << follows_body_text("with_colon")
133
+ end
134
+
135
+ ########################################
136
+ #### WHEN
137
+ ########################################
138
+
139
+ When 'the custom stanza named "$name" is added to the buffer' do |name|
140
+ @lexer << (@custom_stanzas[name] + "\r\n")
141
+ end
142
+
143
+ When 'the custom event identified by "$identifier" is added to the buffer' do |identifier|
144
+ custom_event = @custom_events[identifier].clone
145
+ event_name = custom_event.delete :Event
146
+ stringified_event = "Event: #{event_name}\r\n"
147
+ custom_event.each_pair do |key,value|
148
+ stringified_event << "#{key}: #{value}\r\n"
149
+ end
150
+ stringified_event << "\r\n"
151
+ @lexer << stringified_event
152
+ end
153
+
154
+ When "the buffer is lexed" do
155
+ @lexer.resume!
156
+ end
157
+
158
+ ########################################
159
+ #### THEN
160
+ ########################################
161
+
162
+ Then "the protocol should have lexed without syntax errors" do
163
+ current_pointer = @lexer.send(:instance_variable_get, :@current_pointer)
164
+ data_ending_pointer = @lexer.send(:instance_variable_get, :@data_ending_pointer)
165
+ current_pointer.should equal(data_ending_pointer)
166
+ @lexer.syntax_errors.size.should equal(0)
167
+ end
168
+
169
+ Then "the protocol should have lexed with $number syntax errors?" do |number|
170
+ @lexer.syntax_errors.size.should equal(number.to_i)
171
+ end
172
+
173
+ Then "the syntax error fixture named $name should have been encountered" do |name|
174
+ irregularity = send(:syntax_error_data, name)
175
+ @lexer.syntax_errors.find { |error| error == irregularity }.should_not be_nil
176
+ end
177
+
178
+ Then "$number_received messages? should have been received" do |number_received|
179
+ @lexer.received_messages.size.should equal(number_received.to_i)
180
+ end
181
+
182
+ Then "the 'follows' body of $number messages? received should equal $method_name" do |number, method_name|
183
+ multi_line_response = follows_body_text method_name
184
+ @lexer.received_messages.should_not be_empty
185
+ @lexer.received_messages.select do |message|
186
+ message.text_body == multi_line_response
187
+ end.size.should eql(number.to_i)
188
+ end
189
+
190
+ Then "the version should be set to $version" do |version|
191
+ @lexer.ami_version.should eql(version.to_f)
192
+ end
193
+
194
+ Then 'the $ordered message received should have a key "$key" with value "$value"' do |ordered,key,value|
195
+ ordered = ordered[/^(\d+)\w+$/, 1].to_i - 1
196
+ @lexer.received_messages[ordered][key].should eql(value)
197
+ end
198
+
199
+ Then "$number AMI error should have been received" do |number|
200
+ @lexer.ami_errors.size.should equal(number.to_i)
201
+ end
202
+
203
+ Then 'the $order AMI error should have the message "$message"' do |order, message|
204
+ order = order[/^(\d+)\w+$/, 1].to_i - 1
205
+ @lexer.ami_errors[order].should be_kind_of(Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceError)
206
+ @lexer.ami_errors[order].message.should eql(message)
207
+ end
208
+
209
+ Then '$number message should be an immediate response with text "$text"' do |number, text|
210
+ matching_immediate_responses = @lexer.received_messages.select do |response|
211
+ response.kind_of?(Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceResponse) && response.text_body == text
212
+ end
213
+ matching_immediate_responses.size.should equal(number.to_i)
214
+ matching_immediate_responses.first["ActionID"].should eql(nil)
215
+ end
216
+
217
+ Then 'the $order event should have the name "$name"' do |order, name|
218
+ order = order[/^(\d+)\w+$/, 1].to_i - 1
219
+ @lexer.received_messages.select do |response|
220
+ response.kind_of?(Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceEvent)
221
+ end[order].name.should eql(name)
222
+ end
223
+
224
+ Then '$number event should have been received' do |number|
225
+ @lexer.received_messages.select do |response|
226
+ response.kind_of?(Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceEvent)
227
+ end.size.should equal(number.to_i)
228
+ end
229
+
230
+ Then 'the $order event should have key "$key" with value "$value"' do |order, key, value|
231
+ order = order[/^(\d+)\w+$/, 1].to_i - 1
232
+ @lexer.received_messages.select do |response|
233
+ response.kind_of?(Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceEvent)
234
+ end[order][key].should eql(value)
235
+ end
236
+
237
+ end
238
+
239
+ with_steps_for(:ami_lexer) do
240
+ run File.dirname(__FILE__) + "/lexer_story"
241
+ end