matrioska 0.0.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.
@@ -0,0 +1 @@
1
+ pkg
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format documentation
@@ -0,0 +1,4 @@
1
+ # develop
2
+
3
+ # Version 0.0.1
4
+ * First official release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in plugin-template.gemspec
4
+ gemspec
@@ -0,0 +1,131 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ matrioska (0.0.1)
5
+ activesupport (>= 3.0.10)
6
+ adhearsion (~> 2.2)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ activesupport (3.2.10)
12
+ i18n (~> 0.6)
13
+ multi_json (~> 1.0)
14
+ adhearsion (2.2.0)
15
+ activesupport (~> 3.0)
16
+ adhearsion-loquacious (~> 1.9)
17
+ bundler (~> 1.0)
18
+ celluloid (~> 0.12, >= 0.12.1)
19
+ countdownlatch
20
+ deep_merge
21
+ ffi (~> 1.0)
22
+ future-resource (~> 1.0)
23
+ girl_friday
24
+ has-guarded-handlers (~> 1.5)
25
+ logging (~> 1.8)
26
+ pry
27
+ punchblock (~> 1.4)
28
+ rake
29
+ ruby_speech (~> 1.0)
30
+ thor
31
+ adhearsion-loquacious (1.9.3)
32
+ blather (0.8.2)
33
+ activesupport (>= 2.3.11)
34
+ eventmachine (>= 1.0.0)
35
+ girl_friday
36
+ niceogiri (~> 1.0)
37
+ nokogiri (~> 1.5, >= 1.5.6)
38
+ celluloid (0.12.4)
39
+ facter (>= 1.6.12)
40
+ timers (>= 1.0.0)
41
+ celluloid-io (0.12.1)
42
+ celluloid (~> 0.12.0)
43
+ nio4r (>= 0.4.0)
44
+ coderay (1.0.8)
45
+ connection_pool (0.9.3)
46
+ countdownlatch (1.0.0)
47
+ deep_merge (1.0.0)
48
+ diff-lcs (1.1.3)
49
+ eventmachine (1.0.0)
50
+ facter (1.6.17)
51
+ ffi (1.2.0)
52
+ future-resource (1.0.0)
53
+ girl_friday (0.11.1)
54
+ connection_pool (~> 0.9.0)
55
+ rubinius-actor
56
+ guard (1.5.0)
57
+ listen (>= 0.4.2)
58
+ lumberjack (>= 1.0.2)
59
+ pry (>= 0.9.10)
60
+ thor (>= 0.14.6)
61
+ guard-rspec (2.1.0)
62
+ guard (>= 1.1)
63
+ rspec (~> 2.11)
64
+ has-guarded-handlers (1.5.0)
65
+ i18n (0.6.1)
66
+ json (1.7.5)
67
+ listen (0.5.3)
68
+ little-plugger (1.1.3)
69
+ logging (1.8.1)
70
+ little-plugger (>= 1.1.3)
71
+ multi_json (>= 1.3.6)
72
+ lumberjack (1.0.2)
73
+ method_source (0.8.1)
74
+ multi_json (1.5.0)
75
+ niceogiri (1.1.1)
76
+ nokogiri (~> 1.5)
77
+ nio4r (0.4.3)
78
+ nokogiri (1.5.6)
79
+ pry (0.9.10)
80
+ coderay (~> 1.0.5)
81
+ method_source (~> 0.8)
82
+ slop (~> 3.3.1)
83
+ punchblock (1.7.1)
84
+ activesupport (~> 3.0)
85
+ blather (>= 0.7.0)
86
+ celluloid (~> 0.12, >= 0.12.3)
87
+ future-resource (~> 1.0)
88
+ has-guarded-handlers (~> 1.5)
89
+ niceogiri (~> 1.1)
90
+ ruby_ami (~> 1.2, >= 1.2.1)
91
+ ruby_fs (~> 1.0)
92
+ ruby_speech (~> 1.0)
93
+ state_machine (~> 1.0)
94
+ rake (0.9.2.2)
95
+ rspec (2.11.0)
96
+ rspec-core (~> 2.11.0)
97
+ rspec-expectations (~> 2.11.0)
98
+ rspec-mocks (~> 2.11.0)
99
+ rspec-core (2.11.1)
100
+ rspec-expectations (2.11.3)
101
+ diff-lcs (~> 1.1.3)
102
+ rspec-mocks (2.11.3)
103
+ rubinius-actor (0.0.2)
104
+ rubinius-core-api
105
+ rubinius-core-api (0.0.1)
106
+ ruby_ami (1.2.6)
107
+ celluloid-io (~> 0.12.0)
108
+ countdownlatch (~> 1.0)
109
+ future-resource
110
+ girl_friday
111
+ ruby_fs (1.0.3)
112
+ celluloid-io (~> 0.12.0)
113
+ json
114
+ ruby_speech (1.0.2)
115
+ activesupport (>= 3.0.7)
116
+ niceogiri (~> 1.1, >= 1.1.1)
117
+ nokogiri (~> 1.5, >= 1.5.6)
118
+ slop (3.3.3)
119
+ state_machine (1.1.2)
120
+ thor (0.16.0)
121
+ timers (1.0.2)
122
+
123
+ PLATFORMS
124
+ ruby
125
+
126
+ DEPENDENCIES
127
+ bundler (~> 1.0)
128
+ guard-rspec
129
+ matrioska!
130
+ rake
131
+ rspec (~> 2.5)
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+
17
+ # Capybara request specs
18
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
19
+
20
+ # Turnip features and steps
21
+ watch(%r{^spec/acceptance/(.+)\.feature$})
22
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23
+ end
24
+
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2012 Adhearsion Foundation Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,45 @@
1
+ # Matrioska
2
+
3
+ Matrioska is an Adhearsion plugin for running in-call apps at the press of a DTMF.
4
+
5
+ By mapping controllers or blocks to the desired applications, a listener object waits for DTMF and reacts by executing the specified payload.
6
+
7
+ ## Usage Example
8
+
9
+ ```ruby
10
+ #inside your controller
11
+ runner = Matrioska::AppRunner.new self
12
+ runner.map_app 3 do
13
+ logger.info "hi there!"
14
+ end
15
+ runner.map_app 5, AppController
16
+
17
+ call.on_end do
18
+ runner.stop
19
+ end
20
+
21
+ runner.start
22
+ ```
23
+
24
+ ### Author
25
+
26
+ Original author: [Luca Pradovera](https://github.com/polysics)
27
+
28
+ ### Links
29
+
30
+ * [Adhearsion](http://adhearsion.com)
31
+ * [Source](https://github.com/polysics/matrioska)
32
+ * [Bug Tracker](https://github.com/polysics/matrioska/issues)
33
+
34
+ ### Note on Patches/Pull Requests
35
+
36
+ * Fork the project.
37
+ * Make your feature addition or bug fix.
38
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
39
+ * Commit, do not mess with rakefile, version, or history.
40
+ * If you want to have your own version, that is fine but bump version in a commit by itself so I can ignore when I pull
41
+ * Send me a pull request. Bonus points for topic branches.
42
+
43
+ ### Copyright
44
+
45
+ Copyright (c) 2013 Adhearsion Foundation Inc. MIT license (see LICENSE for details).
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,4 @@
1
+ Matrioska = Module.new
2
+ require "matrioska/version"
3
+ require "matrioska/plugin"
4
+ require "matrioska/app_runner"
@@ -0,0 +1,65 @@
1
+ module Matrioska
2
+ class AppRunner
3
+ include Adhearsion::CallController::Utility
4
+
5
+ def initialize(call)
6
+ @call = call
7
+ @app_map = {}
8
+ end
9
+
10
+ def start
11
+ component = Punchblock::Component::Input.new({ :mode => :dtmf,
12
+ :grammar => {
13
+ :value => grammar_accept
14
+ }
15
+ })
16
+ component.register_event_handler Punchblock::Event::Complete do |event|
17
+ handle_input_complete event
18
+ end
19
+ @call.write_and_await_response component
20
+ end
21
+
22
+ def app_map
23
+ @app_map
24
+ end
25
+
26
+ def map_app(digit, controller=nil, &block)
27
+ digit = digit.to_s
28
+ range = "1234567890*#"
29
+
30
+ unless range.include?(digit) && digit.size == 1
31
+ raise ArgumentError, "The first argument should be a single digit String or number in the range 1234567890*#"
32
+ end
33
+
34
+ payload = if block_given?
35
+ raise ArgumentError, "You cannot specify both a block and a controller name." if controller.is_a? Class
36
+ block
37
+ else
38
+ raise ArgumentError, "You need to provide a block or a controller name." unless controller.is_a? Class
39
+ controller
40
+ end
41
+
42
+ @app_map[digit] = payload
43
+ end
44
+
45
+ def match_and_run(digit)
46
+ if match = @app_map[digit]
47
+ Adhearsion.logger.info "#match_and_run called with #{digit}"
48
+ callback = lambda {|call| start }
49
+
50
+ @call.execute_controller(nil, callback, &match) if match.is_a? Proc
51
+ if match.is_a? Class
52
+ payload = match.new(@call)
53
+ @call.execute_controller(payload, callback)
54
+ end
55
+ end
56
+ start
57
+ end
58
+
59
+ def handle_input_complete(event)
60
+ result = event.reason.respond_to?(:utterance) ? event.reason.utterance : nil
61
+ digit = parse_dtmf result
62
+ match_and_run digit
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,29 @@
1
+ module Matrioska
2
+ class Plugin < Adhearsion::Plugin
3
+ # Actions to perform when the plugin is loaded
4
+ #
5
+ init :matrioska do
6
+ logger.warn "Matrioska has been loaded"
7
+ end
8
+
9
+ # Basic configuration for the plugin
10
+ #
11
+ config :matrioska do
12
+ greeting "Hello", :desc => "What to use to greet users"
13
+ end
14
+
15
+ # Defining a Rake task is easy
16
+ # The following can be invoked with:
17
+ # rake plugin_demo:info
18
+ #
19
+ tasks do
20
+ namespace :matrioska do
21
+ desc "Prints the PluginTemplate information"
22
+ task :info do
23
+ STDOUT.puts "Matrioska plugin v. #{VERSION}"
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module Matrioska
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "matrioska/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "matrioska"
7
+ s.version = Matrioska::VERSION
8
+ s.authors = ["Luca Pradovera"]
9
+ s.email = ["lpradovera@mojolingo.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Adhearsion plugin for in-call apps}
12
+ s.description = %q{Adhearsion plugin for in-call apps. Provides a features-style interface to run applications in calls.}
13
+
14
+ s.rubyforge_project = "matrioska"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_runtime_dependency %q<adhearsion>, ["~> 2.2"]
21
+ s.add_runtime_dependency %q<activesupport>, [">= 3.0.10"]
22
+
23
+ s.add_development_dependency %q<bundler>, ["~> 1.0"]
24
+ s.add_development_dependency %q<rspec>, ["~> 2.5"]
25
+ s.add_development_dependency %q<rake>, [">= 0"]
26
+ s.add_development_dependency %q<guard-rspec>
27
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ module Matrioska
4
+ describe AppRunner do
5
+ let(:mock_call) { mock('Call') }
6
+ subject { AppRunner.new mock_call }
7
+ class MockController < Adhearsion::CallController; end
8
+
9
+ describe "#start" do
10
+ let(:grxml) {
11
+ RubySpeech::GRXML.draw :mode => 'dtmf', :root => 'inputdigits' do
12
+ rule id: 'inputdigits', scope: 'public' do
13
+ one_of do
14
+ 0.upto(9) { |d| item { d.to_s } }
15
+ item { "#" }
16
+ item { "*" }
17
+ end
18
+ end
19
+ end
20
+ }
21
+
22
+ let(:input_component) {
23
+ Punchblock::Component::Input.new(
24
+ { :mode => :dtmf,
25
+ :grammar => {
26
+ :value => grxml.to_s
27
+ }
28
+ }
29
+ )
30
+ }
31
+
32
+ it "should start the appropriate component" do
33
+ mock_call.should_receive(:write_and_await_response).with(input_component)
34
+ subject.start
35
+ end
36
+ end
37
+
38
+ describe "#map_app" do
39
+ context "with invalid input" do
40
+ let(:too_long) { "ab" }
41
+ let(:wrong) { "a" }
42
+ it "should raise if the first argument is not a single digit string in the range" do
43
+ expect { subject.map_app(too_long){} }.to raise_error ArgumentError, "The first argument should be a single digit String or number in the range 1234567890*#"
44
+ expect { subject.map_app(wrong){} }.to raise_error ArgumentError, "The first argument should be a single digit String or number in the range 1234567890*#"
45
+ end
46
+
47
+ it "raises if called without either a class or a block" do
48
+ expect { subject.map_app 1 }.to raise_error ArgumentError, "You need to provide a block or a controller name."
49
+ end
50
+
51
+ it "raises if passed both a class and a block" do
52
+ expect { subject.map_app(1, Object){} }.to raise_error ArgumentError, "You cannot specify both a block and a controller name."
53
+ end
54
+ end
55
+
56
+ context "with valid input" do
57
+ it "properly sets the map for a block" do
58
+ subject.map_app(3) { p "foo" }
59
+ subject.app_map["3"].should be_a Proc
60
+ end
61
+ it "properly sets the map for a class" do
62
+ subject.map_app(3, Object)
63
+ subject.app_map["3"].should be_a Class
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "#match_and_run" do
69
+ before do
70
+ subject.map_app(3) { p "foo" }
71
+ subject.map_app(5, MockController)
72
+ end
73
+
74
+ it "does nothing if there is no match, and restarts the launcher" do
75
+ mock_call.should_receive(:execute_controller).never
76
+ subject.should_receive(:start).once
77
+ subject.match_and_run("4")
78
+ end
79
+
80
+ it "executes the block if the payload is a Proc" do
81
+ mock_call.should_receive(:execute_controller).once.with(&subject.app_map["3"])
82
+ subject.should_receive(:start).once
83
+ subject.match_and_run("3")
84
+ end
85
+ it "executes the controller if the payload is a Class" do
86
+ mock_call.should_receive(:execute_controller).once.with(kind_of(MockController), kind_of(Proc))
87
+ subject.should_receive(:start).once
88
+ subject.match_and_run("5")
89
+ end
90
+ end
91
+
92
+ describe "#handle_input_complete" do
93
+ let(:mock_event) { mock('Event', :reason => mock('Reason', :utterance => "dtmf-5")) }
94
+ it "runs #match_and_run" do
95
+ subject.should_receive(:match_and_run).with("5").once
96
+ subject.handle_input_complete(mock_event)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,11 @@
1
+ require 'adhearsion'
2
+ require 'matrioska'
3
+
4
+ RSpec.configure do |config|
5
+ config.color_enabled = true
6
+ config.tty = true
7
+
8
+ config.filter_run :focus => true
9
+ config.run_all_when_everything_filtered = true
10
+ end
11
+
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: matrioska
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Luca Pradovera
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: adhearsion
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.2'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 3.0.10
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 3.0.10
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.5'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2.5'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Adhearsion plugin for in-call apps. Provides a features-style interface
111
+ to run applications in calls.
112
+ email:
113
+ - lpradovera@mojolingo.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .rspec
120
+ - CHANGELOG.md
121
+ - Gemfile
122
+ - Gemfile.lock
123
+ - Guardfile
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - lib/matrioska.rb
128
+ - lib/matrioska/app_runner.rb
129
+ - lib/matrioska/plugin.rb
130
+ - lib/matrioska/version.rb
131
+ - matrioska.gemspec
132
+ - spec/matrioska/app_runner_spec.rb
133
+ - spec/spec_helper.rb
134
+ homepage: ''
135
+ licenses: []
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project: matrioska
154
+ rubygems_version: 1.8.24
155
+ signing_key:
156
+ specification_version: 3
157
+ summary: Adhearsion plugin for in-call apps
158
+ test_files:
159
+ - spec/matrioska/app_runner_spec.rb
160
+ - spec/spec_helper.rb
161
+ has_rdoc: