ruby_speech 2.0.1 → 2.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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/CHANGELOG.md +6 -0
- data/Guardfile +1 -1
- data/ext/ruby_speech/RubySpeechGRXMLMatcher.java +30 -8
- data/ext/ruby_speech/ruby_speech.c +72 -16
- data/lib/ruby_speech/generic_element.rb +4 -7
- data/lib/ruby_speech/grxml/grammar.rb +1 -1
- data/lib/ruby_speech/grxml/match.rb +1 -1
- data/lib/ruby_speech/grxml/matcher.rb +14 -24
- data/lib/ruby_speech/grxml/max_match.rb +6 -0
- data/lib/ruby_speech/grxml.rb +1 -0
- data/lib/ruby_speech/version.rb +1 -1
- data/ruby_speech.gemspec +1 -1
- data/spec/ruby_speech/grxml/match_spec.rb +3 -37
- data/spec/ruby_speech/grxml/matcher_spec.rb +52 -43
- data/spec/ruby_speech/grxml/max_match_spec.rb +17 -0
- data/spec/support/match_examples.rb +43 -0
- data/spec/support/matchers.rb +1 -7
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de37299d09f7a9dc63c8c5944db79f80594bfffc
|
4
|
+
data.tar.gz: c01558ff39e76c034f1b18df7288c27d04ec84b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2dc9ae2659cc93d40f7f0d55a2d6b4344accf12f7b1d7cf130aba09c4949a868bc47e2c641183aecad8bd42b0312a50d3a14d27eb9b933664fbaaa15de60cdc
|
7
|
+
data.tar.gz: 3df44bf14ab55473bd2dab097e2e972493744d299390085506e90ff437eb82441f535a3b29b1a45ac73d22c1770d0f4e4de9dbbb954d3d3c7c6983f12a741b75
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# [develop](https://github.com/benlangfeld/ruby_speech)
|
2
2
|
|
3
|
+
# [2.0.2](https://github.com/benlangfeld/ruby_speech/compare/v2.0.1...v2.0.2) - [2013-05-01](https://rubygems.org/gems/ruby_speech/versions/2.0.2)
|
4
|
+
* Bugfix: Differentiate between GRXML match cases with are and are not maximal
|
5
|
+
* A Match can accept further input while still matching, while a a MaxMatch cannot.
|
6
|
+
* Matching implementation moved down to C/Java to avoid repeated regex compilation and confusing jumping about.
|
7
|
+
* Bugfix: Back to functioning on JRuby with latest Nokogiri release
|
8
|
+
|
3
9
|
# [2.0.1](https://github.com/benlangfeld/ruby_speech/compare/v2.0.0...v2.0.1) - [2013-04-27](https://rubygems.org/gems/ruby_speech/versions/2.0.1)
|
4
10
|
* Bugfix: Build native C extension in the correct location
|
5
11
|
|
data/Guardfile
CHANGED
@@ -17,26 +17,48 @@ import java.util.regex.*;
|
|
17
17
|
@JRubyClass(name="RubySpeech::GRXML::Matcher")
|
18
18
|
public class RubySpeechGRXMLMatcher extends RubyObject {
|
19
19
|
|
20
|
+
Pattern p;
|
21
|
+
|
20
22
|
public RubySpeechGRXMLMatcher(final Ruby runtime, RubyClass rubyClass) {
|
21
23
|
super(runtime, rubyClass);
|
22
24
|
}
|
23
25
|
|
24
26
|
@JRubyMethod(visibility=Visibility.PRIVATE)
|
25
|
-
public IRubyObject
|
26
|
-
{
|
27
|
+
public IRubyObject compile_regex(ThreadContext context, IRubyObject regex) {
|
27
28
|
Ruby runtime = context.getRuntime();
|
29
|
+
p = Pattern.compile(regex.toString());
|
30
|
+
return runtime.getNil();
|
31
|
+
}
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
@JRubyMethod(visibility=Visibility.PUBLIC)
|
34
|
+
public IRubyObject find_match(ThreadContext context, IRubyObject buffer)
|
35
|
+
{
|
36
|
+
Ruby runtime = context.getRuntime();
|
37
|
+
String string_buffer = buffer.toString();
|
38
|
+
Matcher m = p.matcher(string_buffer);
|
33
39
|
|
34
40
|
if (m.matches()) {
|
41
|
+
if (is_max_match(string_buffer)) {
|
42
|
+
return RuntimeHelpers.invoke(context, this, "match_for_buffer", buffer, runtime.getTrue());
|
43
|
+
}
|
44
|
+
return callMethod(context, "match_for_buffer", buffer);
|
35
45
|
} else if (m.hitEnd()) {
|
36
46
|
RubyModule potential_match = runtime.getClassFromPath("RubySpeech::GRXML::PotentialMatch");
|
37
|
-
return
|
47
|
+
return potential_match.callMethod(context, "new");
|
38
48
|
}
|
39
|
-
|
49
|
+
RubyModule nomatch = runtime.getClassFromPath("RubySpeech::GRXML::NoMatch");
|
50
|
+
return nomatch.callMethod(context, "new");
|
51
|
+
}
|
52
|
+
|
53
|
+
public Boolean is_max_match(String buffer)
|
54
|
+
{
|
55
|
+
String search_set = "0123456789#*ABCD";
|
56
|
+
for (int i = 0; i < 16; i++) {
|
57
|
+
String new_buffer = buffer + search_set.charAt(i);
|
58
|
+
Matcher m = p.matcher(new_buffer);
|
59
|
+
if (m.matches()) return false;
|
60
|
+
}
|
61
|
+
return true;
|
40
62
|
}
|
41
63
|
|
42
64
|
}
|
@@ -2,33 +2,88 @@
|
|
2
2
|
#include "pcre.h"
|
3
3
|
#include <stdio.h>
|
4
4
|
|
5
|
-
static VALUE
|
5
|
+
static VALUE method_compile_regex(VALUE self, VALUE regex_string)
|
6
6
|
{
|
7
|
-
int erroffset
|
8
|
-
const char *errptr
|
9
|
-
int options
|
10
|
-
|
11
|
-
const char *regex = StringValueCStr(regex_string);
|
7
|
+
int erroffset = 0;
|
8
|
+
const char *errptr = "";
|
9
|
+
int options = 0;
|
10
|
+
const char *regex = StringValueCStr(regex_string);
|
12
11
|
|
13
12
|
pcre *compiled_regex = pcre_compile(regex, options, &errptr, &erroffset, NULL);
|
13
|
+
VALUE compiled_regex_wrapper = Data_Wrap_Struct(rb_cObject, 0, pcre_free, compiled_regex);
|
14
|
+
rb_iv_set(self, "@regex", compiled_regex_wrapper);
|
14
15
|
|
16
|
+
return Qnil;
|
17
|
+
}
|
18
|
+
|
19
|
+
#define MAX_INPUT_SIZE 128
|
20
|
+
#define OVECTOR_SIZE 30
|
21
|
+
#define WORKSPACE_SIZE 1024
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Check if no more digits can be added to input and match
|
25
|
+
* @param compiled_regex the regex used in the initial match
|
26
|
+
* @param input the input to check
|
27
|
+
* @return true if end of match (no more input can be added)
|
28
|
+
*/
|
29
|
+
static int is_match_end(pcre *compiled_regex, const char *input)
|
30
|
+
{
|
31
|
+
int ovector[OVECTOR_SIZE];
|
32
|
+
int input_size = (int)strlen(input);
|
33
|
+
char search_input[MAX_INPUT_SIZE + 2];
|
34
|
+
const char *search_set = "0123456789#*ABCD";
|
35
|
+
const char *search = strchr(search_set, input[input_size - 1]); /* start with last digit in input */
|
36
|
+
|
37
|
+
/* For each digit in search_set, check if input + search_set digit is a potential match.
|
38
|
+
If so, then this is not a match end.
|
39
|
+
*/
|
40
|
+
sprintf(search_input, "%sZ", input);
|
41
|
+
int i;
|
42
|
+
for (i = 0; i < 16; i++) {
|
43
|
+
int result;
|
44
|
+
if (!*search) {
|
45
|
+
search = search_set;
|
46
|
+
}
|
47
|
+
search_input[input_size] = *search++;
|
48
|
+
result = pcre_exec(compiled_regex, NULL, search_input, input_size + 1, 0, 0,
|
49
|
+
ovector, sizeof(ovector) / sizeof(ovector[0]));
|
50
|
+
if (result > 0) return 0;
|
51
|
+
}
|
52
|
+
return 1;
|
53
|
+
}
|
54
|
+
|
55
|
+
static VALUE method_find_match(VALUE self, VALUE buffer)
|
56
|
+
{
|
57
|
+
VALUE RubySpeech = rb_const_get(rb_cObject, rb_intern("RubySpeech"));
|
58
|
+
VALUE GRXML = rb_const_get(RubySpeech, rb_intern("GRXML"));
|
59
|
+
VALUE NoMatch = rb_const_get(GRXML, rb_intern("NoMatch"));
|
60
|
+
pcre *compiled_regex;
|
15
61
|
int result = 0;
|
16
|
-
int ovector[
|
17
|
-
int workspace[
|
62
|
+
int ovector[OVECTOR_SIZE];
|
63
|
+
int workspace[WORKSPACE_SIZE];
|
18
64
|
char *input = StringValueCStr(buffer);
|
19
|
-
|
65
|
+
|
66
|
+
Data_Get_Struct(rb_iv_get(self, "@regex"), pcre, compiled_regex);
|
67
|
+
|
68
|
+
if (!compiled_regex) {
|
69
|
+
return rb_class_new_instance(0, NULL, NoMatch);
|
70
|
+
}
|
71
|
+
|
72
|
+
result = pcre_dfa_exec(compiled_regex, NULL, input, (int)strlen(input), 0, PCRE_PARTIAL,
|
20
73
|
ovector, sizeof(ovector) / sizeof(ovector[0]),
|
21
74
|
workspace, sizeof(workspace) / sizeof(workspace[0]));
|
22
|
-
pcre_free(compiled_regex);
|
23
75
|
|
76
|
+
if (result > 0) {
|
77
|
+
if (is_match_end(compiled_regex, input)) {
|
78
|
+
return rb_funcall(self, rb_intern("match_for_buffer"), 2, buffer, Qtrue);
|
79
|
+
}
|
80
|
+
return rb_funcall(self, rb_intern("match_for_buffer"), 1, buffer);
|
81
|
+
}
|
24
82
|
if (result == PCRE_ERROR_PARTIAL) {
|
25
|
-
VALUE
|
26
|
-
VALUE GRXML = rb_const_get(RubySpeech, rb_intern("GRXML"));
|
27
|
-
VALUE PotentialMatch = rb_const_get(GRXML, rb_intern("PotentialMatch"));
|
28
|
-
|
83
|
+
VALUE PotentialMatch = rb_const_get(GRXML, rb_intern("PotentialMatch"));
|
29
84
|
return rb_class_new_instance(0, NULL, PotentialMatch);
|
30
85
|
}
|
31
|
-
return
|
86
|
+
return rb_class_new_instance(0, NULL, NoMatch);
|
32
87
|
}
|
33
88
|
|
34
89
|
void Init_ruby_speech()
|
@@ -37,5 +92,6 @@ void Init_ruby_speech()
|
|
37
92
|
VALUE GRXML = rb_define_module_under(RubySpeech, "GRXML");
|
38
93
|
VALUE Matcher = rb_define_class_under(GRXML, "Matcher", rb_cObject);
|
39
94
|
|
40
|
-
rb_define_method(Matcher, "
|
95
|
+
rb_define_method(Matcher, "find_match", method_find_match, 1);
|
96
|
+
rb_define_method(Matcher, "compile_regex", method_compile_regex, 1);
|
41
97
|
}
|
@@ -109,17 +109,14 @@ module RubySpeech
|
|
109
109
|
|
110
110
|
def children(type = nil, attributes = nil)
|
111
111
|
if type
|
112
|
-
expression =
|
112
|
+
expression = namespace_href ? 'ns:' : ''
|
113
|
+
expression << type.to_s
|
113
114
|
|
114
115
|
expression << '[' << attributes.inject([]) do |h, (key, value)|
|
115
|
-
h << "@#{key}='#{value}'"
|
116
|
+
h << "@#{namespace_href && Nokogiri.jruby? ? 'ns:' : ''}#{key}='#{value}'"
|
116
117
|
end.join(',') << ']' if attributes
|
117
118
|
|
118
|
-
|
119
|
-
xpath "ns:#{expression}", :ns => namespace_href
|
120
|
-
else
|
121
|
-
xpath expression
|
122
|
-
end
|
119
|
+
xpath expression, :ns => namespace_href
|
123
120
|
else
|
124
121
|
super()
|
125
122
|
end.map { |c| self.class.import c }
|
@@ -109,7 +109,7 @@ module RubySpeech
|
|
109
109
|
ref.swap rule.nokogiri_children
|
110
110
|
end
|
111
111
|
|
112
|
-
non_root_rules = xpath "./ns:rule[
|
112
|
+
non_root_rules = xpath "./ns:rule[@#{namespace_href && Nokogiri.jruby? ? 'ns:' : ''}id!='#{root}']", :ns => namespace_href
|
113
113
|
non_root_rules.remove
|
114
114
|
|
115
115
|
self
|
@@ -8,7 +8,7 @@ module RubySpeech
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def eql?(o)
|
11
|
-
o.
|
11
|
+
o.instance_of?(self.class) && [:mode, :confidence, :utterance, :interpretation].all? { |f| self.__send__(f) == o.__send__(f) }
|
12
12
|
end
|
13
13
|
alias :== :eql?
|
14
14
|
end
|
@@ -8,15 +8,12 @@ end
|
|
8
8
|
module RubySpeech
|
9
9
|
module GRXML
|
10
10
|
class Matcher
|
11
|
-
|
12
|
-
BLANK_REGEX = //.freeze
|
13
|
-
|
14
|
-
attr_reader :grammar, :regex
|
11
|
+
attr_reader :grammar
|
15
12
|
|
16
13
|
def initialize(grammar)
|
17
14
|
@grammar = grammar
|
18
15
|
prepare_grammar
|
19
|
-
|
16
|
+
compile_regex regexp_content
|
20
17
|
end
|
21
18
|
|
22
19
|
##
|
@@ -24,7 +21,7 @@ module RubySpeech
|
|
24
21
|
#
|
25
22
|
# @param [String] other the input string to check for a match with the grammar
|
26
23
|
#
|
27
|
-
# @return [NoMatch, Match] depending on the result of a match attempt. If a match can be found, it will be returned with appropriate mode/confidence/utterance and interpretation attributes
|
24
|
+
# @return [NoMatch, PotentialMatch, Match, MaxMatch] depending on the result of a match attempt. A potential match indicates that the buffer is valid, but incomplete. A MaxMatch is differentiated from a Match in that it cannot accept further input. If a match can be found, it will be returned with appropriate mode/confidence/utterance and interpretation attributes
|
28
25
|
#
|
29
26
|
# @example A grammar that takes a 4 digit pin terminated by hash, or the *9 escape sequence
|
30
27
|
# ```ruby
|
@@ -85,34 +82,27 @@ module RubySpeech
|
|
85
82
|
# ```
|
86
83
|
#
|
87
84
|
def match(buffer)
|
88
|
-
|
89
|
-
|
90
|
-
return check_potential_match(buffer) if regex == BLANK_REGEX
|
91
|
-
|
92
|
-
check_full_match(buffer) || check_potential_match(buffer) || NoMatch.new
|
85
|
+
find_match buffer.dup
|
93
86
|
end
|
94
87
|
|
95
88
|
private
|
96
89
|
|
90
|
+
def regexp_content
|
91
|
+
'^' + grammar.root_rule.children.map(&:regexp_content).join + '$'
|
92
|
+
end
|
93
|
+
|
97
94
|
def prepare_grammar
|
98
95
|
grammar.inline!
|
99
96
|
grammar.tokenize!
|
100
97
|
grammar.normalize_whitespace
|
101
98
|
end
|
102
99
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
:confidence => grammar.dtmf? ? 1 : 0,
|
110
|
-
:utterance => buffer,
|
111
|
-
:interpretation => interpret_utterance(buffer)
|
112
|
-
end
|
113
|
-
|
114
|
-
def regexp_content
|
115
|
-
grammar.root_rule.children.map &:regexp_content
|
100
|
+
def match_for_buffer(buffer, maximal = false)
|
101
|
+
match_class = maximal ? MaxMatch : Match
|
102
|
+
match_class.new mode: grammar.mode,
|
103
|
+
confidence: grammar.dtmf? ? 1 : 0,
|
104
|
+
utterance: buffer,
|
105
|
+
interpretation: interpret_utterance(buffer)
|
116
106
|
end
|
117
107
|
|
118
108
|
def interpret_utterance(utterance)
|
data/lib/ruby_speech/grxml.rb
CHANGED
data/lib/ruby_speech/version.rb
CHANGED
data/ruby_speech.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.extensions = ['ext/ruby_speech/extconf.rb']
|
26
26
|
end
|
27
27
|
|
28
|
-
s.add_runtime_dependency %q<niceogiri>, ["~> 1.1", ">= 1.1.
|
28
|
+
s.add_runtime_dependency %q<niceogiri>, ["~> 1.1", ">= 1.1.2"]
|
29
29
|
s.add_runtime_dependency %q<nokogiri>, ["~> 1.5", ">= 1.5.6"]
|
30
30
|
s.add_runtime_dependency %q<activesupport>, [">= 3.0.7"]
|
31
31
|
|
@@ -3,45 +3,11 @@ require 'spec_helper'
|
|
3
3
|
module RubySpeech
|
4
4
|
module GRXML
|
5
5
|
describe Match do
|
6
|
-
|
7
|
-
Match.new :mode => :dtmf,
|
8
|
-
:confidence => 1,
|
9
|
-
:utterance => '6',
|
10
|
-
:interpretation => 'foo'
|
11
|
-
end
|
12
|
-
|
13
|
-
its(:mode) { should == :dtmf }
|
14
|
-
its(:confidence) { should == 1 }
|
15
|
-
its(:utterance) { should == '6' }
|
16
|
-
its(:interpretation) { should == 'foo' }
|
6
|
+
it_behaves_like "match"
|
17
7
|
|
18
8
|
describe "equality" do
|
19
|
-
it "should be equal
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "when the mode is different" do
|
24
|
-
it "should not be equal" do
|
25
|
-
Match.new(:mode => :dtmf).should_not == Match.new(:mode => :speech)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "when the confidence is different" do
|
30
|
-
it "should not be equal" do
|
31
|
-
Match.new(:confidence => 1).should_not == Match.new(:confidence => 0)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "when the utterance is different" do
|
36
|
-
it "should not be equal" do
|
37
|
-
Match.new(:utterance => '6').should_not == Match.new(:utterance => 'foo')
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "when the interpretation is different" do
|
42
|
-
it "should not be equal" do
|
43
|
-
Match.new(:interpretation => 'foo').should_not == Match.new(:interpretation => 'bar')
|
44
|
-
end
|
9
|
+
it "should never be equal to a MaxMatch" do
|
10
|
+
described_class.new.should_not eql(MaxMatch.new)
|
45
11
|
end
|
46
12
|
end
|
47
13
|
end
|
@@ -17,9 +17,9 @@ module RubySpeech
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
it "should match '6'" do
|
20
|
+
it "should max-match '6'" do
|
21
21
|
input = '6'
|
22
|
-
expected_match = GRXML::
|
22
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
23
23
|
:confidence => 1,
|
24
24
|
:utterance => '6',
|
25
25
|
:interpretation => 'dtmf-6'
|
@@ -43,8 +43,8 @@ module RubySpeech
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
it "should match '56'" do
|
47
|
-
expected_match = GRXML::
|
46
|
+
it "should maximally match '56'" do
|
47
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
48
48
|
:confidence => 1,
|
49
49
|
:utterance => '56',
|
50
50
|
:interpretation => 'dtmf-5 dtmf-6'
|
@@ -73,8 +73,8 @@ module RubySpeech
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
it "should match '*6'" do
|
77
|
-
expected_match = GRXML::
|
76
|
+
it "should maximally match '*6'" do
|
77
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
78
78
|
:confidence => 1,
|
79
79
|
:utterance => '*6',
|
80
80
|
:interpretation => 'dtmf-star dtmf-6'
|
@@ -101,8 +101,8 @@ module RubySpeech
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
-
it "should match '#6'" do
|
105
|
-
expected_match = GRXML::
|
104
|
+
it "should maximally match '#6'" do
|
105
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
106
106
|
:confidence => 1,
|
107
107
|
:utterance => '#6',
|
108
108
|
:interpretation => 'dtmf-pound dtmf-6'
|
@@ -134,8 +134,8 @@ module RubySpeech
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
-
it "should match '*6'" do
|
138
|
-
expected_match = GRXML::
|
137
|
+
it "should maximally match '*6'" do
|
138
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
139
139
|
:confidence => 1,
|
140
140
|
:utterance => '*6',
|
141
141
|
:interpretation => 'dtmf-star dtmf-6'
|
@@ -165,16 +165,16 @@ module RubySpeech
|
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
168
|
-
it "should match '6'" do
|
169
|
-
expected_match = GRXML::
|
168
|
+
it "should maximally match '6'" do
|
169
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
170
170
|
:confidence => 1,
|
171
171
|
:utterance => '6',
|
172
172
|
:interpretation => 'dtmf-6'
|
173
173
|
subject.match('6').should == expected_match
|
174
174
|
end
|
175
175
|
|
176
|
-
it "should match '7'" do
|
177
|
-
expected_match = GRXML::
|
176
|
+
it "should maximally match '7'" do
|
177
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
178
178
|
:confidence => 1,
|
179
179
|
:utterance => '7',
|
180
180
|
:interpretation => 'dtmf-7'
|
@@ -206,16 +206,16 @@ module RubySpeech
|
|
206
206
|
end
|
207
207
|
end
|
208
208
|
|
209
|
-
it "should match '65'" do
|
210
|
-
expected_match = GRXML::
|
209
|
+
it "should maximally match '65'" do
|
210
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
211
211
|
:confidence => 1,
|
212
212
|
:utterance => '65',
|
213
213
|
:interpretation => 'dtmf-6 dtmf-5'
|
214
214
|
subject.match('65').should == expected_match
|
215
215
|
end
|
216
216
|
|
217
|
-
it "should match '72'" do
|
218
|
-
expected_match = GRXML::
|
217
|
+
it "should maximally match '72'" do
|
218
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
219
219
|
:confidence => 1,
|
220
220
|
:utterance => '72',
|
221
221
|
:interpretation => 'dtmf-7 dtmf-2'
|
@@ -255,16 +255,16 @@ module RubySpeech
|
|
255
255
|
end
|
256
256
|
end
|
257
257
|
|
258
|
-
it "should match '652'" do
|
259
|
-
expected_match = GRXML::
|
258
|
+
it "should maximally match '652'" do
|
259
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
260
260
|
:confidence => 1,
|
261
261
|
:utterance => '652',
|
262
262
|
:interpretation => 'dtmf-6 dtmf-5 dtmf-2'
|
263
263
|
subject.match('652').should == expected_match
|
264
264
|
end
|
265
265
|
|
266
|
-
it "should match '728'" do
|
267
|
-
expected_match = GRXML::
|
266
|
+
it "should maximally match '728'" do
|
267
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
268
268
|
:confidence => 1,
|
269
269
|
:utterance => '728',
|
270
270
|
:interpretation => 'dtmf-7 dtmf-2 dtmf-8'
|
@@ -297,16 +297,16 @@ module RubySpeech
|
|
297
297
|
end
|
298
298
|
end
|
299
299
|
|
300
|
-
it "should match '*6'" do
|
301
|
-
expected_match = GRXML::
|
300
|
+
it "should maximally match '*6'" do
|
301
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
302
302
|
:confidence => 1,
|
303
303
|
:utterance => '*6',
|
304
304
|
:interpretation => 'dtmf-star dtmf-6'
|
305
305
|
subject.match('*6').should == expected_match
|
306
306
|
end
|
307
307
|
|
308
|
-
it "should match '*7'" do
|
309
|
-
expected_match = GRXML::
|
308
|
+
it "should maximally match '*7'" do
|
309
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
310
310
|
:confidence => 1,
|
311
311
|
:utterance => '*7',
|
312
312
|
:interpretation => 'dtmf-star dtmf-7'
|
@@ -337,24 +337,26 @@ module RubySpeech
|
|
337
337
|
end
|
338
338
|
end
|
339
339
|
|
340
|
-
it "should match '6*'" do
|
341
|
-
expected_match = GRXML::
|
340
|
+
it "should maximally match '6*'" do
|
341
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
342
342
|
:confidence => 1,
|
343
343
|
:utterance => '6*',
|
344
344
|
:interpretation => 'dtmf-6 dtmf-star'
|
345
345
|
subject.match('6*').should == expected_match
|
346
346
|
end
|
347
347
|
|
348
|
-
it "should match '7*'" do
|
349
|
-
expected_match = GRXML::
|
348
|
+
it "should maximally match '7*'" do
|
349
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
350
350
|
:confidence => 1,
|
351
351
|
:utterance => '7*',
|
352
352
|
:interpretation => 'dtmf-7 dtmf-star'
|
353
353
|
subject.match('7*').should == expected_match
|
354
354
|
end
|
355
355
|
|
356
|
-
|
357
|
-
|
356
|
+
%w{6 7}.each do |input|
|
357
|
+
it "should potentially match '#{input}'" do
|
358
|
+
subject.match(input).should == GRXML::PotentialMatch.new
|
359
|
+
end
|
358
360
|
end
|
359
361
|
|
360
362
|
it "should potentially match '7'" do
|
@@ -380,8 +382,8 @@ module RubySpeech
|
|
380
382
|
end
|
381
383
|
end
|
382
384
|
|
383
|
-
it "should match '166'" do
|
384
|
-
expected_match = GRXML::
|
385
|
+
it "should maximally match '166'" do
|
386
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
385
387
|
:confidence => 1,
|
386
388
|
:utterance => '166',
|
387
389
|
:interpretation => 'dtmf-1 dtmf-6 dtmf-6'
|
@@ -413,8 +415,8 @@ module RubySpeech
|
|
413
415
|
end
|
414
416
|
end
|
415
417
|
|
416
|
-
it "should match '661'" do
|
417
|
-
expected_match = GRXML::
|
418
|
+
it "should maximally match '661'" do
|
419
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
418
420
|
:confidence => 1,
|
419
421
|
:utterance => '661',
|
420
422
|
:interpretation => 'dtmf-6 dtmf-6 dtmf-1'
|
@@ -446,11 +448,18 @@ module RubySpeech
|
|
446
448
|
end
|
447
449
|
end
|
448
450
|
|
451
|
+
it "should maximally match '1666'" do
|
452
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
453
|
+
:confidence => 1,
|
454
|
+
:utterance => '1666',
|
455
|
+
:interpretation => 'dtmf-1 dtmf-6 dtmf-6 dtmf-6'
|
456
|
+
subject.match('1666').should == expected_match
|
457
|
+
end
|
458
|
+
|
449
459
|
{
|
450
460
|
'1' => 'dtmf-1',
|
451
461
|
'16' => 'dtmf-1 dtmf-6',
|
452
462
|
'166' => 'dtmf-1 dtmf-6 dtmf-6',
|
453
|
-
'1666' => 'dtmf-1 dtmf-6 dtmf-6 dtmf-6'
|
454
463
|
}.each_pair do |input, interpretation|
|
455
464
|
it "should match '#{input}'" do
|
456
465
|
expected_match = GRXML::Match.new :mode => :dtmf,
|
@@ -486,8 +495,8 @@ module RubySpeech
|
|
486
495
|
'661' => 'dtmf-6 dtmf-6 dtmf-1',
|
487
496
|
'6661' => 'dtmf-6 dtmf-6 dtmf-6 dtmf-1'
|
488
497
|
}.each_pair do |input, interpretation|
|
489
|
-
it "should match '#{input}'" do
|
490
|
-
expected_match = GRXML::
|
498
|
+
it "should maximally match '#{input}'" do
|
499
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
491
500
|
:confidence => 1,
|
492
501
|
:utterance => input,
|
493
502
|
:interpretation => interpretation
|
@@ -564,8 +573,8 @@ module RubySpeech
|
|
564
573
|
'6661' => 'dtmf-6 dtmf-6 dtmf-6 dtmf-1',
|
565
574
|
'66661' => 'dtmf-6 dtmf-6 dtmf-6 dtmf-6 dtmf-1'
|
566
575
|
}.each_pair do |input, interpretation|
|
567
|
-
it "should match '#{input}'" do
|
568
|
-
expected_match = GRXML::
|
576
|
+
it "should maximally match '#{input}'" do
|
577
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
569
578
|
:confidence => 1,
|
570
579
|
:utterance => input,
|
571
580
|
:interpretation => interpretation
|
@@ -617,8 +626,8 @@ module RubySpeech
|
|
617
626
|
'5678#' => 'dtmf-5 dtmf-6 dtmf-7 dtmf-8 dtmf-pound',
|
618
627
|
'1111#' => 'dtmf-1 dtmf-1 dtmf-1 dtmf-1 dtmf-pound'
|
619
628
|
}.each_pair do |input, interpretation|
|
620
|
-
it "should match '#{input}'" do
|
621
|
-
expected_match = GRXML::
|
629
|
+
it "should maximally match '#{input}'" do
|
630
|
+
expected_match = GRXML::MaxMatch.new :mode => :dtmf,
|
622
631
|
:confidence => 1,
|
623
632
|
:utterance => input,
|
624
633
|
:interpretation => interpretation
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
module GRXML
|
5
|
+
describe MaxMatch do
|
6
|
+
it_behaves_like "match"
|
7
|
+
|
8
|
+
it { should be_a Match }
|
9
|
+
|
10
|
+
describe "equality" do
|
11
|
+
it "should never be equal to a MaxMatch" do
|
12
|
+
described_class.new.should_not eql(Match.new)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
shared_examples_for "match" do
|
2
|
+
subject do
|
3
|
+
described_class.new :mode => :dtmf,
|
4
|
+
:confidence => 1,
|
5
|
+
:utterance => '6',
|
6
|
+
:interpretation => 'foo'
|
7
|
+
end
|
8
|
+
|
9
|
+
its(:mode) { should == :dtmf }
|
10
|
+
its(:confidence) { should == 1 }
|
11
|
+
its(:utterance) { should == '6' }
|
12
|
+
its(:interpretation) { should == 'foo' }
|
13
|
+
|
14
|
+
describe "equality" do
|
15
|
+
it "should be equal when mode, confidence, utterance and interpretation are the same" do
|
16
|
+
described_class.new(:mode => :dtmf, :confidence => 1, :utterance => '6', :interpretation => 'foo').should == described_class.new(:mode => :dtmf, :confidence => 1, :utterance => '6', :interpretation => 'foo')
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "when the mode is different" do
|
20
|
+
it "should not be equal" do
|
21
|
+
described_class.new(:mode => :dtmf).should_not == described_class.new(:mode => :speech)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "when the confidence is different" do
|
26
|
+
it "should not be equal" do
|
27
|
+
described_class.new(:confidence => 1).should_not == described_class.new(:confidence => 0)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "when the utterance is different" do
|
32
|
+
it "should not be equal" do
|
33
|
+
described_class.new(:utterance => '6').should_not == described_class.new(:utterance => 'foo')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "when the interpretation is different" do
|
38
|
+
it "should not be equal" do
|
39
|
+
described_class.new(:interpretation => 'foo').should_not == described_class.new(:interpretation => 'bar')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/spec/support/matchers.rb
CHANGED
@@ -14,13 +14,7 @@ class SpeechDocMatcher
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def subject=(s)
|
17
|
-
|
18
|
-
@subject = s
|
19
|
-
else
|
20
|
-
doc = Nokogiri::XML::Document.new
|
21
|
-
doc << s.to_xml
|
22
|
-
@subject = doc
|
23
|
-
end
|
17
|
+
@subject = Nokogiri::XML(s.to_xml)
|
24
18
|
end
|
25
19
|
|
26
20
|
def failure_message
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_speech
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Langfeld
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: niceogiri
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '1.1'
|
20
20
|
- - '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.1.
|
22
|
+
version: 1.1.2
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: '1.1'
|
30
30
|
- - '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.1.
|
32
|
+
version: 1.1.2
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: nokogiri
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,6 +238,7 @@ files:
|
|
238
238
|
- lib/ruby_speech/grxml/item.rb
|
239
239
|
- lib/ruby_speech/grxml/match.rb
|
240
240
|
- lib/ruby_speech/grxml/matcher.rb
|
241
|
+
- lib/ruby_speech/grxml/max_match.rb
|
241
242
|
- lib/ruby_speech/grxml/no_match.rb
|
242
243
|
- lib/ruby_speech/grxml/one_of.rb
|
243
244
|
- lib/ruby_speech/grxml/potential_match.rb
|
@@ -271,6 +272,7 @@ files:
|
|
271
272
|
- spec/ruby_speech/grxml/item_spec.rb
|
272
273
|
- spec/ruby_speech/grxml/match_spec.rb
|
273
274
|
- spec/ruby_speech/grxml/matcher_spec.rb
|
275
|
+
- spec/ruby_speech/grxml/max_match_spec.rb
|
274
276
|
- spec/ruby_speech/grxml/no_match_spec.rb
|
275
277
|
- spec/ruby_speech/grxml/one_of_spec.rb
|
276
278
|
- spec/ruby_speech/grxml/potential_match_spec.rb
|
@@ -296,6 +298,7 @@ files:
|
|
296
298
|
- spec/ruby_speech/ssml_spec.rb
|
297
299
|
- spec/ruby_speech_spec.rb
|
298
300
|
- spec/spec_helper.rb
|
301
|
+
- spec/support/match_examples.rb
|
299
302
|
- spec/support/matchers.rb
|
300
303
|
homepage: https://github.com/benlangfeld/ruby_speech
|
301
304
|
licenses: []
|
@@ -325,6 +328,7 @@ test_files:
|
|
325
328
|
- spec/ruby_speech/grxml/item_spec.rb
|
326
329
|
- spec/ruby_speech/grxml/match_spec.rb
|
327
330
|
- spec/ruby_speech/grxml/matcher_spec.rb
|
331
|
+
- spec/ruby_speech/grxml/max_match_spec.rb
|
328
332
|
- spec/ruby_speech/grxml/no_match_spec.rb
|
329
333
|
- spec/ruby_speech/grxml/one_of_spec.rb
|
330
334
|
- spec/ruby_speech/grxml/potential_match_spec.rb
|
@@ -350,5 +354,6 @@ test_files:
|
|
350
354
|
- spec/ruby_speech/ssml_spec.rb
|
351
355
|
- spec/ruby_speech_spec.rb
|
352
356
|
- spec/spec_helper.rb
|
357
|
+
- spec/support/match_examples.rb
|
353
358
|
- spec/support/matchers.rb
|
354
359
|
has_rdoc:
|