ruby_speech 0.2.2 → 0.3.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.
@@ -0,0 +1,251 @@
1
+ require 'spec_helper'
2
+
3
+ module RubySpeech
4
+ describe GRXML do
5
+ describe "#draw" do
6
+ it "should create a GRXML document" do
7
+ GRXML.draw.should == GRXML::Grammar.new
8
+ end
9
+
10
+ it "should have a rule with id equal to the root attribute if set" do
11
+ pending 'check that a rule exists with the id equal to root if that attribute is set'
12
+ end
13
+
14
+ # TODO: Maybe GRXML#draw should create a Rule to pass the string
15
+ describe "when the return value of the block is a string" do
16
+ it "should be inserted into the document" do
17
+ lambda { GRXML.draw { "Hello Fred" }}.should raise_error(InvalidChildError, "A Grammar can only accept Rule and Tag as children")
18
+ end
19
+ end
20
+
21
+ it "should allow other GRXML elements to be inserted in the document" do
22
+ doc = GRXML.draw(:mode => :voice, :root => 'main') { rule :id => :main, :content => "Hello Fred" }
23
+
24
+ expected_doc = GRXML::Grammar.new(:mode => :voice, :root => 'main')
25
+ rule = GRXML::Rule.new(:id => "main")
26
+ rule << "Hello Fred"
27
+ expected_doc << rule
28
+ doc.should == expected_doc
29
+ end
30
+
31
+ it "should raise error if given an empty rule" do
32
+ pending 'Reject empty rules -- http://www.w3.org/TR/2002/CR-speech-grammar-20020626/#S3.1 http://www.w3.org/Voice/2003/srgs-ir/test/rule-no-empty.grxml'
33
+ lambda { GRXML.draw { rule :id => 'main' }}.should raise_error
34
+ end
35
+
36
+ it "should allow nested block return values" do
37
+ doc = RubySpeech::GRXML.draw do
38
+ rule :scope => 'public', :id => :main do
39
+ "Hello Fred"
40
+ end
41
+ end
42
+ expected_doc = GRXML::Grammar.new
43
+ expected_doc << GRXML::Rule.new(:scope => :public, :id => :main, :content => "Hello Fred")
44
+ doc.should == expected_doc
45
+ end
46
+
47
+ it "should allow nested GRXML elements" do
48
+ doc = RubySpeech::GRXML.draw do
49
+ rule :id => :main, :scope => 'public' do
50
+ string "Hello Fred. I like ninjas and pirates"
51
+ one_of do
52
+ item :content => "ninja"
53
+ item :content => "pirate"
54
+ end
55
+ end
56
+ end
57
+ rule = GRXML::Rule.new(:id => :main, :scope => 'public', :content => "Hello Fred. I like ninjas and pirates")
58
+ oneof = GRXML::OneOf.new
59
+ oneof << GRXML::Item.new(:content => "ninja")
60
+ oneof << GRXML::Item.new(:content => "pirate")
61
+ rule << oneof
62
+ expected_doc = GRXML::Grammar.new
63
+ expected_doc << rule
64
+ doc.should == expected_doc
65
+ end
66
+
67
+ # TODO: maybe turn a rule embedded in anthoer rule into a ruleref??
68
+ describe "embedding" do
69
+ context "GRXML documents" do
70
+ let :doc1 do
71
+ RubySpeech::GRXML.draw :mode => :dtmf, :root => 'digits' do
72
+ rule :id => :digits do
73
+ one_of do
74
+ item { "1" }
75
+ item { "2" }
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ let :doc2 do
82
+ doc = doc1
83
+ RubySpeech::GRXML.draw do
84
+ embed doc
85
+ rule :id => :main do
86
+ "Hello Fred"
87
+ end
88
+ end
89
+ end
90
+
91
+ let :expected_doc do
92
+ RubySpeech::GRXML.draw do
93
+ rule :id => :digits do
94
+ one_of do
95
+ item :content => "1"
96
+ item :content => "2"
97
+ end
98
+ end
99
+ rule :id => :main, :content => 'Hello Fred'
100
+ end
101
+ end
102
+
103
+ it "should embed the document" do
104
+ doc2.should == expected_doc
105
+ end
106
+
107
+ context "of different modes (dtmf in voice or vice-versa)" do
108
+ it "should raise an exception"
109
+ end
110
+ end
111
+
112
+ it "GRXML elements" do
113
+ element = GRXML::Item.new :content => "HELLO?"
114
+
115
+ doc = RubySpeech::GRXML.draw do
116
+ rule :id => :main, :scope => 'public' do
117
+ embed element
118
+ end
119
+ end
120
+
121
+ expected_doc = RubySpeech::GRXML.draw do
122
+ rule :id => :main, :scope => 'public' do
123
+ item do
124
+ "HELLO?"
125
+ end
126
+ end
127
+ end
128
+
129
+ doc.should == expected_doc
130
+ end
131
+
132
+ it "strings" do
133
+ string = "How now, brown cow?"
134
+
135
+ doc = RubySpeech::GRXML.draw do
136
+ rule :id => :main, :scope => 'public' do
137
+ embed string
138
+ end
139
+ end
140
+
141
+ expected_doc = RubySpeech::GRXML.draw do
142
+ rule :id => :main, :scope => 'public' do
143
+ string "How now, brown cow?"
144
+ end
145
+ end
146
+
147
+ doc.should == expected_doc
148
+ end
149
+ end
150
+
151
+ it "should properly escape string input" do
152
+ doc = RubySpeech::GRXML.draw do
153
+ rule { string "I <3 nachos." }
154
+ rule { "I <3 nachos." }
155
+ rule { 'I <3 nachos.' }
156
+ end
157
+ expected_doc = GRXML::Grammar.new
158
+ 3.times do
159
+ expected_doc << GRXML::Rule.new(:content => "I <3 nachos.")
160
+ end
161
+ doc.should == expected_doc
162
+ end
163
+
164
+ # TODO: verfify rule is in document if named in a ruleref
165
+ # TODO: ruleref must have named rule id
166
+
167
+ it "should allow all permutations of possible nested GRXML elements" do
168
+ doc = RubySpeech::GRXML.draw do
169
+ rule :id => "hello" do
170
+ string "HELLO?"
171
+ item :weight => 2.5
172
+ one_of do
173
+ item { "1" }
174
+ item { "2" }
175
+ end
176
+ ruleref :uri => '#test'
177
+ item { "last" }
178
+ end
179
+ rule :id => "test" do
180
+ string "TESTING"
181
+ end
182
+ rule :id => :hello2 do
183
+ item :weight => 5.5 do
184
+ "hello"
185
+ end
186
+ string "H...E...L...L...O?"
187
+ token { "test token" }
188
+ tag { }
189
+ item { "" }
190
+ one_of { item { "single item" } }
191
+ end
192
+ end
193
+ expected_doc = GRXML::Grammar.new
194
+ rule = GRXML::Rule.new(:id => "hello", :content => "HELLO?")
195
+ rule << GRXML::Item.new(:weight => 2.5)
196
+ oneof = GRXML::OneOf.new
197
+ 1.upto(2) { |d| oneof << GRXML::Item.new(:content => d.to_s) }
198
+ rule << oneof
199
+ rule << GRXML::Ruleref.new(:uri => '#test')
200
+ rule << GRXML::Item.new(:content => "last")
201
+ expected_doc << rule
202
+
203
+ rule = GRXML::Rule.new(:id => "test", :content => "TESTING")
204
+ expected_doc << rule
205
+
206
+ rule = GRXML::Rule.new(:id => "hello2")
207
+ rule << GRXML::Item.new(:weight => 5.5, :content => "hello")
208
+ rule << "H...E...L...L...O?"
209
+ rule << GRXML::Token.new(:content => "test token")
210
+ rule << GRXML::Tag.new
211
+ rule << GRXML::Item.new
212
+ oneof = GRXML::OneOf.new
213
+ oneof << GRXML::Item.new(:content => "single item")
214
+ rule << oneof
215
+ expected_doc << rule
216
+ doc.should == expected_doc
217
+ end
218
+
219
+ describe "importing nested tags" do
220
+ let(:item) { GRXML::Item.new(:weight => 1.5, :content => "Are you a pirate or ninja?") }
221
+ let(:string) { "Hello Fred. I like pirates and ninjas " }
222
+ let :rule do
223
+ GRXML::Rule.new(:id => :main, :scope => 'public', :content => string).tap do |rule|
224
+ rule << item
225
+ end
226
+ end
227
+
228
+ let :document do
229
+ GRXML::Grammar.new.tap { |doc| doc << rule }.to_s
230
+ end
231
+
232
+ let(:import) { GRXML::Element.import parse_xml(document).root }
233
+
234
+ subject { import }
235
+
236
+ it "should work" do
237
+ lambda { subject }.should_not raise_error
238
+ end
239
+
240
+ it { should be_a GRXML::Grammar }
241
+
242
+ its(:children) { should == [rule] }
243
+
244
+ describe "rule" do
245
+ subject { import.children.first }
246
+ its(:children) { should == [string,item] }
247
+ end
248
+ end
249
+ end # draw
250
+ end # GRXML
251
+ end # RubySpeech
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,9 @@ require 'rubygems'
2
2
  require 'ruby_speech'
