ruby_speech 1.1.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -187,391 +187,6 @@ module RubySpeech
187
187
  lambda { subject << Token.new }.should_not raise_error
188
188
  end
189
189
  end
190
-
191
- describe "#potential_match?" do
192
- subject { Item.new }
193
-
194
- before do
195
- tokens.each { |token| subject << token }
196
- subject.repeat = repeat if repeat
197
- end
198
-
199
- context "with a single token of '6'" do
200
- let(:tokens) { [Token.new << '6'] }
201
-
202
- context "with no repeat" do
203
- let(:repeat) { nil }
204
-
205
- it "should be true for '6'" do
206
- subject.potential_match?('6').should be true
207
- end
208
-
209
- %w{5 55 65 66}.each do |input|
210
- it "should be false for '#{input}'" do
211
- subject.potential_match?(input).should be false
212
- end
213
- end
214
- end
215
-
216
- context "with an absolute repeat of 3" do
217
- let(:repeat) { 3 }
218
-
219
- %w{6 66 666}.each do |input|
220
- it "should be true for '#{input}'" do
221
- subject.potential_match?(input).should be true
222
- end
223
- end
224
-
225
- %w{5 55 65 6666}.each do |input|
226
- it "should be false for '#{input}'" do
227
- subject.potential_match?(input).should be false
228
- end
229
- end
230
- end
231
-
232
- context "with a range repeat of 0..2" do
233
- let(:repeat) { 0..2 }
234
-
235
- it "should be true for ''" do
236
- subject.potential_match?('').should be true
237
- end
238
-
239
- %w{6 66}.each do |input|
240
- it "should be true for '#{input}'" do
241
- subject.potential_match?(input).should be true
242
- end
243
- end
244
-
245
- %w{5 55 65 666}.each do |input|
246
- it "should be false for '#{input}'" do
247
- subject.potential_match?(input).should be false
248
- end
249
- end
250
- end
251
-
252
- context "with a minimum repeat of 2" do
253
- let(:repeat) { 2..Item::Inf }
254
-
255
- %w{6 66 666 6666 66666}.each do |input|
256
- it "should be true for '#{input}'" do
257
- subject.potential_match?(input).should be true
258
- end
259
- end
260
-
261
- %w{5 55 65}.each do |input|
262
- it "should be false for '#{input}'" do
263
- subject.potential_match?(input).should be false
264
- end
265
- end
266
- end
267
- end
268
-
269
- context "with a collection of two tokens of '6' and '7'" do
270
- let(:tokens) { [Token.new << '6', Token.new << '7'] }
271
-
272
- context "with no repeat" do
273
- let(:repeat) { nil }
274
-
275
- %w{6 67}.each do |input|
276
- it "should be true for '#{input}'" do
277
- subject.potential_match?(input).should be true
278
- end
279
- end
280
-
281
- %w{5 55 65 66 676}.each do |input|
282
- it "should be false for '#{input}'" do
283
- subject.potential_match?(input).should be false
284
- end
285
- end
286
- end
287
-
288
- context "with an absolute repeat of 3" do
289
- let(:repeat) { 3 }
290
-
291
- %w{6 67 676 6767 67676 676767}.each do |input|
292
- it "should be true for '#{input}'" do
293
- subject.potential_match?(input).should be true
294
- end
295
- end
296
-
297
- %w{5 57 66 677 5767 67677 676766 6767676}.each do |input|
298
- it "should be false for '#{input}'" do
299
- subject.potential_match?(input).should be false
300
- end
301
- end
302
- end
303
-
304
- context "with a range repeat of 0..2" do
305
- let(:repeat) { 0..2 }
306
-
307
- it "should be true for ''" do
308
- subject.potential_match?('').should be true
309
- end
310
-
311
- %w{6 67 676 6767}.each do |input|
312
- it "should be true for '#{input}'" do
313
- subject.potential_match?(input).should be true
314
- end
315
- end
316
-
317
- %w{5 57 66 677 5767 67676 67677 676766 6767676}.each do |input|
318
- it "should be false for '#{input}'" do
319
- subject.potential_match?(input).should be false
320
- end
321
- end
322
- end
323
-
324
- context "with a minimum repeat of 2" do
325
- let(:repeat) { 2..Item::Inf }
326
-
327
- %w{6 67 676 6767 67676 676767 67676767}.each do |input|
328
- it "should be true for '#{input}'" do
329
- subject.potential_match?(input).should be true
330
- end
331
- end
332
-
333
- %w{5 57 66 677 5767 67677 676766}.each do |input|
334
- it "should be false for '#{input}'" do
335
- subject.potential_match?(input).should be false
336
- end
337
- end
338
- end
339
- end
340
-
341
- context "with a nested item" do
342
- let(:repeat) { nil }
343
- let(:tokens) { [Item.new << (Token.new << '6') << (Token.new << '6')] }
344
-
345
- before do
346
- tokens.each { |token| token.repeat = nested_repeat if nested_repeat }
347
- end
348
-
349
- context "with no repeat" do
350
- before { pending }
351
- let(:nested_repeat) { nil }
352
-
353
- %w{6 66}.each do |input|
354
- it "should be true for '#{input}'" do
355
- subject.potential_match?(input).should be true
356
- end
357
- end
358
-
359
- %w{5 55 65 666}.each do |input|
360
- it "should be false for '#{input}'" do
361
- subject.potential_match?(input).should be false
362
- end
363
- end
364
- end
365
-
366
- context "with an absolute repeat of 3" do
367
- before { pending }
368
- let(:nested_repeat) { 3 }
369
-
370
- %w{6 66 666}.each do |input|
371
- it "should be true for '#{input}'" do
372
- subject.potential_match?(input).should be true
373
- end
374
- end
375
-
376
- %w{5 55 6666}.each do |input|
377
- it "should be false for '#{input}'" do
378
- subject.potential_match?(input).should be false
379
- end
380
- end
381
- end
382
-
383
- context "with a range repeat of 0..2" do
384
- before { pending }
385
- let(:nested_repeat) { 0..2 }
386
-
387
- it "should be true for ''" do
388
- subject.potential_match?('').should be true
389
- end
390
-
391
- %w{6 67 676 6767}.each do |input|
392
- it "should be true for '#{input}'" do
393
- subject.potential_match?(input).should be true
394
- end
395
- end
396
-
397
- %w{5 57 66 677 5767 67676 67677 676766 6767676}.each do |input|
398
- it "should be false for '#{input}'" do
399
- subject.potential_match?(input).should be false
400
- end
401
- end
402
- end
403
-
404
- context "with a minimum repeat of 2" do
405
- before { pending }
406
- let(:nested_repeat) { 2..Item::Inf }
407
-
408
- %w{6 67 676 6767 67676 676767 67676767}.each do |input|
409
- it "should be true for '#{input}'" do
410
- subject.potential_match?(input).should be true
411
- end
412
- end
413
-
414
- %w{5 57 66 677 5767 67677 676766}.each do |input|
415
- it "should be false for '#{input}'" do
416
- subject.potential_match?(input).should be false
417
- end
418
- end
419
- end
420
- end
421
- end
422
-
423
- describe "#longest_potential_match" do
424
- subject { Item.new }
425
-
426
- before do
427
- tokens.each { |token| subject << token }
428
- subject.repeat = repeat if repeat
429
- end
430
-
431
- context "with a single token of '6'" do
432
- let(:tokens) { [Token.new << '6'] }
433
-
434
- context "with no repeat" do
435
- let(:repeat) { nil }
436
-
437
- %w{6 65 6776}.each do |input|
438
- it "should be '6' for '#{input}'" do
439
- subject.longest_potential_match(input).should == '6'
440
- end
441
- end
442
-
443
- %w{5 7 55 56}.each do |input|
444
- it "should be '' for '#{input}'" do
445
- subject.longest_potential_match(input).should == ''
446
- end
447
- end
448
- end
449
-
450
- context "with an absolute repeat of 3" do
451
- let(:repeat) { 3 }
452
-
453
- {
454
- '6' => '6',
455
- '66' => '66',
456
- '666' => '666',
457
- '6666' => '666',
458
- '66666' => '666'
459
- }.each do |input, match|
460
- it "should be '#{match}' for '#{input}'" do
461
- subject.longest_potential_match(input).should == match
462
- end
463
- end
464
- end
465
-
466
- context "with a range repeat of 0..2" do
467
- let(:repeat) { 0..2 }
468
-
469
- {
470
- '6' => '6',
471
- '66' => '66',
472
- '666' => '66',
473
- '6666' => '66'
474
- }.each do |input, match|
475
- it "should be '#{match}' for '#{input}'" do
476
- subject.longest_potential_match(input).should == match
477
- end
478
- end
479
- end
480
-
481
- context "with a minimum repeat of 2" do
482
- let(:repeat) { 2..Item::Inf }
483
-
484
- {
485
- '6' => '6',
486
- '66' => '66',
487
- '666' => '666',
488
- '6666' => '6666',
489
- '6'*100 => '6'*100
490
- }.each do |input, match|
491
- it "should be '#{match}' for '#{input}'" do
492
- subject.longest_potential_match(input).should == match
493
- end
494
- end
495
- end
496
- end
497
-
498
- context "with a collection of two tokens of '6' and '7'" do
499
- let(:tokens) { [Token.new << '6', Token.new << '7'] }
500
-
501
- context "with no repeat" do
502
- let(:repeat) { nil }
503
-
504
- {
505
- '6' => '6',
506
- '66' => '6',
507
- '67' => '67',
508
- '676' => '67',
509
- '6767' => '67'
510
- }.each do |input, match|
511
- it "should be '#{match}' for '#{input}'" do
512
- subject.longest_potential_match(input).should == match
513
- end
514
- end
515
- end
516
-
517
- context "with an absolute repeat of 3" do
518
- let(:repeat) { 3 }
519
-
520
- {
521
- '6' => '6',
522
- '66' => '6',
523
- '67' => '67',
524
- '676' => '676',
525
- '6767' => '6767',
526
- '67676' => '67676',
527
- '676767' => '676767',
528
- '6767676' => '676767'
529
- }.each do |input, match|
530
- it "should be '#{match}' for '#{input}'" do
531
- subject.longest_potential_match(input).should == match
532
- end
533
- end
534
- end
535
-
536
- context "with a range repeat of 0..2" do
537
- let(:repeat) { 0..2 }
538
-
539
- {
540
- '6' => '6',
541
- '66' => '6',
542
- '67' => '67',
543
- '676' => '676',
544
- '6767' => '6767',
545
- '67676' => '6767',
546
- '676767' => '6767'
547
- }.each do |input, match|
548
- it "should be '#{match}' for '#{input}'" do
549
- subject.longest_potential_match(input).should == match
550
- end
551
- end
552
- end
553
-
554
- context "with a minimum repeat of 2" do
555
- let(:repeat) { 2..Item::Inf }
556
-
557
- {
558
- '6' => '6',
559
- '66' => '6',
560
- '67' => '67',
561
- '676' => '676',
562
- '6767' => '6767',
563
- '67676' => '67676',
564
- '676767' => '676767',
565
- '6767676' => '6767676',
566
- '67'*100 => '67'*100
567
- }.each do |input, match|
568
- it "should be '#{match}' for '#{input}'" do
569
- subject.longest_potential_match(input).should == match
570
- end
571
- end
572
- end
573
- end
574
- end
575
190
  end # Item
