ruby_speech 2.3.1 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.hound.yml +2 -0
  4. data/.travis.yml +25 -9
  5. data/CHANGELOG.md +19 -1
  6. data/README.md +14 -15
  7. data/Rakefile +2 -0
  8. data/ext/ruby_speech/RubySpeechGRXMLMatcher.java +17 -12
  9. data/ext/ruby_speech/RubySpeechService.java +1 -1
  10. data/ext/ruby_speech/extconf.rb +1 -1
  11. data/lib/ruby_speech/generic_element.rb +2 -2
  12. data/lib/ruby_speech/grxml/builtins.rb +18 -11
  13. data/lib/ruby_speech/grxml/grammar.rb +26 -4
  14. data/lib/ruby_speech/grxml/matcher.rb +2 -2
  15. data/lib/ruby_speech/grxml.rb +2 -0
  16. data/lib/ruby_speech/nlsml/builder.rb +2 -1
  17. data/lib/ruby_speech/nlsml/document.rb +5 -0
  18. data/lib/ruby_speech/ssml/break.rb +1 -2
  19. data/lib/ruby_speech/ssml/element.rb +13 -1
  20. data/lib/ruby_speech/ssml/mark.rb +0 -1
  21. data/lib/ruby_speech/ssml/prosody.rb +8 -5
  22. data/lib/ruby_speech/version.rb +1 -1
  23. data/ruby_speech.gemspec +13 -8
  24. data/spec/ruby_speech/grxml/builtins_spec.rb +80 -71
  25. data/spec/ruby_speech/grxml/grammar_spec.rb +168 -34
  26. data/spec/ruby_speech/grxml/item_spec.rb +33 -33
  27. data/spec/ruby_speech/grxml/match_spec.rb +1 -1
  28. data/spec/ruby_speech/grxml/matcher_spec.rb +103 -59
  29. data/spec/ruby_speech/grxml/max_match_spec.rb +2 -2
  30. data/spec/ruby_speech/grxml/no_match_spec.rb +2 -2
  31. data/spec/ruby_speech/grxml/one_of_spec.rb +6 -6
  32. data/spec/ruby_speech/grxml/potential_match_spec.rb +2 -2
  33. data/spec/ruby_speech/grxml/rule_spec.rb +17 -17
  34. data/spec/ruby_speech/grxml/ruleref_spec.rb +10 -10
  35. data/spec/ruby_speech/grxml/tag_spec.rb +5 -5
  36. data/spec/ruby_speech/grxml/token_spec.rb +7 -7
  37. data/spec/ruby_speech/grxml_spec.rb +25 -25
  38. data/spec/ruby_speech/nlsml_spec.rb +58 -10
  39. data/spec/ruby_speech/ssml/audio_spec.rb +19 -19
  40. data/spec/ruby_speech/ssml/break_spec.rb +42 -22
  41. data/spec/ruby_speech/ssml/desc_spec.rb +7 -7
  42. data/spec/ruby_speech/ssml/emphasis_spec.rb +21 -21
  43. data/spec/ruby_speech/ssml/mark_spec.rb +5 -5
  44. data/spec/ruby_speech/ssml/p_spec.rb +17 -17
  45. data/spec/ruby_speech/ssml/phoneme_spec.rb +8 -8
  46. data/spec/ruby_speech/ssml/prosody_spec.rb +82 -64
  47. data/spec/ruby_speech/ssml/s_spec.rb +16 -16
  48. data/spec/ruby_speech/ssml/say_as_spec.rb +9 -9
  49. data/spec/ruby_speech/ssml/speak_spec.rb +29 -29
  50. data/spec/ruby_speech/ssml/sub_spec.rb +7 -7
  51. data/spec/ruby_speech/ssml/voice_spec.rb +31 -31
  52. data/spec/ruby_speech/ssml_spec.rb +41 -17
  53. data/spec/ruby_speech_spec.rb +3 -3
  54. data/spec/spec_helper.rb +8 -3
  55. data/spec/support/dtmf_helper.rb +14 -0
  56. data/spec/support/grammar_matchers.rb +6 -6
  57. data/spec/support/match_examples.rb +5 -5
  58. data/spec/support/matchers.rb +1 -1
  59. metadata +49 -20
@@ -4,22 +4,22 @@ describe RubySpeech::GRXML::Builtins do
4
4
  describe "boolean" do
5
5
  subject(:grammar) { described_class.boolean }
6
6
 
7
- it { should max_match('1').and_interpret_as('true') }
8
- it { should max_match('2').and_interpret_as('false') }
7
+ it { is_expected.to max_match('1').and_interpret_as('true') }
8
+ it { is_expected.to max_match('2').and_interpret_as('false') }
9
9
 
10
- it { should not_match('0') }
11
- it { should not_match('3') }
12
- it { should not_match('10') }
10
+ it { is_expected.to not_match('0') }
11
+ it { is_expected.to not_match('3') }
12
+ it { is_expected.to not_match('10') }
13
13
 
14
14
  context "with the true/false digits parameterized" do
15
15
  subject { described_class.boolean y: 3, n: 7 }
16
16
 
17
- it { should max_match('3').and_interpret_as('true') }
18
- it { should max_match('7').and_interpret_as('false') }
17
+ it { is_expected.to max_match('3').and_interpret_as('true') }
18
+ it { is_expected.to max_match('7').and_interpret_as('false') }
19
19
 
20
- it { should not_match('1') }
21
- it { should not_match('2') }
22
- it { should not_match('4') }
20
+ it { is_expected.to not_match('1') }
21
+ it { is_expected.to not_match('2') }
22
+ it { is_expected.to not_match('4') }
23
23
 
24
24
  context "both the same" do
25
25
  it "should raise ArgumentError" do
@@ -32,54 +32,54 @@ describe RubySpeech::GRXML::Builtins do
32
32
  describe "date" do
33
33
  subject(:grammar) { described_class.date }
34
34
 
35
- it { should max_match('20130929').and_interpret_as('dtmf-2 dtmf-0 dtmf-1 dtmf-3 dtmf-0 dtmf-9 dtmf-2 dtmf-9') }
35
+ it { is_expected.to max_match('20130929').and_interpret_as('dtmf-2 dtmf-0 dtmf-1 dtmf-3 dtmf-0 dtmf-9 dtmf-2 dtmf-9') }
36
36
 
37
- it { should potentially_match('130929') }
38
- it { should potentially_match('0929') }
39
- it { should potentially_match('29') }
40
- it { should potentially_match('1') }
37
+ it { is_expected.to potentially_match('130929') }
38
+ it { is_expected.to potentially_match('0929') }
39
+ it { is_expected.to potentially_match('29') }
40
+ it { is_expected.to potentially_match('1') }
41
41
  end
42
42
 
43
43
  describe "digits" do
44
44
  subject(:grammar) { described_class.digits }
45
45
 
