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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4f1b109d9aca99877fdea094ae7898d160c2bc5
4
- data.tar.gz: 61f380357241df94f39f25db15e17433d6766bb5
3
+ metadata.gz: de37299d09f7a9dc63c8c5944db79f80594bfffc
4
+ data.tar.gz: c01558ff39e76c034f1b18df7288c27d04ec84b1
5
5
  SHA512:
6
- metadata.gz: 01c6b26ae73ae0627b8ce474ea6fdddc8d0b87779a07c3908c57b71e3101ec8a447a8980a88d17de53c216442137122b03c821026146fd650066ec44030ce949
7
- data.tar.gz: 7075b29b0be7f4a7f1ca2b83fc3694be0e09566dbd0ef12be3c66933538cb885053d9971a933e094ac59c5090f56bdb82774ef0c3afcd69cd4eedc21d3a2bf82
6
+ metadata.gz: a2dc9ae2659cc93d40f7f0d55a2d6b4344accf12f7b1d7cf130aba09c4949a868bc47e2c641183aecad8bd42b0312a50d3a14d27eb9b933664fbaaa15de60cdc
7
+ data.tar.gz: 3df44bf14ab55473bd2dab097e2e972493744d299390085506e90ff437eb82441f535a3b29b1a45ac73d22c1770d0f4e4de9dbbb954d3d3c7c6983f12a741b75
data/.travis.yml CHANGED
@@ -7,7 +7,9 @@ rvm:
7
7
  - jruby-19mode
8
8
  - rbx-19mode
9
9
  - ruby-head
10
-
10
+ matrix:
11
+ allow_failures:
12
+ # - rvm: jruby-19mode
11
13
  before_install:
12
14
  - sudo apt-get install libpcre3 libpcre3-dev
13
15
 
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
@@ -1,5 +1,5 @@
1
1
  guard 'rake', :task => 'compile' do
2
- watch(%r{^ext/(.+)\.c$})
2
+ watch(%r{^ext/(.+)\.(c|java)$})
3
3
  end
4
4
 
5
5
  guard 'rspec', :cli => '--format documentation' do
@@ -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 check_potential_match(ThreadContext context, IRubyObject buffer)
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
- IRubyObject regex = getInstanceVariable("@regex");
30
-
31
- Pattern p = Pattern.compile(regex.toString());
32
- Matcher m = p.matcher(buffer.toString());
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 RuntimeHelpers.invoke(context, potential_match, "new");
47
+ return potential_match.callMethod(context, "new");
38
48
  }
39
- return runtime.getNil();
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 method_check_potential_match(VALUE self, VALUE buffer)
5
+ static VALUE method_compile_regex(VALUE self, VALUE regex_string)
6
6
  {
7
- int erroffset = 0;
8
- const char *errptr = "";
9
- int options = 0;
10
- VALUE regex_string = rb_funcall(rb_iv_get(self, "@regex"), rb_intern("to_s"), 0);
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[30];
17
- int workspace[1024];
62
+ int ovector[OVECTOR_SIZE];
63
+ int workspace[WORKSPACE_SIZE];
18
64
  char *input = StringValueCStr(buffer);
19
- result = pcre_dfa_exec(compiled_regex, NULL, input, strlen(input), 0, PCRE_PARTIAL,
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 RubySpeech = rb_const_get(rb_cObject, rb_intern("RubySpeech"));
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 Qnil;
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, "check_potential_match", method_check_potential_match, 1);
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 = type.to_s
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
- if namespace_href
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[@id!='#{root}']", :ns => namespace_href
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.is_a?(self.class) && [:mode, :confidence, :utterance, :interpretation].all? { |f| self.__send__(f) == o.__send__(f) }
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
- @regex = /^#{regexp_content.join}$/
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
- buffer = buffer.dup
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 check_full_match(buffer)
104
- match = regex.match buffer
105
-
106
- return unless match
107
-
108
- Match.new :mode => grammar.mode,
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)
@@ -0,0 +1,6 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ class MaxMatch < Match
4
+ end
5
+ end
6
+ end
@@ -15,6 +15,7 @@ module RubySpeech
15
15
 
16
16
  autoload :Match
17
17
  autoload :Matcher
18
+ autoload :MaxMatch
18
19
  autoload :NoMatch
19
20
  autoload :PotentialMatch
20
21
 
@@ -1,3 +1,3 @@
1
1
  module RubySpeech
2
- VERSION = "2.0.1"
2
+ VERSION = "2.0.2"
3
3
  end
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.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
- subject do
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 when mode, confidence, utterance and interpretation are the same" do
20
- Match.new(:mode => :dtmf, :confidence => 1, :utterance => '6', :interpretation => 'foo').should == Match.new(:mode => :dtmf, :confidence => 1, :utterance => '6', :interpretation => 'foo')
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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
- it "should potentially match '6'" do
357
- subject.match('6').should == GRXML::PotentialMatch.new
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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::Match.new :mode => :dtmf,
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
@@ -14,13 +14,7 @@ class SpeechDocMatcher
14
14
  end
15
15
 
16
16
  def subject=(s)
17
- if s.is_a? Nokogiri::XML::Document
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.1
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-04-27 00:00:00.000000000 Z
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.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.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: