adhearsion 2.0.0.beta1 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.travis.yml +2 -4
  2. data/CHANGELOG.md +34 -4
  3. data/README.markdown +2 -1
  4. data/Rakefile +22 -1
  5. data/adhearsion.gemspec +1 -0
  6. data/bin/ahn +0 -2
  7. data/features/cli_daemon.feature +2 -0
  8. data/features/cli_restart.feature +19 -0
  9. data/features/cli_start.feature +4 -6
  10. data/features/cli_stop.feature +3 -0
  11. data/features/step_definitions/app_generator_steps.rb +2 -0
  12. data/features/step_definitions/cli_steps.rb +2 -0
  13. data/features/support/aruba_helper.rb +2 -0
  14. data/features/support/env.rb +8 -46
  15. data/features/support/utils.rb +2 -0
  16. data/lib/adhearsion.rb +4 -6
  17. data/lib/adhearsion/call.rb +71 -17
  18. data/lib/adhearsion/call_controller.rb +25 -14
  19. data/lib/adhearsion/call_controller/dial.rb +34 -15
  20. data/lib/adhearsion/call_controller/input.rb +186 -144
  21. data/lib/adhearsion/call_controller/output.rb +10 -6
  22. data/lib/adhearsion/call_controller/record.rb +11 -13
  23. data/lib/adhearsion/call_controller/utility.rb +2 -0
  24. data/lib/adhearsion/calls.rb +4 -2
  25. data/lib/adhearsion/cli.rb +4 -0
  26. data/lib/adhearsion/cli_commands.rb +8 -2
  27. data/lib/adhearsion/configuration.rb +7 -3
  28. data/lib/adhearsion/console.rb +17 -17
  29. data/lib/adhearsion/events.rb +10 -4
  30. data/lib/adhearsion/foundation.rb +9 -0
  31. data/lib/adhearsion/foundation/custom_daemonizer.rb +3 -1
  32. data/lib/adhearsion/foundation/exception_handler.rb +2 -0
  33. data/lib/adhearsion/foundation/libc.rb +2 -0
  34. data/lib/adhearsion/foundation/object.rb +3 -0
  35. data/lib/adhearsion/foundation/thread_safety.rb +5 -11
  36. data/lib/adhearsion/generators.rb +2 -0
  37. data/lib/adhearsion/generators/app/app_generator.rb +2 -0
  38. data/lib/adhearsion/generators/app/templates/README.md +9 -0
  39. data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +38 -16
  40. data/lib/adhearsion/generators/app/templates/config/environment.rb +2 -0
  41. data/lib/adhearsion/generators/app/templates/lib/simon_game.rb +5 -3
  42. data/lib/adhearsion/generators/controller/controller_generator.rb +2 -0
  43. data/lib/adhearsion/generators/controller/templates/lib/controller.rb +2 -0
  44. data/lib/adhearsion/generators/controller/templates/spec/controller_spec.rb +2 -0
  45. data/lib/adhearsion/generators/generator.rb +3 -1
  46. data/lib/adhearsion/generators/plugin/plugin_generator.rb +2 -0
  47. data/lib/adhearsion/initializer.rb +31 -17
  48. data/lib/adhearsion/linux_proc_name.rb +2 -0
  49. data/lib/adhearsion/logging.rb +5 -3
  50. data/lib/adhearsion/menu_dsl.rb +2 -0
  51. data/lib/adhearsion/menu_dsl/calculated_match.rb +2 -0
  52. data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +2 -0
  53. data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +2 -0
  54. data/lib/adhearsion/menu_dsl/match_calculator.rb +2 -0
  55. data/lib/adhearsion/menu_dsl/menu.rb +58 -4
  56. data/lib/adhearsion/menu_dsl/menu_builder.rb +14 -1
  57. data/lib/adhearsion/menu_dsl/range_match_calculator.rb +4 -1
  58. data/lib/adhearsion/menu_dsl/string_match_calculator.rb +2 -0
  59. data/lib/adhearsion/outbound_call.rb +2 -0
  60. data/lib/adhearsion/plugin.rb +9 -7
  61. data/lib/adhearsion/plugin/collection.rb +3 -1
  62. data/lib/adhearsion/plugin/initializer.rb +3 -1
  63. data/lib/adhearsion/process.rb +8 -2
  64. data/lib/adhearsion/punchblock_plugin.rb +3 -1
  65. data/lib/adhearsion/punchblock_plugin/initializer.rb +34 -11
  66. data/lib/adhearsion/router.rb +4 -2
  67. data/lib/adhearsion/router/route.rb +2 -0
  68. data/lib/adhearsion/script_ahn_loader.rb +2 -0
  69. data/lib/adhearsion/tasks.rb +2 -0
  70. data/lib/adhearsion/tasks/configuration.rb +2 -0
  71. data/lib/adhearsion/tasks/debugging.rb +8 -0
  72. data/lib/adhearsion/tasks/environment.rb +2 -0
  73. data/lib/adhearsion/tasks/plugins.rb +2 -0
  74. data/lib/adhearsion/tasks/testing.rb +2 -0
  75. data/lib/adhearsion/version.rb +3 -1
  76. data/pre-commit +2 -0
  77. data/spec/adhearsion/call_controller/dial_spec.rb +114 -25
  78. data/spec/adhearsion/call_controller/input_spec.rb +192 -169
  79. data/spec/adhearsion/call_controller/output_spec.rb +26 -12
  80. data/spec/adhearsion/call_controller/record_spec.rb +29 -77
  81. data/spec/adhearsion/call_controller/utility_spec.rb +69 -0
  82. data/spec/adhearsion/call_controller_spec.rb +90 -15
  83. data/spec/adhearsion/call_spec.rb +92 -24
  84. data/spec/adhearsion/calls_spec.rb +9 -7
  85. data/spec/adhearsion/configuration_spec.rb +58 -56
  86. data/spec/adhearsion/console_spec.rb +4 -2
  87. data/spec/adhearsion/events_spec.rb +9 -7
  88. data/spec/adhearsion/generators_spec.rb +3 -1
  89. data/spec/adhearsion/initializer_spec.rb +16 -14
  90. data/spec/adhearsion/logging_spec.rb +11 -9
  91. data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +6 -4
  92. data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +6 -4
  93. data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +3 -1
  94. data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +2 -0
  95. data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +42 -11
  96. data/spec/adhearsion/menu_dsl/menu_spec.rb +197 -36
  97. data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +4 -2
  98. data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +5 -3
  99. data/spec/adhearsion/outbound_call_spec.rb +7 -5
  100. data/spec/adhearsion/plugin_spec.rb +19 -15
  101. data/spec/adhearsion/process_spec.rb +12 -7
  102. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +35 -15
  103. data/spec/adhearsion/punchblock_plugin_spec.rb +4 -1
  104. data/spec/adhearsion/router/route_spec.rb +8 -6
  105. data/spec/adhearsion/router_spec.rb +12 -10
  106. data/spec/adhearsion_spec.rb +13 -2
  107. data/spec/capture_warnings.rb +33 -0
  108. data/spec/spec_helper.rb +4 -0
  109. data/spec/support/call_controller_test_helpers.rb +2 -4
  110. data/spec/support/initializer_stubs.rb +8 -5
  111. data/spec/support/logging_helpers.rb +2 -0
  112. data/spec/support/punchblock_mocks.rb +2 -0
  113. metadata +84 -71
  114. data/EVENTS +0 -11
  115. data/lib/adhearsion/call_controller/menu.rb +0 -124
  116. data/lib/adhearsion/foundation/all.rb +0 -8
  117. data/spec/adhearsion/call_controller/menu_spec.rb +0 -120
  118. data/spec/adhearsion/menu_dsl_spec.rb +0 -12
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Adhearsion::Logging do
@@ -26,7 +28,7 @@ describe Adhearsion::Logging do
26
28
  end
27
29
 
28
30
  it 'should create the predefined set of log levels' do
29
- ::Logging::LEVELS.keys.should == Adhearsion::Logging::LOG_LEVELS.map(&:downcase)
31
+ ::Logging::LEVELS.keys.should be == Adhearsion::Logging::LOG_LEVELS.map(&:downcase)
30
32
  end
31
33
 
32
34
  it "should log to the Object logger when given arguments" do
@@ -93,9 +95,9 @@ describe Adhearsion::Logging do
93
95
  Adhearsion.config.platform.logging['level'] = :warn
94
96
  Adhearsion::Logging.level = :warn
95
97
  Adhearsion::Logging.toggle_trace!
96
- Adhearsion::Logging.level.should == 0
98
+ Adhearsion::Logging.level.should be == 0
97
99
  Adhearsion::Logging.toggle_trace!
98
- Adhearsion::Logging.level.should == 3
100
+ Adhearsion::Logging.level.should be == 3
99
101
  Adhearsion.config.platform.logging['level'] = orig_level
100
102
  end
101
103
 
@@ -106,18 +108,18 @@ describe Adhearsion::Logging do
106
108
 
107
109
  it 'changing the logging level should affect all loggers' do
108
110
  loggers = [::Foo.logger, ::Foo::Bar.logger]