576
191
  end # GRXML
577
192
  end # RubySpeech
@@ -0,0 +1,644 @@
1
+ require 'spec_helper'
2
+
3
+ module RubySpeech
4
+ module GRXML
5
+ describe Matcher do
6
+ let(:grammar) { nil }
7
+
8
+ subject { described_class.new grammar }
9
+
10
+ describe "matching against an input string" do
11
+ context "with a grammar that takes a single specific digit" do
12
+ let(:grammar) do
13
+ GRXML.draw :mode => :dtmf, :root => 'digit' do
14
+ rule :id => 'digit' do
15
+ '6'
16
+ end
17
+ end
18
+ end
19
+
20
+ it "should match '6'" do
21
+ input = '6'
22
+ expected_match = GRXML::Match.new :mode => :dtmf,
23
+ :confidence => 1,
24
+ :utterance => '6',
25
+ :interpretation => 'dtmf-6'
26
+ subject.match(input).should == expected_match
27
+ input.should == '6'
28
+ end
29
+
30
+ %w{1 2 3 4 5 7 8 9 10 66 26 61}.each do |input|
31
+ it "should not match '#{input}'" do
32
+ subject.match(input).should == GRXML::NoMatch.new
33
+ end
34
+ end
35
+ end
36
+
37
+ context "with a grammar that takes two specific digits" do
38
+ let(:grammar) do
39
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
40
+ rule :id => 'digits' do
41
+ '5 6'
42
+ end
43
+ end
44
+ end
45
+
46
+ it "should match '56'" do
47
+ expected_match = GRXML::Match.new :mode => :dtmf,
48
+ :confidence => 1,
49
+ :utterance => '56',
50
+ :interpretation => 'dtmf-5 dtmf-6'
51
+ subject.match('56').should == expected_match
52
+ end
53
+
54
+ it "should potentially match '5'" do
55
+ input = '5'
56
+ subject.match(input).should == GRXML::PotentialMatch.new
57
+ input.should == '5'
58
+ end
59
+
60
+ %w{* *7 #6 6* 1 2 3 4 6 7 8 9 10 65 57 46 26 61}.each do |input|
61
+ it "should not match '#{input}'" do
62
+ subject.match(input).should == GRXML::NoMatch.new
63
+ end
64
+ end
65
+ end
66
+
67
+ context "with a grammar that takes star and a digit" do
68
+ let(:grammar) do
69
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
70
+ rule :id => 'digits' do
71
+ '* 6'
72
+ end
73
+ end
74
+ end
75
+
76
+ it "should match '*6'" do
77
+ expected_match = GRXML::Match.new :mode => :dtmf,
78
+ :confidence => 1,
79
+ :utterance => '*6',
80
+ :interpretation => 'dtmf-star dtmf-6'
81
+ subject.match('*6').should == expected_match
82
+ end
83
+
84
+ it "should potentially match '*'" do
85
+ subject.match('*').should == GRXML::PotentialMatch.new
86
+ end
87
+
88
+ %w{*7 #6 6* 1 2 3 4 5 6 7 8 9 10 66 26 61}.each do |input|
89
+ it "should not match '#{input}'" do
90
+ subject.match(input).should == GRXML::NoMatch.new
91
+ end
92
+ end
93
+ end
94
+
95
+ context "with a grammar that takes hash and a digit" do
96
+ let(:grammar) do
97
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
98
+ rule :id => 'digits' do
99
+ '# 6'
100
+ end
101
+ end
102
+ end
103
+
104
+ it "should match '#6'" do
105
+ expected_match = GRXML::Match.new :mode => :dtmf,
106
+ :confidence => 1,
107
+ :utterance => '#6',
108
+ :interpretation => 'dtmf-pound dtmf-6'
109
+ subject.match('#6').should == expected_match
110
+ end
111
+
112
+ it "should potentially match '#'" do
113
+ subject.match('#').should == GRXML::PotentialMatch.new
114
+ end
115
+
116
+ %w{* *6 #7 6* 1 2 3 4 5 6 7 8 9 10 66 26 61}.each do |input|
117
+ it "should not match '#{input}'" do
118
+ subject.match(input).should == GRXML::NoMatch.new
119
+ end
120
+ end
121
+ end
122
+
123
+ context "with a grammar that takes two specific digits, via a ruleref, and whitespace normalization" do
124
+ let(:grammar) do
125
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
126
+ rule :id => 'digits' do
127
+ ruleref :uri => '#star'
128
+ '" 6 "'
129
+ end
130
+
131
+ rule :id => 'star' do
132
+ '" * "'
133
+ end
134
+ end
135
+ end
136
+
137
+ it "should match '*6'" do
138
+ expected_match = GRXML::Match.new :mode => :dtmf,
139
+ :confidence => 1,
140
+ :utterance => '*6',
141
+ :interpretation => 'dtmf-star dtmf-6'
142
+ subject.match('*6').should == expected_match
143
+ end
144
+
145
+ it "should potentially match '*'" do
146
+ subject.match('*').should == GRXML::PotentialMatch.new
147
+ end
148
+
149
+ %w{*7 #6 6* 1 2 3 4 5 6 7 8 9 10 66 26 61}.each do |input|
150
+ it "should not match '#{input}'" do
151
+ subject.match(input).should == GRXML::NoMatch.new
152
+ end
153
+ end
154
+ end
155
+
156
+ context "with a grammar that takes a single digit alternative" do
157
+ let(:grammar) do
158
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
159
+ rule :id => 'digits' do
160
+ one_of do
161
+ item { '6' }
162
+ item { '7' }
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ it "should match '6'" do
169
+ expected_match = GRXML::Match.new :mode => :dtmf,
170
+ :confidence => 1,
171
+ :utterance => '6',
172
+ :interpretation => 'dtmf-6'
173
+ subject.match('6').should == expected_match
174
+ end
175
+
176
+ it "should match '7'" do
177
+ expected_match = GRXML::Match.new :mode => :dtmf,
178
+ :confidence => 1,
179
+ :utterance => '7',
180
+ :interpretation => 'dtmf-7'
181
+ subject.match('7').should == expected_match
182
+ end
183
+
184
+ %w{* # 1 2 3 4 5 8 9 10 66 26 61}.each do |input|
185
+ it "should not match '#{input}'" do
186
+ subject.match(input).should == GRXML::NoMatch.new
187
+ end
188
+ end
189
+ end
190
+
191
+ context "with a grammar that takes a double digit alternative" do
192
+ let(:grammar) do
193
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
194
+ rule :id => 'digits' do
195
+ one_of do
196
+ item do
197
+ token { '6' }
198
+ token { '5' }
199
+ end
200
+ item do
201
+ token { '7' }
202
+ token { '2' }
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+
209
+ it "should match '65'" do
210
+ expected_match = GRXML::Match.new :mode => :dtmf,
211
+ :confidence => 1,
212
+ :utterance => '65',
213
+ :interpretation => 'dtmf-6 dtmf-5'
214
+ subject.match('65').should == expected_match
215
+ end
216
+
217
+ it "should match '72'" do
218
+ expected_match = GRXML::Match.new :mode => :dtmf,
219
+ :confidence => 1,
220
+ :utterance => '72',
221
+ :interpretation => 'dtmf-7 dtmf-2'
222
+ subject.match('72').should == expected_match
223
+ end
224
+
225
+ %w{6 7}.each do |input|
226
+ it "should potentially match '#{input}'" do
227
+ subject.match(input).should == GRXML::PotentialMatch.new
228
+ end
229
+ end
230
+
231
+ %w{* # 1 2 3 4 5 8 9 10 66 26 61 75}.each do |input|
232
+ it "should not match '#{input}'" do
233
+ subject.match(input).should == GRXML::NoMatch.new
234
+ end
235
+ end
236
+ end
237
+
238
+ context "with a grammar that takes a triple digit alternative" do
239
+ let(:grammar) do
240
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
241
+ rule :id => 'digits' do
242
+ one_of do
243
+ item do
244
+ token { '6' }
245
+ token { '5' }
246
+ token { '2' }
247
+ end
248
+ item do
249
+ token { '7' }
250
+ token { '2' }
251
+ token { '8' }
252
+ end
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ it "should match '652'" do
259
+ expected_match = GRXML::Match.new :mode => :dtmf,
260
+ :confidence => 1,
261
+ :utterance => '652',
262
+ :interpretation => 'dtmf-6 dtmf-5 dtmf-2'
263
+ subject.match('652').should == expected_match
264
+ end
265
+
266
+ it "should match '728'" do
267
+ expected_match = GRXML::Match.new :mode => :dtmf,
268
+ :confidence => 1,
269
+ :utterance => '728',
270
+ :interpretation => 'dtmf-7 dtmf-2 dtmf-8'
271
+ subject.match('728').should == expected_match
272
+ end
273
+
274
+ %w{6 65 7 72}.each do |input|
275
+ it "should potentially match '#{input}'" do
276
+ subject.match(input).should == GRXML::PotentialMatch.new
277
+ end
278
+ end
279
+
280
+ %w{* # 1 2 3 4 5 8 9 10 66 26 61 75 729 654}.each do |input|
281
+ it "should not match '#{input}'" do
282
+ subject.match(input).should == GRXML::NoMatch.new
283
+ end
284
+ end
285
+ end
286
+
287
+ context "with a grammar that takes two specific digits with the second being an alternative" do
288
+ let(:grammar) do
289
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
290
+ rule :id => 'digits' do
291
+ string '*'
292
+ one_of do
293
+ item { '6' }
294
+ item { '7' }
295
+ end
296
+ end
297
+ end
298
+ end
299
+
300
+ it "should match '*6'" do
301
+ expected_match = GRXML::Match.new :mode => :dtmf,
302
+ :confidence => 1,
303
+ :utterance => '*6',
304
+ :interpretation => 'dtmf-star dtmf-6'
305
+ subject.match('*6').should == expected_match
306
+ end
307
+
308
+ it "should match '*7'" do
309
+ expected_match = GRXML::Match.new :mode => :dtmf,
310
+ :confidence => 1,
311
+ :utterance => '*7',
312
+ :interpretation => 'dtmf-star dtmf-7'
313
+ subject.match('*7').should == expected_match
314
+ end
315
+
316
+ it "should potentially match '*'" do
317
+ subject.match('*').should == GRXML::PotentialMatch.new
318
+ end
319
+
320
+ %w{*8 #6 6* 1 2 3 4 5 6 7 8 9 10 66 26 61}.each do |input|
321
+ it "should not match '#{input}'" do
322
+ subject.match(input).should == GRXML::NoMatch.new
323
+ end
324
+ end
325
+ end
326
+
327
+ context "with a grammar that takes two specific digits with the first being an alternative" do
328
+ let(:grammar) do
329
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
330
+ rule :id => 'digits' do
331
+ one_of do
332
+ item { '6' }
333
+ item { '7' }
334
+ end
335
+ string '*'
336
+ end
337
+ end
338
+ end
339
+
340
+ it "should match '6*'" do
341
+ expected_match = GRXML::Match.new :mode => :dtmf,
342
+ :confidence => 1,
343
+ :utterance => '6*',
344
+ :interpretation => 'dtmf-6 dtmf-star'
345
+ subject.match('6*').should == expected_match
346
+ end
347
+
348
+ it "should match '7*'" do
349
+ expected_match = GRXML::Match.new :mode => :dtmf,
350
+ :confidence => 1,
351
+ :utterance => '7*',
352
+ :interpretation => 'dtmf-7 dtmf-star'
353
+ subject.match('7*').should == expected_match
354
+ end
355
+
356
+ it "should potentially match '6'" do
357
+ subject.match('6').should == GRXML::PotentialMatch.new
358
+ end
359
+
360
+ it "should potentially match '7'" do
361
+ subject.match('7').should == GRXML::PotentialMatch.new
362
+ end
363
+
364
+ %w{8* 6# *6 *7 1 2 3 4 5 8 9 10 66 26 61}.each do |input|
365
+ it "should not match '#{input}'" do
366
+ subject.match(input).should == GRXML::NoMatch.new
367
+ end
368
+ end
369
+ end
370
+
371
+ context "with a grammar that takes a specific digit, followed by a specific digit repeated an exact number of times" do
372
+ let(:grammar) do
373
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
374
+ rule :id => 'digits' do
375
+ string '1'
376
+ item :repeat => 2 do
377
+ '6'
378
+ end
379
+ end
380
+ end
381
+ end
382
+
383
+ it "should match '166'" do
384
+ expected_match = GRXML::Match.new :mode => :dtmf,
385
+ :confidence => 1,
386
+ :utterance => '166',
387
+ :interpretation => 'dtmf-1 dtmf-6 dtmf-6'
388
+ subject.match('166').should == expected_match
389
+ end
390
+
391
+ %w{1 16}.each do |input|
392
+ it "should potentially match '#{input}'" do
393
+ subject.match(input).should == GRXML::PotentialMatch.new
394
+ end
395
+ end
396
+
397
+ %w{1666 16666 17}.each do |input|
398
+ it "should not match '#{input}'" do
399
+ subject.match(input).should == GRXML::NoMatch.new
400
+ end
401
+ end
402
+ end
403
+
404
+ context "with a grammar that takes a specific digit repeated an exact number of times, followed by a specific digit" do
405
+ let(:grammar) do
406
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
407
+ rule :id => 'digits' do
408
+ item :repeat => 2 do
409
+ '6'
410
+ end
411
+ string '1'
412
+ end
413
+ end
414
+ end
415
+
416
+ it "should match '661'" do
417
+ expected_match = GRXML::Match.new :mode => :dtmf,
418
+ :confidence => 1,
419
+ :utterance => '661',
420
+ :interpretation => 'dtmf-6 dtmf-6 dtmf-1'
421
+ subject.match('661').should == expected_match
422
+ end
423
+
424
+ %w{6 66}.each do |input|
425
+ it "should potentially match '#{input}'" do
426
+ subject.match(input).should == GRXML::PotentialMatch.new
427
+ end
428
+ end
429
+
430
+ %w{61 6661 66661 71 771}.each do |input|
431
+ it "should not match '#{input}'" do
432
+ subject.match(input).should == GRXML::NoMatch.new
433
+ end
434
+ end
435
+ end
436
+
437
+ context "with a grammar that takes a specific digit, followed by a specific digit repeated within a range" do
438
+ let(:grammar) do
439
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
440
+ rule :id => 'digits' do
441
+ string '1'
442
+ item :repeat => 0..3 do
443
+ '6'
444
+ end
445
+ end
446
+ end
447
+ end
448
+
449
+ {
450
+ '1' => 'dtmf-1',
451
+ '16' => 'dtmf-1 dtmf-6',
452
+ '166' => 'dtmf-1 dtmf-6 dtmf-6',
453
+ '1666' => 'dtmf-1 dtmf-6 dtmf-6 dtmf-6'
454
+ }.each_pair do |input, interpretation|
455
+ it "should match '#{input}'" do
456
+ expected_match = GRXML::Match.new :mode => :dtmf,
457
+ :confidence => 1,
458
+ :utterance => input,
459
+ :interpretation => interpretation
460
+ subject.match(input).should == expected_match
461
+ end
462
+ end
463
+
464
+ %w{6 16666 17}.each do |input|
465
+ it "should not match '#{input}'" do
466
+ subject.match(input).should == GRXML::NoMatch.new
467
+ end
468
+ end
469
+ end
470
+
471
+ context "with a grammar that takes a a specific digit repeated within a range, followed by specific digit" do
472
+ let(:grammar) do
473
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
474
+ rule :id => 'digits' do
475
+ item :repeat => 0..3 do
476
+ '6'
477
+ end
478
+ string '1'
479
+ end
480
+ end
481
+ end
482
+
483
+ {
484
+ '1' => 'dtmf-1',
485
+ '61' => 'dtmf-6 dtmf-1',
486
+ '661' => 'dtmf-6 dtmf-6 dtmf-1',
487
+ '6661' => 'dtmf-6 dtmf-6 dtmf-6 dtmf-1'
488
+ }.each_pair do |input, interpretation|
489
+ it "should match '#{input}'" do
490
+ expected_match = GRXML::Match.new :mode => :dtmf,
491
+ :confidence => 1,
492
+ :utterance => input,
493
+ :interpretation => interpretation
494
+ subject.match(input).should == expected_match
495
+ end
496
+ end
497
+
498
+ %w{6 66 666}.each do |input|
499
+ it "should potentially match '#{input}'" do
500
+ subject.match(input).should == GRXML::PotentialMatch.new
501
+ end
502
+ end
503
+
504
+ %w{66661 71}.each do |input|
505
+ it "should not match '#{input}'" do
506
+ subject.match(input).should == GRXML::NoMatch.new
507
+ end
508
+ end
509
+ end
510
+
511
+ context "with a grammar that takes a specific digit, followed by a specific digit repeated a minimum number of times" do
512
+ let(:grammar) do
513
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
514
+ rule :id => 'digits' do
515
+ string '1'
516
+ item :repeat => '2-' do
517
+ '6'
518
+ end
519
+ end
520
+ end
521
+ end
522
+
523
+ {
524
+ '166' => 'dtmf-1 dtmf-6 dtmf-6',
525
+ '1666' => 'dtmf-1 dtmf-6 dtmf-6 dtmf-6',
526
+ '16666' => 'dtmf-1 dtmf-6 dtmf-6 dtmf-6 dtmf-6'
527
+ }.each_pair do |input, interpretation|
528
+ it "should match '#{input}'" do
529
+ expected_match = GRXML::Match.new :mode => :dtmf,
530
+ :confidence => 1,
531
+ :utterance => input,
532
+ :interpretation => interpretation
533
+ subject.match(input).should == expected_match
534
+ end
535
+ end
536
+
537
+ %w{1 16}.each do |input|
538
+ it "should potentially match '#{input}'" do
539
+ subject.match(input).should == GRXML::PotentialMatch.new
540
+ end
541
+ end
542
+
543
+ %w{7 17}.each do |input|
544
+ it "should not match '#{input}'" do
545
+ subject.match(input).should == GRXML::NoMatch.new
546
+ end
547
+ end
548
+ end
549
+
550
+ context "with a grammar that takes a specific digit repeated a minimum number of times, followed by a specific digit" do
551
+ let(:grammar) do
552
+ GRXML.draw :mode => :dtmf, :root => 'digits' do
553
+ rule :id => 'digits' do
554
+ item :repeat => '2-' do
555
+ '6'
556
+ end
557
+ string '1'
558
+ end
559
+ end
560
+ end
561
+
562
+ {
563
+ '661' => 'dtmf-6 dtmf-6 dtmf-1',
564
+ '6661' => 'dtmf-6 dtmf-6 dtmf-6 dtmf-1',
565
+ '66661' => 'dtmf-6 dtmf-6 dtmf-6 dtmf-6 dtmf-1'
566
+ }.each_pair do |input, interpretation|
567
+ it "should match '#{input}'" do
568
+ expected_match = GRXML::Match.new :mode => :dtmf,
569
+ :confidence => 1,
570
+ :utterance => input,
571
+ :interpretation => interpretation
572
+ subject.match(input).should == expected_match
573
+ end
574
+ end
575
+
576
+ %w{6 66}.each do |input|
577
+ it "should potentially match '#{input}'" do
578
+ subject.match(input).should == GRXML::PotentialMatch.new
579
+ end
580
+ end
581
+
582
+ %w{7 71 61}.each do |input|
583
+ it "should not match '#{input}'" do
584
+ subject.match(input).should == GRXML::NoMatch.new
585
+ end
586
+ end
587
+ end
588
+
589
+ context "with a grammar that takes a 4 digit pin terminated by hash, or the *9 escape sequence" do
590
+ let(:grammar) do
591
+ RubySpeech::GRXML.draw :mode => :dtmf, :root => 'pin' do
592
+ rule :id => 'digit' do
593
+ one_of do
594
+ ('0'..'9').map { |d| item { d } }
595
+ end
596
+ end
597
+
598
+ rule :id => 'pin', :scope => 'public' do
599
+ one_of do
600
+ item do
601
+ item :repeat => '4' do
602
+ ruleref :uri => '#digit'
603
+ end
604
+ "#"
605
+ end
606
+ item do
607
+ "\* 9"
608
+ end
609
+ end
610
+ end
611
+ end
612
+ end
613
+
614
+ {
615
+ '*9' => 'dtmf-star dtmf-9',
616
+ '1234#' => 'dtmf-1 dtmf-2 dtmf-3 dtmf-4 dtmf-pound',
617
+ '5678#' => 'dtmf-5 dtmf-6 dtmf-7 dtmf-8 dtmf-pound',
618
+ '1111#' => 'dtmf-1 dtmf-1 dtmf-1 dtmf-1 dtmf-pound'
619
+ }.each_pair do |input, interpretation|
620
+ it "should match '#{input}'" do
621
+ expected_match = GRXML::Match.new :mode => :dtmf,
622
+ :confidence => 1,
623
+ :utterance => input,
624
+ :interpretation => interpretation
625
+ subject.match(input).should == expected_match
626
+ end
627
+ end
628
+
629
+ %w{* 1 12 123 1234}.each do |input|
630
+ it "should potentially match '#{input}'" do
631
+ subject.match(input).should == GRXML::PotentialMatch.new
632
+ end
633
+ end
634
+
635
+ %w{11111 #1111 *7}.each do |input|
636
+ it "should not match '#{input}'" do
637
+ subject.match(input).should == GRXML::NoMatch.new
638
+ end
639
+ end
640
+ end
641
+ end
642
+ end # Grammar
643
+ end # GRXML
644
+ end # RubySpeech