ruby_speech 0.5.0 → 0.5.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.
- data/CHANGELOG.md +5 -0
- data/lib/ruby_speech.rb +1 -0
- data/lib/ruby_speech/generic_element.rb +1 -0
- data/lib/ruby_speech/grxml.rb +1 -0
- data/lib/ruby_speech/grxml/element.rb +17 -0
- data/lib/ruby_speech/grxml/grammar.rb +21 -3
- data/lib/ruby_speech/grxml/item.rb +36 -7
- data/lib/ruby_speech/grxml/one_of.rb +4 -0
- data/lib/ruby_speech/grxml/potential_match.rb +10 -0
- data/lib/ruby_speech/grxml/token.rb +4 -0
- data/lib/ruby_speech/version.rb +1 -1
- data/spec/ruby_speech/grxml/grammar_spec.rb +226 -8
- data/spec/ruby_speech/grxml/item_spec.rb +427 -13
- data/spec/ruby_speech/grxml/one_of_spec.rb +237 -0
- data/spec/ruby_speech/grxml/potential_match_spec.rb +17 -0
- data/spec/ruby_speech/grxml/token_spec.rb +5 -0
- metadata +116 -176
@@ -8,7 +8,7 @@ module RubySpeech
|
|
8
8
|
its(:name) { should == 'item' }
|
9
9
|
|
10
10
|
its(:weight) { should == 1.1 }
|
11
|
-
its(:repeat) { should ==
|
11
|
+
its(:repeat) { should == 1 }
|
12
12
|
|
13
13
|
it 'registers itself' do
|
14
14
|
Element.class_from_registration(:item).should == Item
|
@@ -22,7 +22,7 @@ module RubySpeech
|
|
22
22
|
it { should be_instance_of Item }
|
23
23
|
|
24
24
|
its(:weight) { should == 1.1 }
|
25
|
-
its(:repeat) { should ==
|
25
|
+
its(:repeat) { should == 1 }
|
26
26
|
its(:content) { should == 'one' }
|
27
27
|
end
|
28
28
|
|
@@ -69,10 +69,19 @@ module RubySpeech
|
|
69
69
|
# Validate various values for repeat -- http://www.w3.org/TR/speech-grammar/#S2.5
|
70
70
|
describe "#repeat" do
|
71
71
|
context "exact" do
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
context "0" do
|
73
|
+
before { subject.repeat = 0 }
|
74
|
+
its(:repeat) { should == 0 }
|
75
|
+
end
|
76
|
+
|
77
|
+
context "5" do
|
78
|
+
before { subject.repeat = 5 }
|
79
|
+
its(:repeat) { should == 5 }
|
80
|
+
end
|
81
|
+
|
82
|
+
context "'1'" do
|
83
|
+
before { subject.repeat = '1' }
|
84
|
+
its(:repeat) { should == 1 }
|
76
85
|
end
|
77
86
|
|
78
87
|
it "invalid values" do
|
@@ -82,10 +91,21 @@ module RubySpeech
|
|
82
91
|
end
|
83
92
|
|
84
93
|
context "ranges" do
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
94
|
+
context "valid ranges from m to n" do
|
95
|
+
context "'1-5'" do
|
96
|
+
before { subject.repeat = '1-5' }
|
97
|
+
its(:repeat) { should == (1..5) }
|
98
|
+
end
|
99
|
+
|
100
|
+
context "'0-5'" do
|
101
|
+
before { subject.repeat = '0-5' }
|
102
|
+
its(:repeat) { should == (0..5) }
|
103
|
+
end
|
104
|
+
|
105
|
+
context "0..5" do
|
106
|
+
before { subject.repeat = 0..5 }
|
107
|
+
its(:repeat) { should == (0..5) }
|
108
|
+
end
|
89
109
|
end
|
90
110
|
|
91
111
|
it "illegal ranges from m to n" do
|
@@ -97,9 +117,18 @@ module RubySpeech
|
|
97
117
|
lambda { subject.repeat = 1..-2 }.should raise_error(ArgumentError, "A Item's repeat must be 0 or a positive integer")
|
98
118
|
end
|
99
119
|
|
100
|
-
|
101
|
-
|
102
|
-
|
120
|
+
context "valid ranges of m or more" do
|
121
|
+
context "'3-'" do
|
122
|
+
before { subject.repeat = '3-' }
|
123
|
+
its(:repeat) { should == (3..Item::Inf) }
|
124
|
+
its(:repeat) { should include 10000 }
|
125
|
+
end
|
126
|
+
|
127
|
+
context "'0-'" do
|
128
|
+
before { subject.repeat = '0-' }
|
129
|
+
its(:repeat) { should == (0..Item::Inf) }
|
130
|
+
its(:repeat) { should include 10000 }
|
131
|
+
end
|
103
132
|
end
|
104
133
|
|
105
134
|
it "illegal ranges for m or more" do
|
@@ -158,6 +187,391 @@ module RubySpeech
|
|
158
187
|
lambda { subject << Token.new }.should_not raise_error
|
159
188
|
end
|
160
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
|
161
575
|
end # Item
|
162
576
|
end # GRXML
|
163
577
|
end # RubySpeech
|