109
- loggers.map(&:level).should_not == [Adhearsion::Logging::DEBUG] * 2
110
- loggers.map(&:level).should == [Adhearsion::Logging::INFO] * 2
111
+ loggers.map(&:level).should_not be == [Adhearsion::Logging::DEBUG] * 2
112
+ loggers.map(&:level).should be == [Adhearsion::Logging::INFO] * 2
111
113
  Adhearsion::Logging.logging_level = :warn
112
- loggers.map(&:level).should == [Adhearsion::Logging::WARN] * 2
114
+ loggers.map(&:level).should be == [Adhearsion::Logging::WARN] * 2
113
115
  end
114
116
 
115
117
  it 'changing the logging level, using level=, should affect all loggers' do
116
118
  loggers = [Foo.logger, ::Foo::Bar.logger]
117
- loggers.map(&:level).should_not == [::Logging::LEVELS["debug"]] * 2
118
- loggers.map(&:level).should == [::Logging::LEVELS["info"]] * 2
119
+ loggers.map(&:level).should_not be == [::Logging::LEVELS["debug"]] * 2
120
+ loggers.map(&:level).should be == [::Logging::LEVELS["info"]] * 2
119
121
  Adhearsion::Logging.level = :warn
120
- loggers.map(&:level).should == [::Logging::LEVELS["warn"]] * 2
122
+ loggers.map(&:level).should be == [::Logging::LEVELS["warn"]] * 2
121
123
  end
122
124
 
123
125
  it 'should change all the Logger instance level' do
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Adhearsion
@@ -23,10 +25,10 @@ module Adhearsion
23
25
  mock_matches_2 = mock_with_potential_matches mock_matches_array_2
24
26
 
25
27
  subject << mock_matches_1
26
- subject.actual_potential_matches.should == mock_matches_array_1
28
+ subject.actual_potential_matches.should be == mock_matches_array_1
27
29
 
28
30
  subject << mock_matches_2
29
- subject.actual_potential_matches.should == mock_matches_array_1 + mock_matches_array_2
31
+ subject.actual_potential_matches.should be == mock_matches_array_1 + mock_matches_array_2
30
32
  end
31
33
 
32
34
  it "the <<() method should collect the exact matches into the actual_exact_matches Array" do
@@ -36,10 +38,10 @@ module Adhearsion
36
38
  mock_matches_2 = mock_with_exact_matches mock_matches_array_2
37
39
 
38
40
  subject << mock_matches_1
39
- subject.actual_exact_matches.should == mock_matches_array_1
41
+ subject.actual_exact_matches.should be == mock_matches_array_1
40
42
 
41
43
  subject << mock_matches_2
42
- subject.actual_exact_matches.should == mock_matches_array_1 + mock_matches_array_2
44
+ subject.actual_exact_matches.should be == mock_matches_array_1 + mock_matches_array_2
43
45
  end
44
46
 
45
47
  it "if any exact matches exist, the exact_match?() method should return true" do
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Adhearsion
@@ -34,11 +36,11 @@ module Adhearsion
34
36
  end
35
37
 
36
38
  it "#exact_matches should return an array of exact matches" do
37
- CalculatedMatch.new(:exact_matches => [0,3,5]).exact_matches.should == [0,3,5]
39
+ CalculatedMatch.new(:exact_matches => [0,3,5]).exact_matches.should be == [0,3,5]
38
40
  end
39
41
 
40
42
  it "#potential_matches should return an array of potential matches" do
41
- CalculatedMatch.new(:potential_matches => [88,99,77]).potential_matches.should == [88,99,77]
43
+ CalculatedMatch.new(:potential_matches => [88,99,77]).potential_matches.should be == [88,99,77]
42
44
  end
43
45
 
44
46
  it "::failed_match! should return a match that *really* failed" do
@@ -49,8 +51,8 @@ module Adhearsion
49
51
  failure.type_of_match.should be nil
50
52
 
51
53
  failure.match_payload.should be :match_payload_does_not_matter
52
- failure.pattern.should == (10..20)
53
- failure.query.should == 30
54
+ failure.pattern.should be == (10..20)
55
+ failure.query.should be == 30
54
56
  end
55
57
  end
56
58
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Adhearsion
@@ -10,7 +12,7 @@ module Adhearsion
10
12
  match = calculator.match 4
11
13
  match.potential_match?.should be true
12
14
  match.exact_match?.should_not be true
13
- match.potential_matches.should == [444]
15
+ match.potential_matches.should be == [444]
14
16
  end
15
17
 
16
18
  it "a multi-digit exact match scenario" do
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Adhearsion
@@ -1,10 +1,12 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Adhearsion
4
6
  module MenuDSL
5
7
 
6
8
  describe MenuBuilder do
7
- subject{ MenuDSL::MenuBuilder.new }
9
+ subject{ MenuDSL::MenuBuilder.new }
8
10
 
9
11
  describe "#build" do
10
12
  it "sets the context and instance_eval's the block" do
@@ -17,12 +19,13 @@ module Adhearsion
17
19
 
18
20
  describe "#match" do
19
21
  let(:match_block) { Proc.new() {} }
22
+
20
23
  it "raises an exception if called without a CallController and no block" do
21
24
  expect { subject.match 1 }.to raise_error(ArgumentError)
22
25
  end
23
26
 
24
27
  it "raises an exception if given both a payload and a block" do
25
- expect { subject.match(1, Object) {} }.to raise_error(ArgumentError)
28
+ expect { subject.match(1, Object) {} }.to raise_error(ArgumentError)
26
29
  end
27
30
 
28
31
  it "raises an exception if given no patterns" do
@@ -38,6 +41,7 @@ module Adhearsion
38
41
  flexmock(MenuDSL::MatchCalculator).should_receive(:build_with_pattern).with("1", nil, match_block)
39
42
  subject.match("1", &match_block)
40
43
  end
44
+
41
45
  it "creates multiple patterns if multiple arguments are passed in" do
42
46
  flexmock(MenuDSL::MatchCalculator).should_receive(:build_with_pattern).with(1, Object)
43
47
  flexmock(MenuDSL::MatchCalculator).should_receive(:build_with_pattern).with(2, Object)
@@ -45,13 +49,27 @@ module Adhearsion
45
49
  end
46
50
  end#match
47
51
 
52
+ describe "#has_matchers?" do
53
+ context "with no matchers specified" do
54
+ its(:has_matchers?) { should be false }
55
+ end
56
+
57
+ context "with at least one matcher specified" do
58
+ before do
59
+ subject.match(1) {}
60
+ end
61
+
62
+ its(:has_matchers?) { should be true }
63
+ end
64
+ end
65
+
48
66
  describe "#weighted_match_calculators" do
49
67
  let(:expected_pattern) { MenuDSL::MatchCalculator.build_with_pattern("1", Object) }
50
-
68
+
51
69
  it "returns the generated patterns" do
52
70
  flexmock(MenuDSL::MatchCalculator).should_receive(:build_with_pattern).with("1", Object).and_return(expected_pattern)
53
71
  subject.match("1", Object)
54
- subject.weighted_match_calculators.should == [expected_pattern]
72
+ subject.weighted_match_calculators.should be == [expected_pattern]
55
73
  end
56
74
  end#weighted_match_calculators
57
75
 
@@ -59,12 +77,12 @@ module Adhearsion
59
77
  let(:callback) { Proc.new() {} }
60
78
 
61
79
  it "raises an error if not passed a block" do
62
- expect { subject.invalid }.to raise_error(LocalJumpError)
80
+ expect { subject.invalid }.to raise_error(LocalJumpError)
63
81
  end
64
82
 
65
83
  it "sets the invalid callback" do
66
84
  subject.invalid(&callback)
67
- subject.menu_callbacks[:invalid].should == callback
85
+ subject.menu_callbacks[:invalid].should be == callback
68
86
  end
69
87
  end#invalid
70
88
 
@@ -72,12 +90,12 @@ module Adhearsion
72
90
  let(:callback) { Proc.new() {} }
73
91
 
74
92
  it "raises an error if not passed a block" do
75
- expect { subject.timeout }.to raise_error(LocalJumpError)
93
+ expect { subject.timeout }.to raise_error(LocalJumpError)
76
94
  end
77
95
 
78
96
  it "sets the timeout callback" do
79
97
  subject.timeout(&callback)
80
- subject.menu_callbacks[:timeout].should == callback
98
+ subject.menu_callbacks[:timeout].should be == callback
81
99
  end
82
100
  end#timeout
83
101
 
@@ -85,15 +103,28 @@ module Adhearsion
85
103
  let(:callback) { Proc.new() {} }
86
104
 
87
105
  it "raises an error if not passed a block" do
88
- expect { subject.failure }.to raise_error(LocalJumpError)
106
+ expect { subject.failure }.to raise_error(LocalJumpError)
89
107
  end
90
108
 
91
109
  it "sets the failure callback" do
92
110
  subject.failure(&callback)
93
- subject.menu_callbacks[:failure].should == callback
111
+ subject.menu_callbacks[:failure].should be == callback
94
112
  end
95
113
  end#failure
96
114
 
115
+ describe "#validator" do
116
+ let(:callback) { Proc.new() {} }
117
+
118
+ it "raises an error if not passed a block" do
119
+ expect { subject.validator }.to raise_error(LocalJumpError)
120
+ end
121
+
122
+ it "sets the invalid callback" do
123
+ subject.validator(&callback)
124
+ subject.menu_callbacks[:validator].should be == callback
125
+ end
126
+ end#invalid
127
+
97
128
  describe "#execute_hook_for" do
98
129
  it "executes the correct hook" do
99
130
  bar = nil
@@ -101,7 +132,7 @@ module Adhearsion
101
132
  bar = baz
102
133
  end
103
134
  subject.execute_hook_for(:invalid, "1")
104
- bar.should == "1"
135
+ bar.should be == "1"
105
136
  end
106
137
  end#execute_hook_for
107
138
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Adhearsion
@@ -5,38 +7,128 @@ module Adhearsion
5
7
  describe Menu do
6
8
 
7
9
  let(:options) { Hash.new }
8
- subject { Menu.new(options) {} }
10
+ subject { Menu.new(options) }
9
11
 
10
12
  describe "#initialize" do
11
-
12
- its(:tries_count) { should == 0 }
13
-
13
+ its(:tries_count) { should be == 0 }
14
14
 
15
15
  context 'when no timeout is set' do
16
16
  it "should have the default timeout" do
17
- subject.timeout.should == 5
17
+ subject.timeout.should be == 5
18
18
  end
19
19
  end
20
+
20
21
  context 'when a timeout is set' do
21
22
  let(:options) {
22
23
  {:timeout => 20}
23
24
  }
25
+
24
26
  it 'should have the passed timeout' do
25
- subject.timeout.should == 20
27
+ subject.timeout.should be == 20
26
28
  end
27
29
  end
28
30
 
29
31
  context 'when no max number of tries is set' do
30
32
  it "should have the default max number of tries" do
31
- subject.max_number_of_tries.should == 1
33
+ subject.max_number_of_tries.should be == 1
32
34
  end
33
35
  end
36
+
34
37
  context 'when a max number of tries is set' do
35
38
  let(:options) {
36
39
  {:tries => 3}
37
40
  }
41
+
38
42
  it 'should have the passed max number of tries' do
