ruby_speech 0.4.0 → 0.5.0
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 +15 -0
- data/README.md +108 -14
- data/lib/ruby_speech/generic_element.rb +71 -10
- data/lib/ruby_speech/grxml.rb +4 -1
- data/lib/ruby_speech/grxml/element.rb +4 -0
- data/lib/ruby_speech/grxml/grammar.rb +177 -46
- data/lib/ruby_speech/grxml/item.rb +12 -11
- data/lib/ruby_speech/grxml/match.rb +16 -0
- data/lib/ruby_speech/grxml/no_match.rb +10 -0
- data/lib/ruby_speech/grxml/one_of.rb +4 -11
- data/lib/ruby_speech/grxml/rule.rb +0 -11
- data/lib/ruby_speech/grxml/ruleref.rb +0 -11
- data/lib/ruby_speech/grxml/tag.rb +0 -11
- data/lib/ruby_speech/grxml/token.rb +8 -11
- data/lib/ruby_speech/ssml.rb +6 -0
- data/lib/ruby_speech/ssml/audio.rb +1 -12
- data/lib/ruby_speech/ssml/break.rb +0 -11
- data/lib/ruby_speech/ssml/desc.rb +24 -0
- data/lib/ruby_speech/ssml/emphasis.rb +1 -12
- data/lib/ruby_speech/ssml/mark.rb +43 -0
- data/lib/ruby_speech/ssml/p.rb +25 -0
- data/lib/ruby_speech/ssml/phoneme.rb +72 -0
- data/lib/ruby_speech/ssml/prosody.rb +1 -12
- data/lib/ruby_speech/ssml/s.rb +25 -0
- data/lib/ruby_speech/ssml/say_as.rb +0 -11
- data/lib/ruby_speech/ssml/speak.rb +2 -44
- data/lib/ruby_speech/ssml/sub.rb +42 -0
- data/lib/ruby_speech/ssml/voice.rb +1 -12
- data/lib/ruby_speech/version.rb +1 -1
- data/spec/ruby_speech/grxml/grammar_spec.rb +478 -35
- data/spec/ruby_speech/grxml/item_spec.rb +5 -2
- data/spec/ruby_speech/grxml/match_spec.rb +49 -0
- data/spec/ruby_speech/grxml/no_match_spec.rb +17 -0
- data/spec/ruby_speech/grxml/one_of_spec.rb +1 -1
- data/spec/ruby_speech/grxml/rule_spec.rb +1 -1
- data/spec/ruby_speech/grxml/ruleref_spec.rb +1 -1
- data/spec/ruby_speech/grxml/tag_spec.rb +1 -1
- data/spec/ruby_speech/grxml/token_spec.rb +11 -1
- data/spec/ruby_speech/grxml_spec.rb +64 -5
- data/spec/ruby_speech/ssml/audio_spec.rb +5 -6
- data/spec/ruby_speech/ssml/break_spec.rb +1 -1
- data/spec/ruby_speech/ssml/desc_spec.rb +57 -0
- data/spec/ruby_speech/ssml/emphasis_spec.rb +1 -4
- data/spec/ruby_speech/ssml/mark_spec.rb +53 -0
- data/spec/ruby_speech/ssml/p_spec.rb +96 -0
- data/spec/ruby_speech/ssml/phoneme_spec.rb +65 -0
- data/spec/ruby_speech/ssml/prosody_spec.rb +9 -4
- data/spec/ruby_speech/ssml/s_spec.rb +92 -0
- data/spec/ruby_speech/ssml/say_as_spec.rb +1 -1
- data/spec/ruby_speech/ssml/speak_spec.rb +1 -6
- data/spec/ruby_speech/ssml/sub_spec.rb +57 -0
- data/spec/ruby_speech/ssml/voice_spec.rb +1 -6
- data/spec/spec_helper.rb +0 -4
- data/spec/support/matchers.rb +13 -53
- metadata +200 -113
@@ -17,7 +17,7 @@ module RubySpeech
|
|
17
17
|
describe "everything from a document" do
|
18
18
|
let(:document) { '<item weight="1.1" repeat="1">one</item>' }
|
19
19
|
|
20
|
-
subject { Element.import
|
20
|
+
subject { Element.import document }
|
21
21
|
|
22
22
|
it { should be_instance_of Item }
|
23
23
|
|
@@ -28,7 +28,7 @@ module RubySpeech
|
|
28
28
|
|
29
29
|
describe "#weight" do
|
30
30
|
context "from a document" do
|
31
|
-
subject { Element.import
|
31
|
+
subject { Element.import document }
|
32
32
|
|
33
33
|
describe "using .1" do
|
34
34
|
let(:document) { '<item weight=".1" repeat="1">one</item>' }
|
@@ -85,6 +85,7 @@ module RubySpeech
|
|
85
85
|
it "valid ranges from m to n" do
|
86
86
|
lambda { subject.repeat = '1-5' }.should_not raise_error
|
87
87
|
lambda { subject.repeat = '0-5' }.should_not raise_error
|
88
|
+
lambda { subject.repeat = 0..5 }.should_not raise_error
|
88
89
|
end
|
89
90
|
|
90
91
|
it "illegal ranges from m to n" do
|
@@ -92,6 +93,8 @@ module RubySpeech
|
|
92
93
|
lambda { subject.repeat = '-1-2' }.should raise_error(ArgumentError, "A Item's repeat must be 0 or a positive integer")
|
93
94
|
lambda { subject.repeat = '1-2-3' }.should raise_error(ArgumentError, "A Item's repeat must be 0 or a positive integer")
|
94
95
|
lambda { subject.repeat = '1-B' }.should raise_error(ArgumentError, "A Item's repeat must be 0 or a positive integer")
|
96
|
+
lambda { subject.repeat = -1..2 }.should raise_error(ArgumentError, "A Item's repeat must be 0 or a positive integer")
|
97
|
+
lambda { subject.repeat = 1..-2 }.should raise_error(ArgumentError, "A Item's repeat must be 0 or a positive integer")
|
95
98
|
end
|
96
99
|
|
97
100
|
it "valid ranges of m or more" do
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
module GRXML
|
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' }
|
17
|
+
|
18
|
+
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
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
module GRXML
|
5
|
+
describe NoMatch do
|
6
|
+
describe "equality" do
|
7
|
+
it "should be equal to another NoMatch" do
|
8
|
+
NoMatch.new.should == NoMatch.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not equal a match" do
|
12
|
+
NoMatch.new.should_not == Match.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -17,7 +17,7 @@ module RubySpeech
|
|
17
17
|
describe "from a document" do
|
18
18
|
let(:document) { '<rule id="one" scope="public"> <item /> </rule>' }
|
19
19
|
|
20
|
-
subject { Element.import
|
20
|
+
subject { Element.import document }
|
21
21
|
|
22
22
|
it { should be_instance_of Rule }
|
23
23
|
|
@@ -12,7 +12,7 @@ module RubySpeech
|
|
12
12
|
describe "from a document" do
|
13
13
|
let(:document) { '<token>hello</token>' }
|
14
14
|
|
15
|
-
subject { Element.import
|
15
|
+
subject { Element.import document }
|
16
16
|
|
17
17
|
it { should be_instance_of Token }
|
18
18
|
|
@@ -25,6 +25,16 @@ module RubySpeech
|
|
25
25
|
its(:language) { should == 'jp' }
|
26
26
|
end
|
27
27
|
|
28
|
+
describe "#normalize_whitespace" do
|
29
|
+
it "should remove leading & trailing whitespace and collapse multiple spaces down to 1" do
|
30
|
+
element = Element.import '<token> Welcome to San Francisco </token>'
|
31
|
+
|
32
|
+
element.normalize_whitespace
|
33
|
+
|
34
|
+
element.content.should == 'Welcome to San Francisco'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
28
38
|
describe "comparing objects" do
|
29
39
|
it "should be equal if the content is the same" do
|
30
40
|
Token.new(:content => "hello").should == Token.new(:content => "hello")
|
@@ -7,8 +7,16 @@ module RubySpeech
|
|
7
7
|
GRXML.draw.should == GRXML::Grammar.new
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
context "with a root rule name specified but not found" do
|
11
|
+
it "should raise an error" do
|
12
|
+
lambda do
|
13
|
+
GRXML.draw :root => 'foo' do
|
14
|
+
rule :id => 'bar' do
|
15
|
+
'6'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end.should raise_error(InvalidChildError, "A GRXML document must have a rule matching the root rule name")
|
19
|
+
end
|
12
20
|
end
|
13
21
|
|
14
22
|
# TODO: Maybe GRXML#draw should create a Rule to pass the string
|
@@ -95,7 +103,7 @@ module RubySpeech
|
|
95
103
|
|
96
104
|
let :doc2 do
|
97
105
|
doc = doc1
|
98
|
-
RubySpeech::GRXML.draw do
|
106
|
+
RubySpeech::GRXML.draw :mode => :dtmf do
|
99
107
|
embed doc
|
100
108
|
rule :id => :main do
|
101
109
|
"Hello Fred"
|
@@ -104,7 +112,7 @@ module RubySpeech
|
|
104
112
|
end
|
105
113
|
|
106
114
|
let :expected_doc do
|
107
|
-
RubySpeech::GRXML.draw do
|
115
|
+
RubySpeech::GRXML.draw :mode => :dtmf do
|
108
116
|
rule :id => :digits do
|
109
117
|
one_of do
|
110
118
|
item :content => "1"
|
@@ -120,7 +128,23 @@ module RubySpeech
|
|
120
128
|
end
|
121
129
|
|
122
130
|
context "of different modes (dtmf in voice or vice-versa)" do
|
123
|
-
|
131
|
+
let :voice_doc do
|
132
|
+
GRXML.draw :mode => :voice do
|
133
|
+
embed dtmf_doc
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
let :dtmf_doc do
|
138
|
+
GRXML.draw :mode => :dtmf do
|
139
|
+
rule do
|
140
|
+
'6'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should raise an exception" do
|
146
|
+
lambda { voice_doc }.should raise_error(InvalidChildError, "Embedded grammars must have the same mode")
|
147
|
+
end
|
124
148
|
end
|
125
149
|
end
|
126
150
|
|
@@ -275,6 +299,41 @@ module RubySpeech
|
|
275
299
|
|
276
300
|
item.children(:item, :weight => 0.5).should == [item1]
|
277
301
|
end
|
302
|
+
|
303
|
+
it "should be able to traverse up the tree" do
|
304
|
+
grammar = GRXML.draw do
|
305
|
+
rule :id => 'one' do
|
306
|
+
item do
|
307
|
+
'foobar'
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
rule = grammar.children.first
|
313
|
+
rule.parent.should == grammar
|
314
|
+
|
315
|
+
item = rule.children.first
|
316
|
+
item.parent.should == rule
|
317
|
+
|
318
|
+
text = item.nokogiri_children.first
|
319
|
+
text.parent.should == item
|
320
|
+
end
|
278
321
|
end # draw
|
322
|
+
|
323
|
+
describe "manually created documents" do
|
324
|
+
it "should be able to traverse up the tree" do
|
325
|
+
grammar = GRXML::Grammar.new
|
326
|
+
rule = GRXML::Rule.new :id => 'one'
|
327
|
+
item = GRXML::Item.new
|
328
|
+
text = Nokogiri::XML::Text.new 'foobar', grammar.document
|
329
|
+
item << text
|
330
|
+
rule << item
|
331
|
+
grammar << rule
|
332
|
+
|
333
|
+
text.parent.should == item
|
334
|
+
item.parent.should == rule
|
335
|
+
rule.parent.should == grammar
|
336
|
+
end
|
337
|
+
end
|
279
338
|
end # GRXML
|
280
339
|
end # RubySpeech
|
@@ -19,7 +19,7 @@ module RubySpeech
|
|
19
19
|
describe "from a document" do
|
20
20
|
let(:document) { '<audio src="http://whatever.you-say-boss.com">Hello</audio>' }
|
21
21
|
|
22
|
-
subject { Element.import
|
22
|
+
subject { Element.import document }
|
23
23
|
|
24
24
|
it { should be_instance_of Audio }
|
25
25
|
|
@@ -54,22 +54,23 @@ module RubySpeech
|
|
54
54
|
lambda { subject << Break.new }.should_not raise_error
|
55
55
|
end
|
56
56
|
|
57
|
+
it "should accept Desc" do
|
58
|
+
lambda { subject << Desc.new }.should_not raise_error
|
59
|
+
end
|
60
|
+
|
57
61
|
it "should accept Emphasis" do
|
58
62
|
lambda { subject << Emphasis.new }.should_not raise_error
|
59
63
|
end
|
60
64
|
|
61
65
|
it "should accept Mark" do
|
62
|
-
pending
|
63
66
|
lambda { subject << Mark.new }.should_not raise_error
|
64
67
|
end
|
65
68
|
|
66
69
|
it "should accept P" do
|
67
|
-
pending
|
68
70
|
lambda { subject << P.new }.should_not raise_error
|
69
71
|
end
|
70
72
|
|
71
73
|
it "should accept Phoneme" do
|
72
|
-
pending
|
73
74
|
lambda { subject << Phoneme.new }.should_not raise_error
|
74
75
|
end
|
75
76
|
|
@@ -82,12 +83,10 @@ module RubySpeech
|
|
82
83
|
end
|
83
84
|
|
84
85
|
it "should accept Sub" do
|
85
|
-
pending
|
86
86
|
lambda { subject << Sub.new }.should_not raise_error
|
87
87
|
end
|
88
88
|
|
89
89
|
it "should accept S" do
|
90
|
-
pending
|
91
90
|
lambda { subject << S.new }.should_not raise_error
|
92
91
|
end
|
93
92
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
module SSML
|
5
|
+
describe Desc do
|
6
|
+
its(:name) { should == 'desc' }
|
7
|
+
|
8
|
+
describe "setting options in initializers" do
|
9
|
+
subject { Desc.new :language => 'foo' }
|
10
|
+
|
11
|
+
its(:language) { should == 'foo' }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'registers itself' do
|
15
|
+
Element.class_from_registration(:desc).should == Desc
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "from a document" do
|
19
|
+
let(:document) { '<desc xml:lang="en"/>' }
|
20
|
+
|
21
|
+
subject { Element.import document }
|
22
|
+
|
23
|
+
it { should be_instance_of Desc }
|
24
|
+
|
25
|
+
its(:language) { should == 'en' }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "comparing objects" do
|
29
|
+
it "should be equal if the content and language are the same" do
|
30
|
+
Desc.new(:language => 'jp', :content => "Hello there").should == Desc.new(:language => 'jp', :content => "Hello there")
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "when the content is different" do
|
34
|
+
it "should not be equal" do
|
35
|
+
Desc.new(:content => "Hello").should_not == Desc.new(:content => "Hello there")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "when the language is different" do
|
40
|
+
it "should not be equal" do
|
41
|
+
Desc.new(:language => 'jp').should_not == Desc.new(:language => 'en')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "<<" do
|
47
|
+
it "should accept String" do
|
48
|
+
lambda { subject << 'anything' }.should_not raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should raise InvalidChildError with non-acceptable objects" do
|
52
|
+
lambda { subject << Voice.new }.should raise_error(InvalidChildError, "A Desc can only accept Strings as children")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end # Desc
|
56
|
+
end # SSML
|
57
|
+
end # RubySpeech
|
@@ -18,7 +18,7 @@ module RubySpeech
|
|
18
18
|
describe "from a document" do
|
19
19
|
let(:document) { '<emphasis level="strong"/>' }
|
20
20
|
|
21
|
-
subject { Element.import
|
21
|
+
subject { Element.import document }
|
22
22
|
|
23
23
|
it { should be_instance_of Emphasis }
|
24
24
|
|
@@ -78,12 +78,10 @@ module RubySpeech
|
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should accept Mark" do
|
81
|
-
pending
|
82
81
|
lambda { subject << Mark.new }.should_not raise_error
|
83
82
|
end
|
84
83
|
|
85
84
|
it "should accept Phoneme" do
|
86
|
-
pending
|
87
85
|
lambda { subject << Phoneme.new }.should_not raise_error
|
88
86
|
end
|
89
87
|
|
@@ -96,7 +94,6 @@ module RubySpeech
|
|
96
94
|
end
|
97
95
|
|
98
96
|
it "should accept Sub" do
|
99
|
-
pending
|
100
97
|
lambda { subject << Sub.new }.should_not raise_error
|
101
98
|
end
|
102
99
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
module SSML
|
5
|
+
describe Mark do
|
6
|
+
its(:element_name) { should == 'mark' }
|
7
|
+
|
8
|
+
describe "setting options in initializers" do
|
9
|
+
subject { Mark.new :name => 'foo' }
|
10
|
+
|
11
|
+
its(:name) { should == 'foo' }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'registers itself' do
|
15
|
+
Element.class_from_registration(:mark).should == Mark
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "from a document" do
|
19
|
+
let(:document) { '<mark name="foo"/>' }
|
20
|
+
|
21
|
+
subject { Element.import document }
|
22
|
+
|
23
|
+
it { should be_instance_of Mark }
|
24
|
+
|
25
|
+
its(:name) { should == 'foo' }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#name" do
|
29
|
+
before { subject.name = 'foo' }
|
30
|
+
|
31
|
+
its(:name) { should == 'foo' }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "<<" do
|
35
|
+
it "should always raise InvalidChildError" do
|
36
|
+
lambda { subject << 'anything' }.should raise_error(InvalidChildError, "A Mark cannot contain children")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "comparing objects" do
|
41
|
+
it "should be equal if the name is the same" do
|
42
|
+
Mark.new(:name => "foo").should == Mark.new(:name => "foo")
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "when the name is different" do
|
46
|
+
it "should not be equal" do
|
47
|
+
Mark.new(:name => "foo").should_not == Mark.new(:name => "bar")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end # Mark
|
52
|
+
end # SSML
|
53
|
+
end # RubySpeech
|