ruby_speech 0.1.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/.gitignore +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +4 -0
- data/LICENSE.md +20 -0
- data/README.md +76 -0
- data/Rakefile +22 -0
- data/assets/synthesis-core.xsd +442 -0
- data/assets/synthesis.xsd +63 -0
- data/assets/xml.xsd +287 -0
- data/lib/ruby_speech.rb +15 -0
- data/lib/ruby_speech/ssml.rb +24 -0
- data/lib/ruby_speech/ssml/break.rb +71 -0
- data/lib/ruby_speech/ssml/element.rb +26 -0
- data/lib/ruby_speech/ssml/emphasis.rb +53 -0
- data/lib/ruby_speech/ssml/prosody.rb +180 -0
- data/lib/ruby_speech/ssml/say_as.rb +109 -0
- data/lib/ruby_speech/ssml/speak.rb +57 -0
- data/lib/ruby_speech/ssml/voice.rb +125 -0
- data/lib/ruby_speech/version.rb +3 -0
- data/lib/ruby_speech/xml.rb +7 -0
- data/lib/ruby_speech/xml/language.rb +13 -0
- data/ruby_speech.gemspec +31 -0
- data/spec/ruby_speech/ssml/break_spec.rb +85 -0
- data/spec/ruby_speech/ssml/emphasis_spec.rb +100 -0
- data/spec/ruby_speech/ssml/prosody_spec.rb +286 -0
- data/spec/ruby_speech/ssml/say_as_spec.rb +61 -0
- data/spec/ruby_speech/ssml/speak_spec.rb +123 -0
- data/spec/ruby_speech/ssml/voice_spec.rb +188 -0
- data/spec/ruby_speech/ssml_spec.rb +65 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/matchers.rb +45 -0
- metadata +232 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
module SSML
|
5
|
+
describe SayAs do
|
6
|
+
subject { SayAs.new 'one', format: 'two', detail: 'three' }
|
7
|
+
|
8
|
+
its(:name) { should == 'say-as' }
|
9
|
+
|
10
|
+
its(:interpret_as) { should == 'one' }
|
11
|
+
its(:format) { should == 'two' }
|
12
|
+
its(:detail) { should == 'three' }
|
13
|
+
|
14
|
+
describe "without interpret_as" do
|
15
|
+
it "should raise an ArgumentError" do
|
16
|
+
expect { SayAs.new }.should raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "comparing objects" do
|
21
|
+
it "should be equal if the content, interpret_as, format, age, variant, name are the same" do
|
22
|
+
SayAs.new('jp', format: 'foo', detail: 'bar', content: "hello").should == SayAs.new('jp', format: 'foo', detail: 'bar', content: "hello")
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "when the content is different" do
|
26
|
+
it "should not be equal" do
|
27
|
+
SayAs.new('jp', content: "Hello").should_not == SayAs.new('jp', content: "Hello there")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "when the interpret_as is different" do
|
32
|
+
it "should not be equal" do
|
33
|
+
SayAs.new("Hello").should_not == SayAs.new("Hello there")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "when the format is different" do
|
38
|
+
it "should not be equal" do
|
39
|
+
SayAs.new('jp', format: 'foo').should_not == SayAs.new('jp', format: 'bar')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "when the detail is different" do
|
44
|
+
it "should not be equal" do
|
45
|
+
SayAs.new('jp', detail: 'foo').should_not == SayAs.new('jp', detail: 'bar')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "<<" do
|
51
|
+
it "should accept String" do
|
52
|
+
lambda { subject << 'anything' }.should_not raise_error
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should raise InvalidChildError with non-acceptable objects" do
|
56
|
+
lambda { subject << Voice.new }.should raise_error(InvalidChildError, "A SayAs can only accept Strings as children")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end # SayAs
|
60
|
+
end # SSML
|
61
|
+
end # RubySpeech
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
module SSML
|
5
|
+
describe Speak do
|
6
|
+
it { should be_a_valid_ssml_document }
|
7
|
+
|
8
|
+
its(:name) { should == 'speak' }
|
9
|
+
its(:language) { should == 'en-US' }
|
10
|
+
|
11
|
+
describe "setting options in initializers" do
|
12
|
+
subject { Speak.new :language => 'jp', :base_uri => 'blah' }
|
13
|
+
|
14
|
+
its(:language) { should == 'jp' }
|
15
|
+
its(:base_uri) { should == 'blah' }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#language" do
|
19
|
+
before { subject.language = 'jp' }
|
20
|
+
|
21
|
+
its(:language) { should == 'jp' }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#base_uri" do
|
25
|
+
before { subject.base_uri = 'blah' }
|
26
|
+
|
27
|
+
its(:base_uri) { should == 'blah' }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "comparing objects" do
|
31
|
+
it "should be equal if the content, language and base uri are the same" do
|
32
|
+
Speak.new(language: 'en-GB', base_uri: 'blah', content: "Hello there").should == Speak.new(language: 'en-GB', base_uri: 'blah', content: "Hello there")
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "when the content is different" do
|
36
|
+
it "should not be equal" do
|
37
|
+
Speak.new(content: "Hello").should_not == Speak.new(content: "Hello there")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "when the language is different" do
|
42
|
+
it "should not be equal" do
|
43
|
+
Speak.new(language: 'en-US').should_not == Speak.new(language: 'en-GB')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "when the base URI is different" do
|
48
|
+
it "should not be equal" do
|
49
|
+
Speak.new(base_uri: 'foo').should_not == Speak.new(base_uri: 'bar')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should allow creating child SSML elements" do
|
55
|
+
s = Speak.new
|
56
|
+
s.voice gender: :male, content: 'Hello'
|
57
|
+
expected_s = Speak.new
|
58
|
+
expected_s << Voice.new(gender: :male, content: 'Hello')
|
59
|
+
s.should == expected_s
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "<<" do
|
63
|
+
it "should accept String" do
|
64
|
+
lambda { subject << 'anything' }.should_not raise_error
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should accept Audio" do
|
68
|
+
pending
|
69
|
+
lambda { subject << Audio.new }.should_not raise_error
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should accept Break" do
|
73
|
+
lambda { subject << Break.new }.should_not raise_error
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should accept Emphasis" do
|
77
|
+
lambda { subject << Emphasis.new }.should_not raise_error
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should accept Mark" do
|
81
|
+
pending
|
82
|
+
lambda { subject << Mark.new }.should_not raise_error
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should accept P" do
|
86
|
+
pending
|
87
|
+
lambda { subject << P.new }.should_not raise_error
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should accept Phoneme" do
|
91
|
+
pending
|
92
|
+
lambda { subject << Phoneme.new }.should_not raise_error
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should accept Prosody" do
|
96
|
+
lambda { subject << Prosody.new }.should_not raise_error
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should accept SayAs" do
|
100
|
+
lambda { subject << SayAs.new(:interpret_as => :foo) }.should_not raise_error
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should accept Sub" do
|
104
|
+
pending
|
105
|
+
lambda { subject << Sub.new }.should_not raise_error
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should accept S" do
|
109
|
+
pending
|
110
|
+
lambda { subject << S.new }.should_not raise_error
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should accept Voice" do
|
114
|
+
lambda { subject << Voice.new }.should_not raise_error
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should raise InvalidChildError with non-acceptable objects" do
|
118
|
+
lambda { subject << 1 }.should raise_error(InvalidChildError, "A Speak can only accept String, Audio, Break, Emphasis, Mark, P, Phoneme, Prosody, SayAs, Sub, S, Voice as children")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end # Speak
|
122
|
+
end # SSML
|
123
|
+
end # RubySpeech
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
module SSML
|
5
|
+
describe Voice do
|
6
|
+
its(:node_name) { should == 'voice' }
|
7
|
+
its(:name) { should be_nil }
|
8
|
+
|
9
|
+
describe "setting options in initializers" do
|
10
|
+
subject { Voice.new :language => 'jp', :gender => :male, :age => 25, :variant => 2, :name => "paul" }
|
11
|
+
|
12
|
+
its(:language) { should == 'jp' }
|
13
|
+
its(:gender) { should == :male }
|
14
|
+
its(:age) { should == 25 }
|
15
|
+
its(:variant) { should == 2 }
|
16
|
+
its(:name) { should == 'paul' }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#language" do
|
20
|
+
before { subject.language = 'jp' }
|
21
|
+
|
22
|
+
its(:language) { should == 'jp' }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#gender" do
|
26
|
+
before { subject.gender = :male }
|
27
|
+
|
28
|
+
its(:gender) { should == :male }
|
29
|
+
|
30
|
+
it "with a valid gender" do
|
31
|
+
lambda { subject.gender = :male }.should_not raise_error
|
32
|
+
lambda { subject.gender = :female }.should_not raise_error
|
33
|
+
lambda { subject.gender = :neutral }.should_not raise_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it "with an invalid gender" do
|
37
|
+
lambda { subject.gender = :something }.should raise_error(ArgumentError, "You must specify a valid gender (:male, :female, :neutral)")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#age" do
|
42
|
+
before { subject.age = 12 }
|
43
|
+
|
44
|
+
its(:age) { should == 12 }
|
45
|
+
|
46
|
+
it "with an integer of 0" do
|
47
|
+
lambda { subject.age = 0 }.should_not raise_error
|
48
|
+
end
|
49
|
+
|
50
|
+
it "with an integer less than 0" do
|
51
|
+
lambda { subject.age = -1 }.should raise_error(ArgumentError, "You must specify a valid age (non-negative integer)")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "with something other than an integer" do
|
55
|
+
lambda { subject.age = "bah" }.should raise_error(ArgumentError, "You must specify a valid age (non-negative integer)")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#variant" do
|
60
|
+
before { subject.variant = 12 }
|
61
|
+
|
62
|
+
its(:variant) { should == 12 }
|
63
|
+
|
64
|
+
it "with an integer less than 1" do
|
65
|
+
lambda { subject.variant = 0 }.should raise_error(ArgumentError, "You must specify a valid variant (positive integer)")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "with something other than an integer" do
|
69
|
+
lambda { subject.variant = "bah" }.should raise_error(ArgumentError, "You must specify a valid variant (positive integer)")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#name" do
|
74
|
+
before { subject.name = 'george' }
|
75
|
+
|
76
|
+
its(:name) { should == 'george' }
|
77
|
+
|
78
|
+
context "with an array of names" do
|
79
|
+
before { subject.name = %w{george frank} }
|
80
|
+
|
81
|
+
its(:name) { should == %w{george frank} }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "comparing objects" do
|
86
|
+
it "should be equal if the content, language, gender, age, variant, name are the same" do
|
87
|
+
Voice.new(language: 'jp', gender: :male, age: 25, variant: 2, name: "paul", content: "hello").should == Voice.new(language: 'jp', gender: :male, age: 25, variant: 2, name: "paul", content: "hello")
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "when the content is different" do
|
91
|
+
it "should not be equal" do
|
92
|
+
Voice.new(content: "Hello").should_not == Voice.new(content: "Hello there")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "when the language is different" do
|
97
|
+
it "should not be equal" do
|
98
|
+
Voice.new(language: "Hello").should_not == Voice.new(language: "Hello there")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "when the gender is different" do
|
103
|
+
it "should not be equal" do
|
104
|
+
Voice.new(gender: :male).should_not == Voice.new(gender: :female)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "when the age is different" do
|
109
|
+
it "should not be equal" do
|
110
|
+
Voice.new(age: 20).should_not == Voice.new(age: 30)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "when the variant is different" do
|
115
|
+
it "should not be equal" do
|
116
|
+
Voice.new(variant: 1).should_not == Voice.new(variant: 2)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "when the name is different" do
|
121
|
+
it "should not be equal" do
|
122
|
+
Voice.new(name: "Hello").should_not == Voice.new(name: "Hello there")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "<<" do
|
128
|
+
it "should accept String" do
|
129
|
+
lambda { subject << 'anything' }.should_not raise_error
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should accept Audio" do
|
133
|
+
pending
|
134
|
+
lambda { subject << Audio.new }.should_not raise_error
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should accept Break" do
|
138
|
+
lambda { subject << Break.new }.should_not raise_error
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should accept Emphasis" do
|
142
|
+
lambda { subject << Emphasis.new }.should_not raise_error
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should accept Mark" do
|
146
|
+
pending
|
147
|
+
lambda { subject << Mark.new }.should_not raise_error
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should accept P" do
|
151
|
+
pending
|
152
|
+
lambda { subject << P.new }.should_not raise_error
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should accept Phoneme" do
|
156
|
+
pending
|
157
|
+
lambda { subject << Phoneme.new }.should_not raise_error
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should accept Prosody" do
|
161
|
+
lambda { subject << Prosody.new }.should_not raise_error
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should accept SayAs" do
|
165
|
+
lambda { subject << SayAs.new(:interpret_as => :foo) }.should_not raise_error
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should accept Sub" do
|
169
|
+
pending
|
170
|
+
lambda { subject << Sub.new }.should_not raise_error
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should accept S" do
|
174
|
+
pending
|
175
|
+
lambda { subject << S.new }.should_not raise_error
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should accept Voice" do
|
179
|
+
lambda { subject << Voice.new }.should_not raise_error
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should raise InvalidChildError with non-acceptable objects" do
|
183
|
+
lambda { subject << 1 }.should raise_error(InvalidChildError, "A Voice can only accept String, Audio, Break, Emphasis, Mark, P, Phoneme, Prosody, SayAs, Sub, S, Voice as children")
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end # Voice
|
187
|
+
end # SSML
|
188
|
+
end # RubySpeech
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RubySpeech
|
4
|
+
describe SSML do
|
5
|
+
describe "#draw" do
|
6
|
+
let(:expected_doc) { Nokogiri::XML::Document.new }
|
7
|
+
|
8
|
+
it "should create an SSML document" do
|
9
|
+
expected_doc << SSML::Speak.new
|
10
|
+
SSML.draw.should == expected_doc.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "when the return value of the block is a string" do
|
14
|
+
it "should be inserted into the document" do
|
15
|
+
expected_doc << SSML::Speak.new(content: "Hi, I'm Fred")
|
16
|
+
SSML.draw { "Hi, I'm Fred" }.should == expected_doc.to_s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "when the return value of the block is a string" do
|
21
|
+
it "should not be inserted into the document" do
|
22
|
+
expected_doc << SSML::Speak.new
|
23
|
+
SSML.draw { :foo }.should == expected_doc.to_s
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow other SSML elements to be inserted in the document" do
|
28
|
+
doc = SSML.draw { voice gender: :male, name: 'fred' }
|
29
|
+
speak = SSML::Speak.new
|
30
|
+
speak << SSML::Voice.new(gender: :male, name: 'fred')
|
31
|
+
expected_doc << speak
|
32
|
+
doc.should == expected_doc.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should allow nested block return values" do
|
36
|
+
doc = RubySpeech::SSML.draw do
|
37
|
+
voice gender: :male, name: 'fred' do
|
38
|
+
"Hi, I'm Fred."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
speak = SSML::Speak.new
|
42
|
+
speak << SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred.")
|
43
|
+
expected_doc << speak
|
44
|
+
doc.should == expected_doc.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should allow nested SSML elements" do
|
48
|
+
doc = RubySpeech::SSML.draw do
|
49
|
+
voice gender: :male, name: 'fred' do
|
50
|
+
string "Hi, I'm Fred. The time is currently "
|
51
|
+
say_as 'date', format: 'dmy' do
|
52
|
+
"01/02/1960"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
speak = SSML::Speak.new
|
57
|
+
voice = SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred. The time is currently ")
|
58
|
+
voice << SSML::SayAs.new('date', format: 'dmy', content: "01/02/1960")
|
59
|
+
speak << voice
|
60
|
+
expected_doc << speak
|
61
|
+
doc.should == expected_doc.to_s
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ruby_speech'
|
3
|
+
require 'mocha'
|
4
|
+
|
5
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
6
|
+
|
7
|
+
schema_file_path = File.expand_path File.join(__FILE__, '../../assets/synthesis.xsd')
|
8
|
+
puts "Loading the SSML Schema from #{schema_file_path}..."
|
9
|
+
SSML_SCHEMA = Nokogiri::XML::Schema File.open(schema_file_path)
|
10
|
+
puts "Finished loading schema."
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.mock_with :mocha
|
14
|
+
config.filter_run :focus => true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_xml(xml)
|
19
|
+
Nokogiri::XML.parse xml, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS
|
20
|
+
end
|