39
- subject.max_number_of_tries.should == 3
43
+ subject.max_number_of_tries.should be == 3
44
+ end
45
+ end
46
+
47
+ context 'when no terminator is set' do
48
+ it "should have no terminator" do
49
+ subject.terminator.should be == ''
50
+ end
51
+
52
+ it 'should not validate successfully' do
53
+ lambda { subject.validate }.should raise_error(Menu::InvalidStructureError)
54
+ end
55
+ end
56
+
57
+ context 'when a terminator is set' do
58
+ let(:options) {
59
+ {:terminator => 3}
60
+ }
61
+
62
+ it 'should have the passed terminator' do
63
+ subject.terminator.should be == '3'
64
+ end
65
+
66
+ it 'should validate(:basic) successfully' do
67
+ subject.validate(:basic).should be true
68
+ end
69
+
70
+ it 'should not validate successfully' do
71
+ lambda { subject.validate }.should raise_error(Menu::InvalidStructureError)
72
+ end
73
+ end
74
+
75
+ context 'when no limit is set' do
76
+ it "should have no limit" do
77
+ subject.limit.should be nil
78
+ end
79
+
80
+ it 'should not validate successfully' do
81
+ lambda { subject.validate }.should raise_error(Menu::InvalidStructureError)
82
+ end
83
+ end
84
+
85
+ context 'when a limit is set' do
86
+ let(:options) {
87
+ {:limit => 3}
88
+ }
89
+
90
+ it 'should have the passed limit' do
91
+ subject.limit.should be == 3
92
+ end
93
+
94
+ it 'should validate(:basic) successfully' do
95
+ subject.validate(:basic).should be true
96
+ end
97
+
98
+ it 'should not validate successfully' do
99
+ lambda { subject.validate }.should raise_error(Menu::InvalidStructureError)
100
+ end
101
+ end
102
+
103
+ context 'when no interruptibility is set' do
104
+ it "should be interruptible" do
105
+ subject.interruptible.should be true
106
+ end
107
+ end
108
+
109
+ context 'when interruptible is set false' do
110
+ let(:options) {
111
+ {:interruptible => false}
112
+ }
113
+
114
+ it 'should be interruptible' do
115
+ subject.interruptible.should be false
116
+ end
117
+ end
118
+
119
+ context 'when matchers are specified' do
120
+ subject do
121
+ Menu.new do
122
+ match(1) { }
123
+ end
124
+ end
125
+
126
+ it 'should validate successfully' do
127
+ subject.validate.should be true
128
+ end
129
+
130
+ it 'should not validate(:basic) successfully' do
131
+ lambda { subject.validate :basic }.should raise_error(Menu::InvalidStructureError)
40
132
  end
41
133
  end
42
134
 
@@ -47,7 +139,7 @@ module Adhearsion
47
139
  mock_menu_builder = flexmock(MenuBuilder.new)
48
140
  flexmock(MenuBuilder).should_receive(:new).and_return(mock_menu_builder)
49
141
  mock_menu_builder.should_receive(:match).once.with(1)
50
- Menu.new {match 1}
142
+ Menu.new { match 1 }
51
143
  end
52
144
  end
53
145
 
@@ -55,38 +147,40 @@ module Adhearsion
55
147
 
56
148
  describe "#digit_buffer" do
57
149
  its(:digit_buffer) { should be_a Menu::ClearableStringBuffer }
58
- its(:digit_buffer) { should == "" }
150
+ its(:digit_buffer) { should be == "" }
59
151
  end
60
152
 
61
153
  describe "#<<" do
62
154
  it "should add a digit to the buffer" do
63
155
  subject << 'a'
64
- subject.digit_buffer.should == 'a'
156
+ subject.digit_buffer.should be == 'a'
157
+ subject.result.should be == 'a'
65
158
  end
66
159
  end
67
160
 
68
161
  describe "#digit_buffer_empty?" do
69
162
  it "returns true if buffer is empty" do
70
- subject.digit_buffer_empty?.should == true
163
+ subject.digit_buffer_empty?.should be == true
71
164
  end
165
+
72
166
  it "returns false if buffer is not empty" do
73
167
  subject << 1
74
- subject.digit_buffer_empty?.should == false
168
+ subject.digit_buffer_empty?.should be == false
75
169
  end
76
170
  end
77
171
 
78
172
  describe "#digit_buffer_string" do
79
173
  it "returns the digit buffer as a string" do
80
174
  subject << 1
81
- subject.digit_buffer_string.should == "1"
175
+ subject.digit_buffer_string.should be == "1"
82
176
  end
83
177
  end
84
178
 
85
179
  describe "#should_continue?" do
86
180
  it "returns true if the number of tries is less than the maximum" do
87
- subject.max_number_of_tries.should == 1
88
- subject.tries_count.should == 0
89
- subject.should_continue?.should == true
181
+ subject.max_number_of_tries.should be == 1
182
+ subject.tries_count.should be == 0
183
+ subject.should_continue?.should be == true
90
184
  end