3
3
  require 'mocha'
4
4
 
5
+ include RubySpeech::GRXML
6
+ include RubySpeech::XML::Language
7
+
5
8
  Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
6
9
 
7
10
  schema_file_path = File.expand_path File.join(__FILE__, '../../assets/synthesis.xsd')
@@ -9,6 +12,12 @@ puts "Loading the SSML Schema from #{schema_file_path}..."
9
12
  SSML_SCHEMA = Nokogiri::XML::Schema File.open(schema_file_path)
10
13
  puts "Finished loading schema."
11
14
 
15
+ schema_file_path = File.expand_path File.join(__FILE__, '../../assets/grammar.xsd')
16
+ puts "Loading the GRXML Schema from #{schema_file_path}..."
17
+ GRXML_SCHEMA = Nokogiri::XML::Schema File.open(schema_file_path)
18
+ puts "Finished loading schema."
19
+
20
+
12
21
  RSpec.configure do |config|
13
22
  config.mock_with :mocha
14
23
  config.filter_run :focus => true
@@ -1,3 +1,7 @@
1
+ def be_a_valid_grxml_document
2
+ GRXMLMatcher.new
3
+ end
4
+
1
5
  def be_a_valid_ssml_document
2
6
  SSMLMatcher.new
3
7
  end
@@ -43,3 +47,46 @@ class SSMLMatcher
43
47
  end
44
48
 
45
49
  end
50
+
51
+
52
+ class GRXMLMatcher
53
+ attr_reader :subject
54
+
55
+ def subject=(s)
56
+ if s.is_a? Nokogiri::XML::Document
57
+ @subject = s
58
+ else
59
+ doc = Nokogiri::XML::Document.new
60
+ doc << s
61
+ @subject = doc
62
+ end
63
+ end
64
+
65
+ def failure_message
66
+ " expected #{subject} to be a valid GRXML document\n#{errors}"
67
+ end
68
+
69
+ def negative_failure_message
70
+ " expected #{subject} not to be a valid GRXML document"
71
+ end
72
+
73
+ def description
74
+ "to be a valid GRXML document"
75
+ end
76
+
77
+ def matches?(s)
78
+ self.subject = s
79
+ GRXML_SCHEMA.valid? subject
80
+ end
81
+
82
+ def does_not_match?(s)
83
+ !matches? s
84
+ end
85
+
86
+ private
87
+
88
+ def errors
89
+ GRXML_SCHEMA.validate(subject).map(&:message).join "\n"
90
+ end
91
+
92
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_speech
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-12 00:00:00.000000000 +01:00
12
+ date: 2011-09-22 00:00:00.000000000 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: niceogiri
17
- requirement: &2153165820 !ruby/object:Gem::Requirement
17
+ requirement: &2164745280 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.0.4
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2153165820
25
+ version_requirements: *2164745280
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: activesupport
28
- requirement: &2153165300 !ruby/object:Gem::Requirement
28
+ requirement: &2164744760 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 3.0.7
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2153165300
36
+ version_requirements: *2164744760
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: bundler
39
- requirement: &2153164820 !ruby/object:Gem::Requirement
39
+ requirement: &2164744280 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 1.0.0
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *2153164820
47
+ version_requirements: *2164744280
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rspec
50
- requirement: &2153164340 !ruby/object:Gem::Requirement
50
+ requirement: &2164743800 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 2.3.0
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *2153164340
58
+ version_requirements: *2164743800
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: ci_reporter
61
- requirement: &2153163860 !ruby/object:Gem::Requirement
61
+ requirement: &2164743320 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 1.6.3
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *2153163860
69
+ version_requirements: *2164743320
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: yard
72
- requirement: &2153163380 !ruby/object:Gem::Requirement
72
+ requirement: &2164742820 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 0.7.0
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *2153163380
80
+ version_requirements: *2164742820
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rake
83
- requirement: &2153162900 !ruby/object:Gem::Requirement
83
+ requirement: &2164742300 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *2153162900
91
+ version_requirements: *2164742300
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: mocha
94
- requirement: &2153162420 !ruby/object:Gem::Requirement
94
+ requirement: &2164741820 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ! '>='
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: '0'
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *2153162420
102
+ version_requirements: *2164741820
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: i18n
105
- requirement: &2153161940 !ruby/object:Gem::Requirement
105
+ requirement: &2164741300 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - ! '>='
@@ -110,7 +110,7 @@ dependencies:
110
110
  version: '0'
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *2153161940
113
+ version_requirements: *2164741300
114
114
  description: Prepare SSML and GRXML documents with ease