46
- it { should match('1').and_interpret_as('dtmf-1') }
47
- it { should match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
48
- it { should match('1').and_interpret_as('dtmf-1') }
46
+ it { is_expected.to match('1').and_interpret_as('dtmf-1') }
47
+ it { is_expected.to match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
48
+ it { is_expected.to match('1').and_interpret_as('dtmf-1') }
49
49
 
50
50
  context "with a minimum length" do
51
51
  subject { described_class.digits minlength: 3 }
52
52
 
53
- it { should match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
54
- it { should match('1234567890').and_interpret_as('dtmf-1 dtmf-2 dtmf-3 dtmf-4 dtmf-5 dtmf-6 dtmf-7 dtmf-8 dtmf-9 dtmf-0') }
53
+ it { is_expected.to match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
54
+ it { is_expected.to match('1234567890').and_interpret_as('dtmf-1 dtmf-2 dtmf-3 dtmf-4 dtmf-5 dtmf-6 dtmf-7 dtmf-8 dtmf-9 dtmf-0') }
55
55
 
56
- it { should potentially_match('1') }
57
- it { should potentially_match('11') }
58
- it { should potentially_match('4') }
56
+ it { is_expected.to potentially_match('1') }
57
+ it { is_expected.to potentially_match('11') }
58
+ it { is_expected.to potentially_match('4') }
59
59
  end
60
60
 
61
61
  context "with a maximum length" do
62
62
  subject { described_class.digits maxlength: 3 }
63
63
 
64
- it { should match('1').and_interpret_as('dtmf-1') }
65
- it { should match('12').and_interpret_as('dtmf-1 dtmf-2') }
66
- it { should match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
64
+ it { is_expected.to match('1').and_interpret_as('dtmf-1') }
65
+ it { is_expected.to match('12').and_interpret_as('dtmf-1 dtmf-2') }
66
+ it { is_expected.to match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
67
67
 
68
- it { should not_match('1111') }
69
- it { should not_match('1111111') }
68
+ it { is_expected.to not_match('1111') }
69
+ it { is_expected.to not_match('1111111') }
70
70
  end
71
71
 
72
72
  context "with an absolute length" do
73
73
  subject { described_class.digits length: 3 }
74
74
 
75
- it { should max_match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
76
- it { should max_match('111').and_interpret_as('dtmf-1 dtmf-1 dtmf-1') }
75
+ it { is_expected.to max_match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
76
+ it { is_expected.to max_match('111').and_interpret_as('dtmf-1 dtmf-1 dtmf-1') }
77
77
 
78
- it { should potentially_match('1') }
79
- it { should potentially_match('12') }
78
+ it { is_expected.to potentially_match('1') }
79
+ it { is_expected.to potentially_match('12') }
80
80
 
81
- it { should not_match('1234') }
82
- it { should not_match('12345') }
81
+ it { is_expected.to not_match('1234') }
82
+ it { is_expected.to not_match('12345') }
83
83
  end
84
84
 
85
85
  context "when the min and max lengths are swapped" do
@@ -104,62 +104,71 @@ describe RubySpeech::GRXML::Builtins do
104
104
  describe "currency" do
105
105
  subject(:grammar) { described_class.currency }
106
106
 
107
- it { should max_match('1*01').and_interpret_as('dtmf-1 dtmf-star dtmf-0 dtmf-1') }
108
- it { should max_match('01*00').and_interpret_as('dtmf-0 dtmf-1 dtmf-star dtmf-0 dtmf-0') }
109
- it { should max_match('100000000000*00').and_interpret_as('dtmf-1 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-star dtmf-0 dtmf-0') }
110
- it { should max_match('0*08').and_interpret_as('dtmf-0 dtmf-star dtmf-0 dtmf-8') }
111
- it { should max_match('*59').and_interpret_as('dtmf-star dtmf-5 dtmf-9') }
107
+ it { is_expected.to max_match('1*01').and_interpret_as('dtmf-1 dtmf-star dtmf-0 dtmf-1') }
108
+ it { is_expected.to max_match('01*00').and_interpret_as('dtmf-0 dtmf-1 dtmf-star dtmf-0 dtmf-0') }
109
+ it { is_expected.to max_match('100000000000*00').and_interpret_as('dtmf-1 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-star dtmf-0 dtmf-0') }
110
+ it { is_expected.to max_match('0*08').and_interpret_as('dtmf-0 dtmf-star dtmf-0 dtmf-8') }
111
+ it { is_expected.to max_match('*59').and_interpret_as('dtmf-star dtmf-5 dtmf-9') }
112
112
 
113
- it { should match('0').and_interpret_as('dtmf-0') }
114
- it { should match('0*0').and_interpret_as('dtmf-0 dtmf-star dtmf-0') }
115
- it { should match('10*5').and_interpret_as('dtmf-1 dtmf-0 dtmf-star dtmf-5') }
116
- it { should match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
117
- it { should match('123*').and_interpret_as('dtmf-1 dtmf-2 dtmf-3 dtmf-star') }
113
+ it { is_expected.to match('0').and_interpret_as('dtmf-0') }
114
+ it { is_expected.to match('0*0').and_interpret_as('dtmf-0 dtmf-star dtmf-0') }
115
+ it { is_expected.to match('10*5').and_interpret_as('dtmf-1 dtmf-0 dtmf-star dtmf-5') }
116
+ it { is_expected.to match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
117
+ it { is_expected.to match('123*').and_interpret_as('dtmf-1 dtmf-2 dtmf-3 dtmf-star') }
118
118
 
119
- it { should not_match('#') }
119
+ it { is_expected.to not_match('#') }
120
120
  end
121
121
 
122
- describe "number" do
122
+ describe 'number' do
123
123
  subject(:grammar) { described_class.number }
124
124
 
125
- it { should match('0').and_interpret_as('dtmf-0') }
126
- it { should match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
127
- it { should match('1*01').and_interpret_as('dtmf-1 dtmf-star dtmf-0 dtmf-1') }
128
- it { should match('01*00').and_interpret_as('dtmf-0 dtmf-1 dtmf-star dtmf-0 dtmf-0') }
129
- it { should match('100000000000*00').and_interpret_as('dtmf-1 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-0 dtmf-star dtmf-0 dtmf-0') }
130
- it { should match('0*08').and_interpret_as('dtmf-0 dtmf-star dtmf-0 dtmf-8') }
131
- it { should match('*59').and_interpret_as('dtmf-star dtmf-5 dtmf-9') }
132
- it { should match('0*0').and_interpret_as('dtmf-0 dtmf-star dtmf-0') }
133
- it { should match('10*5').and_interpret_as('dtmf-1 dtmf-0 dtmf-star dtmf-5') }
134
- it { should match('123*').and_interpret_as('dtmf-1 dtmf-2 dtmf-3 dtmf-star') }
135
- it { should match('123*2342').and_interpret_as('dtmf-1 dtmf-2 dtmf-3 dtmf-star dtmf-2 dtmf-3 dtmf-4 dtmf-2') }
136
-
137
- it { should not_match('#') }
125
+ it { is_expected.to match('0').and_interpret_as 'dtmf-0' }
126
+ it { is_expected.to match('123').and_interpret_as 'dtmf-1 dtmf-2 dtmf-3' }
127
+ it { is_expected.to match('1*01').and_interpret_as dtmf_seq %w(1 star 0 1) }
128
+ it { is_expected.to match('01*00').and_interpret_as dtmf_seq %w(0 1 star 0 0) }
129
+ it do
130
+ is_expected.to match('100000000000*00')
131
+ .and_interpret_as dtmf_seq %w(1 0 0 0 0 0 0 0 0 0 0 0 star 0 0)
132
+ end
133
+ it { is_expected.to match('0*08').and_interpret_as dtmf_seq %w(0 star 0 8) }
134
+ it { is_expected.to match('*59').and_interpret_as 'dtmf-star dtmf-5 dtmf-9' }
135
+ it { is_expected.to match('0*0').and_interpret_as 'dtmf-0 dtmf-star dtmf-0' }
136
+ it { is_expected.to match('10*5').and_interpret_as dtmf_seq %w(1 0 star 5) }
137
+ it { is_expected.to match('123*').and_interpret_as dtmf_seq %w(1 2 3 star) }
138
+ it do
139
+ is_expected.to match('123*2342').and_interpret_as dtmf_seq %w(1 2 3 star 2 3 4 2)
140
+ end
141
+
142
+ it { is_expected.to potentially_match '*' }
143
+
144
+ it { is_expected.to not_match '#' }
145
+ it { is_expected.to not_match '**' }
146
+ it { is_expected.to not_match '0123*456*789' }
138
147
  end
139
148
 
140
149
  describe "phone" do
141
150
  subject(:grammar) { described_class.phone }
142
151
 
143
- it { should match('0').and_interpret_as('dtmf-0') }
144
- it { should match('0123').and_interpret_as('dtmf-0 dtmf-1 dtmf-2 dtmf-3') }
145
- it { should match('0123*456').and_interpret_as('dtmf-0 dtmf-1 dtmf-2 dtmf-3 dtmf-star dtmf-4 dtmf-5 dtmf-6') }
152
+ it { is_expected.to match('0').and_interpret_as('dtmf-0') }
153
+ it { is_expected.to match('0123').and_interpret_as('dtmf-0 dtmf-1 dtmf-2 dtmf-3') }
154
+ it { is_expected.to match('0123*456').and_interpret_as('dtmf-0 dtmf-1 dtmf-2 dtmf-3 dtmf-star dtmf-4 dtmf-5 dtmf-6') }
146
155
 
147
- it { should potentially_match('') }
156
+ it { is_expected.to potentially_match('') }
148
157
 
149
- it { should not_match('#') }
150
- it { should not_match('0123*456*789') }
158
+ it { is_expected.to not_match('#') }
159
+ it { is_expected.to not_match('0123*456*789') }
151
160
  end
152
161
 
153
162
  describe "time" do
154
163
  subject(:grammar) { described_class.time }
155
164
 
156
- it { should max_match('1235').and_interpret_as('dtmf-1 dtmf-2 dtmf-3 dtmf-5') }
165
+ it { is_expected.to max_match('1235').and_interpret_as('dtmf-1 dtmf-2 dtmf-3 dtmf-5') }
157
166
 
158
- it { should match('12').and_interpret_as('dtmf-1 dtmf-2') }
159
- it { should match('4').and_interpret_as('dtmf-4') }
160
- it { should match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
167
+ it { is_expected.to match('12').and_interpret_as('dtmf-1 dtmf-2') }
168
+ it { is_expected.to match('4').and_interpret_as('dtmf-4') }
169
+ it { is_expected.to match('123').and_interpret_as('dtmf-1 dtmf-2 dtmf-3') }
161
170
 
162
- it { should not_match('*') }
163
- it { should not_match('#') }
171
+ it { is_expected.to not_match('*') }
172
+ it { is_expected.to not_match('#') }
164
173
  end
165
174
  end
@@ -7,7 +7,7 @@ module RubySpeech
7
7
 
8
8
  subject { described_class.new doc }
9
9
 
10
- it { should be_a_valid_grxml_document }
10
+ it { is_expected.to be_a_valid_grxml_document }
11
11
 
12
12
  its(:name) { should == 'grammar' }
13
13
  its(:language) { should == 'en-US' }
@@ -36,7 +36,7 @@ module RubySpeech
36
36
  end
37
37
 
38
38
  it 'registers itself' do
39
- Element.class_from_registration(:grammar).should == Grammar
39
+ expect(Element.class_from_registration(:grammar)).to eq(Grammar)
40
40
  end
41
41
 
42
42
  describe "from a document" do
@@ -48,7 +48,7 @@ module RubySpeech
48
48
 
49
49
  subject { Element.import document }
50
50
 
51
- it { should be_instance_of Grammar }
51
+ it { is_expected.to be_instance_of Grammar }
52
52
 
53
53
  its(:language) { should == 'jp' }
54
54
  its(:base_uri) { should == 'blah' }
@@ -70,24 +70,24 @@ module RubySpeech
70
70
 
71
71
  describe "comparing objects" do
72
72
  it "should be equal if the content, language and base uri are the same" do
73
- Grammar.new(doc, :language => 'en-GB', :base_uri => 'blah', :content => "Hello there").should == Grammar.new(doc, :language => 'en-GB', :base_uri => 'blah', :content => "Hello there")
73
+ expect(Grammar.new(doc, :language => 'en-GB', :base_uri => 'blah', :content => "Hello there")).to eq(Grammar.new(doc, :language => 'en-GB', :base_uri => 'blah', :content => "Hello there"))
74
74
  end
75
75
 
76
76
  describe "when the content is different" do
77
77
  it "should not be equal" do
78
- Grammar.new(doc, :content => "Hello").should_not == Grammar.new(doc, :content => "Hello there")
78
+ expect(Grammar.new(doc, :content => "Hello")).not_to eq(Grammar.new(doc, :content => "Hello there"))
79
79
  end
80
80
  end
81
81
 
82
82
  describe "when the language is different" do
83
83
  it "should not be equal" do
84
- Grammar.new(doc, :language => 'en-US').should_not == Grammar.new(doc, :language => 'en-GB')
84
+ expect(Grammar.new(doc, :language => 'en-US')).not_to eq(Grammar.new(doc, :language => 'en-GB'))
85
85
  end
86
86
  end
87
87
 
88
88
  describe "when the base URI is different" do
89
89
  it "should not be equal" do
90
- Grammar.new(doc, :base_uri => 'foo').should_not == Grammar.new(doc, :base_uri => 'bar')
90
+ expect(Grammar.new(doc, :base_uri => 'foo')).not_to eq(Grammar.new(doc, :base_uri => 'bar'))
91
91
  end
92
92
  end
93
93
 
@@ -98,7 +98,7 @@ module RubySpeech
98
98
  g2 = Grammar.new doc
99
99
  g2 << Rule.new(doc, :id => 'main2')
100
100
 
101
- g1.should_not == g2
101
+ expect(g1).not_to eq(g2)
102
102
  end
103
103
  end
104
104
  end
@@ -108,32 +108,32 @@ module RubySpeech
108
108
  g.rule :id => :main, :scope => 'public'
109
109
  expected_g = Grammar.new doc
110
110
  expected_g << Rule.new(doc, :id => :main, :scope => 'public')
111
- g.should == expected_g
111
+ expect(g).to eq(expected_g)
112
112
  end
113
113
 
114
114
  describe "<<" do
115
115
  it "should accept Rule" do
116
- lambda { subject << Rule.new(doc) }.should_not raise_error
116
+ expect { subject << Rule.new(doc) }.not_to raise_error
117
117
  end
118
118
 
119
119
  it "should accept Tag" do
120
- lambda { subject << Tag.new(doc) }.should_not raise_error
120
+ expect { subject << Tag.new(doc) }.not_to raise_error
121
121
  end
122
122
 
123
123
  it "should raise InvalidChildError with non-acceptable objects" do
124
- lambda { subject << 1 }.should raise_error(InvalidChildError, "A Grammar can only accept Rule and Tag as children")
124
+ expect { subject << 1 }.to raise_error(InvalidChildError, "A Grammar can only accept Rule and Tag as children")
125
125
  end
126
126
  end
127
127
 
128
128
  describe "#to_doc" do
129
129
  it "should create an XML document from the grammar" do
130
- subject.to_doc.should == subject.document
130
+ expect(subject.to_doc).to eq(subject.document)
131
131
  end
132
132
  end
133
133
 
134
134
  describe "#tag_format" do
135
135
  it "should allow setting tag-format identifier" do
136
- lambda { subject.tag_format = "semantics/1.0" }.should_not raise_error
136
+ expect { subject.tag_format = "semantics/1.0" }.not_to raise_error
137
137
  end
138
138
  end
139
139
 
@@ -152,11 +152,11 @@ module RubySpeech
152
152
  expected_concat << Rule.new(doc, :id => 'millie', :scope => 'public', :content => "Hi Millie")
153
153
 
154
154
  concat = grammar1 + grammar2
155
- grammar1.to_s.should == grammar1_string
156
- grammar2.to_s.should == grammar2_string
157
- concat.should == expected_concat
158
- concat.document.root.should == concat
159
- concat.to_s.should_not include('default')
155
+ expect(grammar1.to_s).to eq(grammar1_string)
156
+ expect(grammar2.to_s).to eq(grammar2_string)
157
+ expect(concat).to eq(expected_concat)
158
+ expect(concat.document.root).to eq(concat)
159
+ expect(concat.to_s).not_to include('default')
160
160
  end
161
161
  end
162
162
 
@@ -167,7 +167,7 @@ module RubySpeech
167
167
  foo = GRXML::Rule.new doc, :id => 'foo'
168
168
  grammar << foo
169
169
 
170
- grammar.root_rule.should == foo
170
+ expect(grammar.root_rule).to eq(foo)
171
171
  end
172
172
 
173
173
  describe "inlining rule references" do
@@ -224,13 +224,147 @@ module RubySpeech
224
224
  end
225
225
 
226
226
  it "should be possible in a non-destructive manner" do
227
- grammar.inline.should == inline_grammar
228
- grammar.should_not == inline_grammar
227
+ expect(grammar.inline).to eq(inline_grammar)
228
+ expect(grammar).not_to eq(inline_grammar)
229
229
  end
230
230
 
231
231
  it "should be possible in a destructive manner" do
232
- grammar.inline!.should == inline_grammar
233
- grammar.should == inline_grammar
232
+ expect(grammar.inline!).to eq(inline_grammar)
233
+ expect(grammar).to eq(inline_grammar)
234
+ end
235
+
236
+ context 'nested' do
237
+ let :expected_doc do
238
+ RubySpeech::GRXML.draw mode: :dtmf, root: 'main' do
239
+ rule id: :main, scope: 'public' do
240
+ string "How about an oatmeal cookie? You'll feel better."
241
+ end
242
+ end
243
+ end
244
+
245
+ context '1 level deep' do
246
+ subject do
247
+ RubySpeech::GRXML.draw mode: :dtmf, root: 'main' do
248
+ rule id: :main, scope: 'public' do
249
+ ruleref uri: '#rabbit_hole2'
250
+ end
251
+ rule id: 'rabbit_hole2' do
252
+ string "How about an oatmeal cookie? You'll feel better."
253
+ end
254
+ end.inline
255
+ end
256
+
257
+ it { is_expected.to eq expected_doc }
258
+ end
259
+
260
+ context '2 levels deep' do
261
+ subject do
262
+ RubySpeech::GRXML.draw mode: :dtmf, root: 'main' do
263
+ rule id: :main, scope: 'public' do
264
+ ruleref uri: '#rabbit_hole2'
265
+ end
266
+ rule id: 'rabbit_hole2' do
267
+ ruleref uri: '#rabbit_hole3'
268
+ end
269
+ rule id: 'rabbit_hole3' do
270
+ string "How about an oatmeal cookie? You'll feel better."
271
+ end
272
+ end.inline
273
+ end
274
+
275
+ it { is_expected.to eq expected_doc }
276
+ end
277
+
278
+ context '3 levels deep' do
279
+ subject do
280
+ RubySpeech::GRXML.draw mode: :dtmf, root: 'main' do
281
+ rule id: :main, scope: 'public' do
282
+ ruleref uri: '#rabbit_hole2'
283
+ end
284
+ rule id: 'rabbit_hole2' do
285
+ ruleref uri: '#rabbit_hole3'
286
+ end
287
+ rule id: 'rabbit_hole3' do
288
+ ruleref uri: '#rabbit_hole4'
289
+ end
290
+ rule id: 'rabbit_hole4' do
291
+ string "How about an oatmeal cookie? You'll feel better."
292
+ end
293
+ end.inline
294
+ end
295
+
296
+ it { is_expected.to eq expected_doc }
297
+ end
298
+
299
+ context 'in a self-referencial infinite loop' do
300
+ subject do
301
+ RubySpeech::GRXML.draw mode: :dtmf, root: 'main' do
302
+ rule id: :main, scope: 'public' do
303
+ ruleref uri: '#paradox'
304
+ end
305
+ rule id: 'paradox' do
306
+ ruleref uri: '#paradox'
307
+ end
308
+ end.inline
309
+ end
310
+
311
+ it 'should raise an Exception' do
312
+ expect { subject }
313
+ .to raise_error RubySpeech::GRXML::ReferentialLoopError
314
+ end
315
+ end
316
+
317
+ context 'in a cross-referencial infinite loop' do
318
+ subject do
319
+ RubySpeech::GRXML.draw mode: :dtmf, root: 'main' do
320
+ rule id: :main, scope: 'public' do
321
+ ruleref uri: '#007'
322
+ end
323
+ rule id: '007' do
324
+ one_of do
325
+ item do
326
+ ruleref uri: '#bond'
327
+ end
328
+ end
329
+ end
330
+ rule id: 'bond' do
331
+ one_of do
332
+ item do
333
+ ruleref uri: '#james_bond'
334
+ end
335
+ end
336
+ end
337
+ rule id: 'james_bond' do
338
+ one_of do
339
+ item do
340
+ ruleref uri: '#007'
341
+ end
342
+ end
343
+ end
344
+ end.inline
345
+ end
346
+
347
+ it 'should raise an Exception' do
348
+ expect { subject }
349
+ .to raise_error RubySpeech::GRXML::ReferentialLoopError
350
+ end
351
+ end
352
+
353
+ context 'with an invalid-reference' do
354
+ subject do
355
+ RubySpeech::GRXML.draw mode: :dtmf, root: 'main' do
356
+ rule id: :main, scope: 'public' do
357
+ ruleref uri: '#lost'
358
+ end
359
+ end.inline
360
+ end
361
+
362
+ it 'should raise a descriptive exception' do
363
+ expect { subject }
364
+ .to raise_error RubySpeech::GRXML::MissingReferenceError,
365
+ "Ruleref '#lost' is referenced but not defined"
366
+ end
367
+ end
234
368
  end
235
369
  end
236
370
 
@@ -259,7 +393,7 @@ module RubySpeech
259
393
  let(:tokens) { 'hello' }
260
394
 
261
395
  it "should tokenize correctly" do
262
- should == tokenized_version
396
+ is_expected.to eq(tokenized_version)
263
397
  end
264
398
  end
265
399
 
@@ -268,7 +402,7 @@ module RubySpeech
268
402
  let(:tokens) { ['2'] }
269
403
 
270
404
  it "should tokenize correctly" do
271
- should == tokenized_version
405
+ is_expected.to eq(tokenized_version)
272
406
  end
273
407
  end
274
408
 
@@ -277,7 +411,7 @@ module RubySpeech
277
411
  let(:tokens) { ['San Francisco'] }
278
412
 
279
413
  it "should tokenize correctly" do
280
- should == tokenized_version
414
+ is_expected.to eq(tokenized_version)
281
415
  end
282
416
  end
283
417
 
@@ -286,7 +420,7 @@ module RubySpeech
286
420
  let(:tokens) { ['hello'] }
287
421
 
288
422
  it "should tokenize correctly" do
289
- should == tokenized_version
423
+ is_expected.to eq(tokenized_version)
290
424
  end
291
425
  end
292
426
 
@@ -295,7 +429,7 @@ module RubySpeech
295
429
  let(:tokens) { ['bon', 'voyage'] }
296
430
 
297
431
  it "should tokenize correctly" do
298
- should == tokenized_version
432
+ is_expected.to eq(tokenized_version)
299
433
  end
300
434
  end
301
435
 
@@ -304,7 +438,7 @@ module RubySpeech
304
438
  let(:tokens) { ['this', 'is', 'a', 'test'] }
305
439
 
306
440
  it "should tokenize correctly" do
307
- should == tokenized_version
441
+ is_expected.to eq(tokenized_version)
308
442
  end
309
443
  end
310
444
 
@@ -313,7 +447,7 @@ module RubySpeech
313
447
  let(:tokens) { ['San Francisco'] }
314
448
 
315
449
  it "should tokenize correctly" do
316
- should == tokenized_version
450
+ is_expected.to eq(tokenized_version)
317
451
  end
318
452
  end
319
453
 
@@ -328,7 +462,7 @@ module RubySpeech
328
462
  let(:tokens) { ['Welcome', 'to', 'San Francisco', 'Have Fun!'] }
329
463
 
330
464
  it "should tokenize correctly" do
331
- should == tokenized_version
465
+ is_expected.to eq(tokenized_version)
332
466
  end
333
467
  end
334
468
  end
@@ -349,9 +483,9 @@ module RubySpeech
349
483
  end
350
484
  end
351
485
 
352
- grammar.should_not == normalized_grammar
486
+ expect(grammar).not_to eq(normalized_grammar)
353
487
  grammar.normalize_whitespace
354
- grammar.should == normalized_grammar
488
+ expect(grammar).to eq(normalized_grammar)
355
489
  end
356
490
  end
357
491
  end # Grammar