91
185
  end
92
186
 
@@ -94,8 +188,8 @@ module Adhearsion
94
188
  it "increments tries and clears the digit buffer" do
95
189
  subject << 1
96
190
  subject.restart!
97
- subject.tries_count.should == 1
98
- subject.digit_buffer_empty?.should == true
191
+ subject.tries_count.should be == 1
192
+ subject.digit_buffer_empty?.should be == true
99
193
  end
100
194
  end
101
195
 
@@ -104,7 +198,7 @@ module Adhearsion
104
198
  mock_menu_builder = flexmock(MenuBuilder.new)
105
199
  flexmock(MenuBuilder).should_receive(:new).and_return(mock_menu_builder)
106
200
  mock_menu_builder.should_receive(:execute_hook_for).with(:invalid, "")
107
- menu_instance = Menu.new() {}
201
+ menu_instance = Menu.new
108
202
  menu_instance.execute_invalid_hook
109
203
  end
110
204
  end
@@ -114,7 +208,7 @@ module Adhearsion
114
208
  mock_menu_builder = flexmock(MenuBuilder.new)
115
209
  flexmock(MenuBuilder).should_receive(:new).and_return(mock_menu_builder)
116
210
  mock_menu_builder.should_receive(:execute_hook_for).with(:timeout, "")
117
- menu_instance = Menu.new() {}
211
+ menu_instance = Menu.new
118
212
  menu_instance.execute_timeout_hook
119
213
  end
120
214
  end
@@ -124,17 +218,28 @@ module Adhearsion
124
218
  mock_menu_builder = flexmock(MenuBuilder.new)
125
219
  flexmock(MenuBuilder).should_receive(:new).and_return(mock_menu_builder)
126
220
  mock_menu_builder.should_receive(:execute_hook_for).with(:failure, "")
127
- menu_instance = Menu.new() {}
221
+ menu_instance = Menu.new
128
222
  menu_instance.execute_failure_hook
129
223
  end
130
224
  end
131
225
 
226
+ describe "#execute_validator_hook" do
227
+ it "calls the builder's execute_hook_for with :validator" do
228
+ mock_menu_builder = flexmock(MenuBuilder.new)
229
+ flexmock(MenuBuilder).should_receive(:new).and_return(mock_menu_builder)
230
+ mock_menu_builder.should_receive(:execute_hook_for).with(:validator, "")
231
+ menu_instance = Menu.new
232
+ menu_instance.execute_validator_hook
233
+ end
234
+ end
235
+
132
236
  describe "#continue" do
133
237
  class MockControllerA; end
134
238
  class MockControllerB; end
135
239
  class MockControllerC; end
240
+ let(:options) { {} }
136
241
  let(:menu_instance) {
137
- Menu.new do
242
+ Menu.new options do
138
243
  match 1, MockControllerA
139
244
  match 21, MockControllerA
140
245
  match 23, MockControllerA
@@ -145,46 +250,102 @@ module Adhearsion
145
250
  match 6..8, MockControllerA
146
251
  end
147
252
  }
253
+
148
254
  it "returns a MenuGetAnotherDigitOrTimeout if the digit buffer is empty" do
149
255
  subject.continue.should be_a Menu::MenuGetAnotherDigitOrTimeout
256
+ menu_instance.status.should be nil
150
257
  end
151
258
 
152
259
  it "asks for another digit if it has potential matches" do
153
260
  menu_instance << 2
154
- menu_instance.continue.should be_a Menu::MenuGetAnotherDigitOrTimeout
261
+ menu_instance.continue.should be_a Menu::MenuGetAnotherDigitOrTimeout
262
+ menu_instance.status.should be == :potential
155
263
  end
156
264
 
157
265
  it "returns a MenuResultInvalid if there are no matches" do
158
266
  menu_instance << 9
159
267
  menu_instance.continue.should be_a Menu::MenuResultInvalid
160
- end
161
-
162
- it "returns a MenuGetAnotherDigitOrFinish if it has exact and potential matches" do
163
- menu_instance << 3
164
- menu_result = menu_instance.continue
165
- menu_result.should be_a Menu::MenuGetAnotherDigitOrFinish
268
+ menu_instance.status.should be == :invalid
166
269
  end
167
270
 
168
271
  it "returns the first exact match when it has exact and potentials" do