115
115
  email:
116
116
  - ben@langfeld.me
@@ -126,10 +126,21 @@ files:
126
126
  - LICENSE.md
127
127
  - README.md
128
128
  - Rakefile
129
+ - assets/grammar-core.xsd
130
+ - assets/grammar.xsd
129
131
  - assets/synthesis-core.xsd
130
132
  - assets/synthesis.xsd
131
133
  - assets/xml.xsd
132
134
  - lib/ruby_speech.rb
135
+ - lib/ruby_speech/grxml.rb
136
+ - lib/ruby_speech/grxml/element.rb
137
+ - lib/ruby_speech/grxml/grammar.rb
138
+ - lib/ruby_speech/grxml/item.rb
139
+ - lib/ruby_speech/grxml/one_of.rb
140
+ - lib/ruby_speech/grxml/rule.rb
141
+ - lib/ruby_speech/grxml/ruleref.rb
142
+ - lib/ruby_speech/grxml/tag.rb
143
+ - lib/ruby_speech/grxml/token.rb
133
144
  - lib/ruby_speech/ssml.rb
134
145
  - lib/ruby_speech/ssml/audio.rb
135
146
  - lib/ruby_speech/ssml/break.rb
@@ -143,6 +154,14 @@ files:
143
154
  - lib/ruby_speech/xml.rb
144
155
  - lib/ruby_speech/xml/language.rb
145
156
  - ruby_speech.gemspec
157
+ - spec/ruby_speech/grxml/grammar_spec.rb
158
+ - spec/ruby_speech/grxml/item_spec.rb
159
+ - spec/ruby_speech/grxml/one_of_spec.rb
160
+ - spec/ruby_speech/grxml/rule_spec.rb
161
+ - spec/ruby_speech/grxml/ruleref_spec.rb
162
+ - spec/ruby_speech/grxml/tag_spec.rb
163
+ - spec/ruby_speech/grxml/token_spec.rb
164
+ - spec/ruby_speech/grxml_spec.rb
146
165
  - spec/ruby_speech/ssml/audio_spec.rb
147
166
  - spec/ruby_speech/ssml/break_spec.rb
148
167
  - spec/ruby_speech/ssml/emphasis_spec.rb
@@ -179,6 +198,14 @@ signing_key:
179
198
  specification_version: 3
180
199
  summary: A ruby library for TTS & ASR document preparation
181
200
  test_files:
201
+ - spec/ruby_speech/grxml/grammar_spec.rb
202
+ - spec/ruby_speech/grxml/item_spec.rb
203
+ - spec/ruby_speech/grxml/one_of_spec.rb
204
+ - spec/ruby_speech/grxml/rule_spec.rb
205
+ - spec/ruby_speech/grxml/ruleref_spec.rb
206
+ - spec/ruby_speech/grxml/tag_spec.rb
207
+ - spec/ruby_speech/grxml/token_spec.rb
208
+ - spec/ruby_speech/grxml_spec.rb
182
209
  - spec/ruby_speech/ssml/audio_spec.rb
183
210
  - spec/ruby_speech/ssml/break_spec.rb
184
211
  - spec/ruby_speech/ssml/emphasis_spec.rb