169
272
  menu_instance << 3
170
273
  menu_result = menu_instance.continue
171
274
  menu_result.should be_a Menu::MenuGetAnotherDigitOrFinish
172
- menu_result.match_object.should == MockControllerB
173
- menu_result.new_extension.should == "3"
275
+ menu_result.match_object.should be == MockControllerB
276
+ menu_result.new_extension.should be == "3"
277
+ menu_instance.status.should be == :multi_matched
174
278
  end
175
279
 
176
280
  it "returns a MenuResultFound if it has exact matches" do
177
281
  menu_instance << 6
178
282
  menu_result = menu_instance.continue
179
283
  menu_result.should be_a Menu::MenuResultFound
284
+ menu_instance.status.should be == :matched
180
285
  end
181
286
 
182
287
  it "returns the first exact match when it has only exact matches" do
183
288
  menu_instance << 6
184
289
  menu_result = menu_instance.continue
185
290
  menu_result.should be_a Menu::MenuResultFound
186
- menu_result.match_object.match_payload.should == MockControllerC
187
- menu_result.match_object.pattern.to_s.should == "6"
291
+ menu_result.match_object.match_payload.should be == MockControllerC
292
+ menu_result.match_object.pattern.to_s.should be == "6"
293
+ end
294
+
295
+ context "with no matchers" do
296
+ let(:menu_instance) { Menu.new options }
297
+
298
+ context "when a terminator digit is set" do
299
+ let(:options) { { :terminator => '#' } }
300
+
301
+ it "buffers until the terminator is issued then returns a MenuTerminated and sets the status to :terminated, removing the terminator from the buffer" do
302
+ menu_instance << 2
303
+ menu_instance << 4
304
+ menu_instance.continue.should be_a Menu::MenuGetAnotherDigitOrTimeout
305
+ menu_instance.status.should be == :potential
306
+ menu_instance << '#'
307
+ menu_instance.continue.should be_a Menu::MenuTerminated
308
+ menu_instance.continue.should be_a Menu::MenuResultDone
309
+ menu_instance.status.should be == :terminated
310
+ menu_instance.result.should be == '24'
311
+ end
312
+ end
313
+
314
+ context "when a digit limit is set" do
315
+ let(:options) { { :limit => 3 } }
316
+
317
+ it "buffers until the limit is reached, then returns MenuLimitReached and sets the status to :limited" do
318
+ menu_instance << 2
319
+ menu_instance << 4
320
+ menu_instance.continue.should be_a Menu::MenuGetAnotherDigitOrTimeout
321
+ menu_instance.status.should be == :potential
322
+ menu_instance << 2
323
+ menu_instance.continue.should be_a Menu::MenuLimitReached
324
+ menu_instance.continue.should be_a Menu::MenuResultDone
325
+ menu_instance.status.should be == :limited
326
+ menu_instance.result.should be == '242'
327
+ end
328
+ end
329
+
330
+ context "when a validator is defined" do
331
+ let(:menu_instance) do
332
+ Menu.new options do
333
+ validator { |buffer| buffer == "242" }
334
+ end
335
+ end
336
+
337
+ it "buffers until the validator returns true, then returns MenuValidatorTerminated and sets the status to :validator_terminated" do
338
+ menu_instance << 2
339
+ menu_instance << 4
340
+ menu_instance.continue.should be_a Menu::MenuGetAnotherDigitOrTimeout
341
+ menu_instance.status.should be == :potential
342
+ menu_instance << 2
343
+ menu_instance.continue.should be_a Menu::MenuValidatorTerminated
344
+ menu_instance.continue.should be_a Menu::MenuResultDone
345
+ menu_instance.status.should be == :validator_terminated
346
+ menu_instance.result.should be == '242'
347
+ end
348
+ end
188
349
  end
189
350
 
190
351
  end#continue
@@ -195,13 +356,13 @@ module Adhearsion
195
356
  it "adds a string to itself" do
196
357
  subject << 'b'
197
358
  subject << 'c'
198
- subject.should == 'bc'
359
+ subject.should be == 'bc'
199
360
  end
200
361
 
201
362
  it "clears itself" do
202
363
  subject << 'a'
203
364
  subject.clear!
204
- subject.should == ""
365
+ subject.should be == ""
205
366
  end
206
367
  end
207
368