poefy-pg 0.1.0 → 2.0.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.
@@ -1,682 +1,697 @@
1
- #!/usr/bin/env ruby
2
- # Encoding: UTF-8
3
-
4
- ################################################################################
5
-
6
- describe Poefy::Poem, "-- Postgres" do
7
-
8
- before(:all) do
9
- require 'poefy/pg'
10
- @root = Poefy.root
11
- dbs = %w{spec_test_tiny spec_shakespeare spec_whitman}
12
- dbs.each do |db_name|
13
- Poefy::Database.single_exec! <<-SQL
14
- SET client_min_messages TO WARNING;
15
- DROP TABLE IF EXISTS #{db_name};
16
- SQL
17
- end
18
- end
19
-
20
- after(:all) do
21
- dbs = %w{spec_test_tiny spec_shakespeare spec_whitman}
22
- dbs.each do |db_name|
23
- Poefy::Database.single_exec! <<-SQL
24
- SET client_min_messages TO WARNING;
25
- DROP TABLE IF EXISTS #{db_name};
26
- SQL
27
- end
28
- end
29
-
30
- ##############################################################################
31
-
32
- describe "using tiny dataset 'spec_test_tiny'" do
33
- corpus = "spec_test_tiny"
34
-
35
- # Create a small corpus of a few rhymes.
36
- text_array = %w{man plan flan can dan fish dish wish bee sea tree flea}
37
- text_array.map!{ |i| 'a ' + i }
38
- text_string = text_array.join("\n")
39
- row_count = text_array.count
40
-
41
- before(:each) do
42
- @poefy = Poefy::Poem.new(corpus, { proper: false })
43
- end
44
- after(:each) do
45
- @poefy.close
46
- end
47
- it "initialised object not nil" do
48
- expect(@poefy).to_not be_nil
49
- end
50
-
51
- # Create corpora in the three different ways.
52
- describe "@poefy#make_database!" do
53
-
54
- it "Use array of strings" do
55
- @poefy.make_database! text_array
56
- expect(@poefy.corpus.exists?).to be true
57
- expect(@poefy.corpus.count).to be row_count
58
- poem = @poefy.poem({ rhyme: 'aabb' })
59
- expect(poem.count).to be 4
60
- end
61
-
62
- it "Use one long newline delimited string" do
63
- @poefy.make_database! text_string
64
- expect(@poefy.corpus.exists?).to be true
65
- expect(@poefy.corpus.count).to be row_count
66
- poem = @poefy.poem({ rhyme: 'aabb' })
67
- expect(poem.count).to be 4
68
- end
69
-
70
- it "Use text lines from a file" do
71
-
72
- # Create a temp file.
73
- tmp = Tempfile.new('spec-', Poefy.root + '/spec')
74
- text_path = tmp.path
75
- tmp.write text_string
76
- tmp.close
77
-
78
- @poefy.make_database! text_path
79
- expect(@poefy.corpus.exists?).to be true
80
- expect(@poefy.corpus.count).to be row_count
81
- poem = @poefy.poem({ rhyme: 'aabb' })
82
- expect(poem.count).to be 4
83
-
84
- # Delete the temp file.
85
- tmp.delete
86
- end
87
- end
88
-
89
- # Make sure that the description can be updated as specified
90
- # and that it doesn't cause SQL injection.
91
- describe "corpus description using #desc=" do
92
- it "@poefy.corpus.desc is initially empty" do
93
- expect(@poefy.corpus.desc).to eq ''
94
- end
95
-
96
- values = [
97
- "test",
98
- " -- test",
99
- "; -- test",
100
- "test' -- ",
101
- "test'' -- ",
102
- "'test' -- ",
103
- "'test'' -- ",
104
- "Shakespeare's sonnets",
105
- "Shakespeare's -- sonnets",
106
- "Shakespeare's; -- sonnets",
107
- "test' ; INSERT INTO spec_test_tiny VALUES('foo') -- ",
108
- "105 OR 1=1",
109
- "' or ''='"
110
- ]
111
- values.each do |value|
112
- it "@poefy.corpus.desc = #{value}" do
113
- @poefy.corpus.desc = value
114
- expect(@poefy.corpus.desc).to eq value
115
- expect(@poefy.corpus.count).to be row_count
116
- end
117
- end
118
- end
119
-
120
- describe ":rhyme option" do
121
-
122
- describe "should return nil" do
123
- it "blank, no argument" do
124
- poem = @poefy.poem
125
- expect(poem).to be_nil
126
- end
127
- it "({ })" do
128
- poem = @poefy.poem ({ })
129
- expect(poem).to be_nil
130
- end
131
- it "({ rhyme: nil })" do
132
- poem = @poefy.poem ({ rhyme: nil })
133
- expect(poem).to be_nil
134
- end
135
- it "({ rhyme: ' ' })" do
136
- poem = @poefy.poem ({ rhyme: ' ' })
137
- expect(poem).to be_nil
138
- end
139
- it "({ rhyme: '' })" do
140
- poem = @poefy.poem ({ rhyme: '' })
141
- expect(poem).to be_nil
142
- end
143
- end
144
-
145
- describe "should return correct number of lines" do
146
- rhymes = %w{a b z A aa ab zz AA AB AA1 A1 B1 Z1 AB1 A1A1A1A1B1B1B1B1B1}
147
- rhymes += ['A1A1A1 A1A1A1 B1B1B1B1B1B1','a b c a b c']
148
- rhymes += [' abc','abc ',' abc ']
149
- rhymes += ['n aaa n','n aXXXa N1']
150
- rhymes.each do |i|
151
- it "({ rhyme: '#{i}' })" do
152
- poem = @poefy.poem ({ rhyme: i })
153
- expect(poem.count).to be i.gsub(/[0-9]/,'').length
154
- end
155
- end
156
- end
157
-
158
- describe "should accept characters other than number" do
159
- rhymes = %w{. , : .. ., ,, :: (()) @ ~ <<>< A1A1A1...a;}
160
- rhymes.each do |i|
161
- it "({ rhyme: '#{i}' })" do
162
- poem = @poefy.poem ({ rhyme: i })
163
- expect(poem.count).to be i.gsub(/[0-9]/,'').length
164
- end
165
- end
166
- end
167
-
168
- describe "should be nil if can't parse rhyme string" do
169
- rhymes = %w{a1 b1 ab1 Ab1 AAAAABb1 1 1111 1122 11221 ;;::1. }
170
- rhymes += ['AA Bb1','11 11','11 1 1','..1.']
171
- rhymes.each do |i|
172
- it "({ rhyme: '#{i}' })" do
173
- poem = @poefy.poem ({ rhyme: i })
174
- expect(poem).to be_nil
175
- end
176
- end
177
- end
178
-
179
- describe "should be nil if can't complete rhyme string" do
180
- rhymes = %w{aaaaaa abcd aaaaabbbbb}
181
- rhymes.each do |i|
182
- it "({ rhyme: '#{i}' })" do
183
- poem = @poefy.poem ({ rhyme: i })
184
- expect(poem).to be_nil
185
- end
186
- end
187
- end
188
-
189
- describe "should correctly repeat uppercase lines" do
190
- lines = 200
191
- it "({ rhyme: 'A' * #{lines} })" do
192
- poem = @poefy.poem ({ rhyme: 'A' * lines })
193
- expect(poem.count).to be lines
194
- expect(poem.uniq.count).to be 1
195
- end
196
- it "({ rhyme: ('A'..'C').to_a.map { |i| i * #{lines} }.join })" do
197
- rhyme = ('A'..'C').to_a.map { |i| i * lines }.join
198
- poem = @poefy.poem ({ rhyme: rhyme })
199
- expect(poem.count).to be lines * 3
200
- expect(poem.uniq.count).to be 3
201
- end
202
- end
203
-
204
- describe "should be nil if can't complete repeating rhyme string" do
205
- lines = 200
206
- it "({ rhyme: ('A'..'D').to_a.map { |i| i * #{lines} }.join })" do
207
- rhyme = ('A'..'D').to_a.map { |i| i * lines }.join
208
- poem = @poefy.poem ({ rhyme: rhyme })
209
- expect(poem).to be_nil
210
- end
211
- end
212
-
213
- end
214
-
215
- describe ":form option" do
216
-
217
- describe "should return correct number of lines" do
218
- it "({ form: :default })" do
219
- poem = @poefy.poem ({ form: :default })
220
- expect(poem.count).to be 1
221
- end
222
- end
223
-
224
- describe "should be nil if given a named form it can't fulfil" do
225
- it "({ form: 'sonnet' })" do
226
- poem = @poefy.poem ({ form: 'sonnet' })
227
- expect(poem).to be_nil
228
- end
229
- it "({ form: :villanelle })" do
230
- poem = @poefy.poem ({ form: :villanelle })
231
- expect(poem).to be_nil
232
- end
233
- end
234
-
235
- describe "should be nil if given a junk named form" do
236
- it "({ form: 'sonnet_junk' })" do
237
- poem = @poefy.poem ({ form: 'sonnet_junk' })
238
- expect(poem).to be_nil
239
- end
240
- it "({ form: :not_a_form })" do
241
- poem = @poefy.poem ({ form: :not_a_form })
242
- expect(poem).to be_nil
243
- end
244
- it "({ form: :not_a_form, indent: '0010' })" do
245
- poem = @poefy.poem ({ form: :not_a_form, indent: '0010' })
246
- expect(poem).to be_nil
247
- end
248
- end
249
-
250
- describe "should be valid if given a junk named form, and a rhyme" do
251
- it "({ form: :not_a_form, rhyme: 'abcb' })" do
252
- poem = @poefy.poem ({ form: :not_a_form, rhyme: 'abcb' })
253
- expect(poem.count).to be 4
254
- end
255
- end
256
-
257
- describe "should overwrite a named form if another option is specified" do
258
- it "({ form: 'default', rhyme: 'ab' })" do
259
- poem = @poefy.poem ({ form: 'default', rhyme: 'ab' })
260
- expect(poem.count).to be 2
261
- end
262
- it "({ form: :villanelle, rhyme: 'abcb' })" do
263
- poem = @poefy.poem ({ form: :villanelle, rhyme: 'abcb' })
264
- expect(poem.count).to be 4
265
- end
266
- end
267
- end
268
- end
269
-
270
- ##############################################################################
271
-
272
- describe "using dataset 'spec_shakespeare'" do
273
-
274
- file_txt = "shakespeare_sonnets.txt"
275
- file_db = "spec_shakespeare"
276
-
277
- # All the Shakespeare lines are pentameter, so some forms should fail.
278
- forms = Poefy::PoeticForms::POETIC_FORMS
279
- forms_fail = [:limerick, :haiku, :common, :ballad, :double_dactyl]
280
- forms_pass = forms.keys - forms_fail
281
-
282
- before(:each) do
283
- @poefy = Poefy::Poem.new(file_db, { proper: false })
284
- end
285
- after(:each) do
286
- @poefy.close
287
- end
288
-
289
- it "initialised object not nil" do
290
- expect(@poefy).to_not be_nil
291
- end
292
-
293
- describe "#make_database( '#{@root}/data/#{file_txt}', true )" do
294
- it "should make the database '#{@root}/data/#{file_db}" do
295
- input = `sed '/[a-z]/!d' #{@root}/data/#{file_txt}`
296
- @poefy.make_database! input
297
- expect(@poefy.corpus.exists?).to be true
298
- end
299
- end
300
-
301
- describe "using acrostic option" do
302
- describe "should return correct number of lines" do
303
- it "({ form: :sonnet, acrostic: 'pauldpthompson' })" do
304
- poem = @poefy.poem ({ form: :sonnet,
305
- acrostic: 'pauldpthompson' })
306
- expect(poem.count).to be 14
307
- end
308
- end
309
- describe "should fail to be created" do
310
- it "({ form: :sonnet, acrostic: 'qqqqqqqqqqqqqq' })" do
311
- poem = @poefy.poem ({ form: :sonnet,
312
- acrostic: 'qqqqqqqqqqqqqq' })
313
- expect(poem).to be_nil
314
- end
315
- end
316
- end
317
-
318
- describe "using form string" do
319
- describe "should return correct number of lines" do
320
-
321
- # Make sure each form's lines match the expected output.
322
- # Generate a few to be sure.
323
- forms_pass.each do |form|
324
- it "({ form: #{form} })" do
325
- 10.times do
326
- poem = @poefy.poem ({ form: form })
327
- expect(poem.count).to satisfy do |c|
328
- [*forms[form][:rhyme]].map do |r|
329
- r.gsub(/[0-9]/,'').length
330
- end.include?(c)
331
- end
332
- end
333
- end
334
- end
335
- end
336
-
337
- describe "should fail to be created" do
338
- forms_fail.each do |form|
339
- it "({ form: #{form} })" do
340
- 4.times do
341
- poem = @poefy.poem ({ form: form })
342
- expect(poem).to be_nil
343
- end
344
- end
345
- end
346
- end
347
- end
348
-
349
- describe "make sonnets" do
350
- sonnet_options = [
351
- { rhyme: 'ababcdcdefefgg' },
352
- { rhyme: 'abab cdcd efef gg', indent: '0101 0101 0011 01' },
353
- { form: 'sonnet' },
354
- { form: :sonnet, syllable: 0 },
355
- { form: :sonnet, syllable: 10 },
356
- { form: :sonnet, regex: /^[A-Z].*$/ },
357
- { form: :sonnet, regex: '^[A-Z].*$' },
358
- { form: :sonnet, acrostic: 'pauldpthompson' },
359
- { form: 'sonnet', indent: '01010101001101' },
360
- { form: 'sonnet', proper: false }
361
- ]
362
- sonnet_options.each do |option|
363
- it "#{option}" do
364
- 4.times do
365
- poem = @poefy.poem(option)
366
- expect(poem).to_not be_nil
367
- end
368
- end
369
- end
370
- end
371
- end
372
-
373
- ##############################################################################
374
-
375
- describe "using dataset 'spec_whitman'" do
376
-
377
- file_txt = "whitman_leaves.txt"
378
- file_db = "spec_whitman"
379
-
380
- # There's a good mix of syllable count, so all forms should pass.
381
- forms = Poefy::PoeticForms::POETIC_FORMS
382
- forms_pass = forms.keys
383
-
384
- before(:each) do
385
- @poefy = Poefy::Poem.new(file_db, { proper: false })
386
- end
387
- after(:each) do
388
- @poefy.close
389
- end
390
-
391
- it "initialised object not nil" do
392
- expect(@poefy).to_not be_nil
393
- end
394
-
395
- describe "#make_database( '#{@root}/data/#{file_txt}', true )" do
396
- it "should make the database '#{@root}/data/#{file_db}" do
397
- input = `sed '/[a-z]/!d' #{@root}/data/#{file_txt}`
398
- @poefy.make_database! input
399
- expect(@poefy.corpus.exists?).to be true
400
- end
401
- end
402
-
403
- describe "using form string" do
404
- describe "should return correct number of lines" do
405
-
406
- # Make sure each form's lines match the expected output.
407
- # Generate a few to be sure.
408
- forms_pass.each do |form|
409
- it "({ form: #{form} })" do
410
- 10.times do
411
- poem = @poefy.poem ({ form: form })
412
- expect(poem.count).to satisfy do |c|
413
- [*forms[form][:rhyme]].map do |r|
414
- r.gsub(/[0-9]/,'').length
415
- end.include?(c)
416
- end
417
- end
418
- end
419
- end
420
- end
421
- end
422
-
423
- describe "make sonnets" do
424
- sonnet_options = [
425
- { rhyme: 'ababcdcdefefgg' },
426
- { rhyme: 'abab cdcd efef gg', indent: '0101 0101 0011 01' },
427
- { form: 'sonnet' },
428
- { form: :sonnet, syllable: 0 },
429
- { form: :sonnet, syllable: 10 },
430
- { form: :sonnet, regex: /^[A-Z].*$/ },
431
- { form: :sonnet, regex: '^[A-Z].*$' },
432
- { form: :sonnet, acrostic: 'pauldpthompson' },
433
- { form: 'sonnet', indent: '01010101001101' },
434
- { form: 'sonnet', proper: false }
435
- ]
436
- sonnet_options.each do |option|
437
- it "#{option}" do
438
- 4.times do
439
- poem = @poefy.poem(option)
440
- expect(poem).to_not be_nil
441
- end
442
- end
443
- end
444
- end
445
-
446
- describe "using syllable string" do
447
-
448
- it "({ rhyme: 'abcb defe', syllable: '[8,6,8,6,0,8,6,8,6]' })" do
449
- options = {
450
- rhyme: 'abcb defe',
451
- syllable: '[8,6,8,6,0,8,6,8,6]'
452
- }
453
- poem = @poefy.poem (options)
454
- expect(poem.count).to be options[:rhyme].length
455
- end
456
-
457
- it "({ rhyme: 'abcb defe', syllable: '[8,6,8,6,8,6,8,6]' })" do
458
- options = {
459
- rhyme: 'abcb defe',
460
- syllable: '[8,6,8,6,8,6,8,6]'
461
- }
462
- poem = @poefy.poem (options)
463
- expect(poem.count).to be options[:rhyme].length
464
- end
465
- end
466
- end
467
-
468
- ##############################################################################
469
-
470
- describe "reusing the same Poem instance" do
471
- it "should correctly merge the option hashes" do
472
-
473
- # Default to use rondeau poetic form, and proper sentence validation
474
- poefy = Poefy::Poem.new(
475
- 'spec_shakespeare',
476
- { form: 'rondeau', proper: true }
477
- )
478
-
479
- # Generate a properly sentenced rondeau
480
- poem = poefy.poem
481
- expect(poem.count).to be 17
482
-
483
- # Generate a rondeau without proper validation
484
- poem = poefy.poem ({ proper: false })
485
- expect(poem.count).to be 17
486
-
487
- # Generate a proper rondeau with a certain indentation
488
- poem = poefy.poem ({ indent: '01012 0012 010112' })
489
- expect(poem.count).to be 17
490
-
491
- # Generate other forms
492
- poem = poefy.poem ({ rhyme: 'abbaabbacdecde' })
493
- expect(poem.count).to be 14
494
- poem = poefy.poem ({ form: 'sonnet' })
495
- expect(poem.count).to be 14
496
- poem = poefy.poem ({ form: 'ballade' })
497
- expect(poem.count).to be 31
498
-
499
- # Generate a default rondeau again
500
- poem = poefy.poem
501
- expect(poem.count).to be 17
502
-
503
- poefy.close
504
- end
505
- end
506
-
507
- ##############################################################################
508
-
509
- describe "using the transform option" do
510
-
511
- it "should correctly transform the output 1" do
512
- poefy = Poefy::Poem.new :spec_shakespeare
513
- transform_hash = {
514
- 4 => proc { |line, num, poem| line.upcase },
515
- 12 => proc { |line, num, poem| line.upcase }
516
- }
517
- poem = poefy.poem({ form: :sonnet, transform: transform_hash })
518
- expect(poem.count).to be 14
519
- expect(poem[3]).to eq poem[3].upcase
520
- expect(poem[11]).to eq poem[11].upcase
521
- poefy.close
522
- end
523
-
524
- it "should correctly transform the output 2" do
525
- poefy = Poefy::Poem.new :spec_shakespeare
526
- transform_hash = {
527
- 4 => proc { |line, num, poem| poem.count },
528
- -3 => proc { |line, num, poem| poem.count },
529
- 7 => proc { |line, num, poem| 'test string' }
530
- }
531
- poem = poefy.poem({ form: :sonnet, transform: transform_hash })
532
- expect(poem.count).to be 14
533
- expect(poem[3]).to eq '14'
534
- expect(poem[11]).to eq '14'
535
- expect(poem[6]).to eq 'test string'
536
- poefy.close
537
- end
538
-
539
- it "should correctly transform the output 3" do
540
- poefy = Poefy::Poem.new :spec_shakespeare
541
- transform_proc = proc { |line, num, poem| line.downcase }
542
- poem = poefy.poem({ form: :sonnet, transform: transform_proc })
543
- expect(poem.count).to be 14
544
- poem.each do |i|
545
- expect(i).to eq i.downcase
546
- end
547
- poefy.close
548
- end
549
-
550
- it "should correctly transform the output 4" do
551
- poefy = Poefy::Poem.new :spec_shakespeare
552
- transform_proc = proc { |line, num, poem| "#{num} #{line.downcase}" }
553
- poem = poefy.poem({ form: :sonnet, transform: transform_proc })
554
- expect(poem.count).to be 14
555
- poem.each.with_index do |line, index|
556
- expect(line).to eq line.downcase
557
- first_word = line.split(' ').first
558
- expect(first_word).to eq (index + 1).to_s
559
- end
560
- poefy.close
561
- end
562
- end
563
-
564
- ##############################################################################
565
-
566
- describe "using the form_from_text option" do
567
- before(:all) do
568
- @text = <<-TEXT
569
- [Chorus 1]
570
- Oh yeah, I'll tell you something
571
- I think you'll understand
572
- When I'll say that something
573
- I want to hold your hand
574
- I want to hold your hand
575
- I want to hold your hand
576
-
577
- [Verse 1]
578
- Oh please, say to me
579
- You'll let me be your man
580
- And please, say to me
581
- You'll let me hold your hand
582
- I'll let me hold your hand
583
- I want to hold your hand
584
- TEXT
585
- @line_count = @text.split("\n").count
586
- end
587
-
588
- it "should use the exact poetic form 1" do
589
- poefy = Poefy::Poem.new(:spec_whitman, {
590
- form_from_text: @text
591
- })
592
- poem = poefy.poem
593
- poem.map!(&:strip!)
594
- expect(poem.count).to be @line_count
595
- expect(poem[0]).to eq "[Chorus 1]"
596
- expect(poem[8]).to eq "[Verse 1]"
597
- expect(poem[5]).to eq poem[4]
598
- expect(poem[6]).to eq poem[4]
599
- poefy.close
600
- end
601
-
602
- it "should use the exact poetic form 2" do
603
- poefy = Poefy::Poem.new :spec_whitman
604
- poem = poefy.poem({
605
- form_from_text: @text
606
- })
607
- poem.map!(&:strip!)
608
- expect(poem.count).to be @line_count
609
- expect(poem[0]).to eq "[Chorus 1]"
610
- expect(poem[8]).to eq "[Verse 1]"
611
- expect(poem[5]).to eq poem[4]
612
- expect(poem[6]).to eq poem[4]
613
- poefy.close
614
- end
615
-
616
- it "should correctly modify the poetic form 1" do
617
- poefy = Poefy::Poem.new(:spec_whitman, {
618
- form_from_text: @text,
619
- syllable: 6
620
- })
621
- poem = poefy.poem
622
- poem.map!(&:strip!)
623
- expect(poem.count).to be @line_count
624
- expect(poem[0]).to eq "[Chorus 1]"
625
- expect(poem[8]).to eq "[Verse 1]"
626
- expect(poem[5]).to eq poem[4]
627
- expect(poem[6]).to eq poem[4]
628
- poefy.close
629
- end
630
-
631
- it "should correctly modify the poetic form 2" do
632
- poefy = Poefy::Poem.new :spec_whitman
633
- poem = poefy.poem({
634
- form_from_text: @text,
635
- syllable: 6
636
- })
637
- poem.map!(&:strip!)
638
- expect(poem.count).to be @line_count
639
- expect(poem[0]).to eq "[Chorus 1]"
640
- expect(poem[8]).to eq "[Verse 1]"
641
- expect(poem[5]).to eq poem[4]
642
- expect(poem[6]).to eq poem[4]
643
- poefy.close
644
- end
645
-
646
- it "should correctly modify the poetic form 3" do
647
- poefy = Poefy::Poem.new(:spec_whitman, {
648
- form_from_text: @text
649
- })
650
- poem = poefy.poem({
651
- syllable: 6
652
- })
653
- poem.map!(&:strip!)
654
- expect(poem.count).to be @line_count
655
- expect(poem[0]).to eq "[Chorus 1]"
656
- expect(poem[8]).to eq "[Verse 1]"
657
- expect(poem[5]).to eq poem[4]
658
- expect(poem[6]).to eq poem[4]
659
- poefy.close
660
- end
661
-
662
- it "should correctly replace the poetic form" do
663
- poefy = Poefy::Poem.new(:spec_whitman, {
664
- syllable: 6
665
- })
666
- poem = poefy.poem({
667
- form_from_text: @text
668
- })
669
- poem.map!(&:strip!)
670
- expect(poem.count).to be @line_count
671
- expect(poem[0]).to eq "[Chorus 1]"
672
- expect(poem[8]).to eq "[Verse 1]"
673
- expect(poem[5]).to eq poem[4]
674
- expect(poem[6]).to eq poem[4]
675
- poefy.close
676
- end
677
-
678
- end
679
-
680
- end
681
-
682
- ################################################################################
1
+ #!/usr/bin/env ruby
2
+ # Encoding: UTF-8
3
+
4
+ ################################################################################
5
+
6
+ describe Poefy::Poem, "-- Postgres" do
7
+
8
+ before(:all) do
9
+ require 'poefy/pg'
10
+ @root = Poefy.root
11
+ dbs = %w{spec_test_tiny spec_shakespeare spec_whitman}
12
+ dbs.each do |db_name|
13
+ Poefy::Database.single_exec! <<-SQL
14
+ SET client_min_messages TO WARNING;
15
+ DROP TABLE IF EXISTS #{db_name};
16
+ SQL
17
+ end
18
+ end
19
+
20
+ after(:all) do
21
+ dbs = %w{spec_test_tiny spec_shakespeare spec_whitman}
22
+ dbs.each do |db_name|
23
+ Poefy::Database.single_exec! <<-SQL
24
+ SET client_min_messages TO WARNING;
25
+ DROP TABLE IF EXISTS #{db_name};
26
+ SQL
27
+ end
28
+ end
29
+
30
+ ##############################################################################
31
+
32
+ describe "using tiny dataset 'spec_test_tiny'" do
33
+ corpus = "spec_test_tiny"
34
+
35
+ # Create a small corpus of a few rhymes.
36
+ text_array = %w{man plan flan can dan fish dish wish bee sea tree flea}
37
+ text_array.map!{ |i| 'a ' + i }
38
+ text_string = text_array.join("\n")
39
+ row_count = text_array.count
40
+
41
+ before(:each) do
42
+ @poefy = Poefy::Poem.new(corpus, { proper: false })
43
+ end
44
+ after(:each) do
45
+ @poefy.close
46
+ end
47
+ it "initialised object not nil" do
48
+ expect(@poefy).to_not be_nil
49
+ end
50
+
51
+ # Create corpora in the three different ways.
52
+ describe "@poefy#make_database!" do
53
+
54
+ it "Use array of strings" do
55
+ @poefy.make_database! text_array
56
+ expect(@poefy.corpus.exist?).to be true
57
+ expect(@poefy.corpus.count).to be row_count
58
+ poem = @poefy.poem({ rhyme: 'aabb' })
59
+ expect(poem.count).to be 4
60
+ end
61
+
62
+ it "Use one long newline delimited string" do
63
+ @poefy.make_database! text_string
64
+ expect(@poefy.corpus.exist?).to be true
65
+ expect(@poefy.corpus.count).to be row_count
66
+ poem = @poefy.poem({ rhyme: 'aabb' })
67
+ expect(poem.count).to be 4
68
+ end
69
+
70
+ it "Use text lines from a file" do
71
+
72
+ # Create a temp file.
73
+ tmp = Tempfile.new('spec-', Poefy.root + '/spec')
74
+ text_path = tmp.path
75
+ tmp.write text_string
76
+ tmp.close
77
+
78
+ @poefy.make_database! text_path
79
+ expect(@poefy.corpus.exist?).to be true
80
+ expect(@poefy.corpus.count).to be row_count
81
+ poem = @poefy.poem({ rhyme: 'aabb' })
82
+ expect(poem.count).to be 4
83
+
84
+ # Delete the temp file.
85
+ tmp.delete
86
+ end
87
+ end
88
+
89
+ # Make sure that the description can be updated as specified
90
+ # and that it doesn't cause SQL injection.
91
+ describe "corpus description using #desc=" do
92
+ it "@poefy.corpus.desc is initially empty" do
93
+ expect(@poefy.corpus.desc).to eq ''
94
+ end
95
+
96
+ values = [
97
+ "test",
98
+ " -- test",
99
+ "; -- test",
100
+ "test' -- ",
101
+ "test'' -- ",
102
+ "'test' -- ",
103
+ "'test'' -- ",
104
+ "Shakespeare's sonnets",
105
+ "Shakespeare's -- sonnets",
106
+ "Shakespeare's; -- sonnets",
107
+ "test' ; INSERT INTO spec_test_tiny VALUES('foo') -- ",
108
+ "105 OR 1=1",
109
+ "' or ''='"
110
+ ]
111
+ values.each do |value|
112
+ it "@poefy.corpus.desc = #{value}" do
113
+ @poefy.corpus.desc = value
114
+ expect(@poefy.corpus.desc).to eq value
115
+ expect(@poefy.corpus.count).to be row_count
116
+ end
117
+ end
118
+ end
119
+
120
+ describe ":rhyme option" do
121
+
122
+ describe "should raise Poefy::MissingFormOrRhyme" do
123
+ it "blank, no argument" do
124
+ expect {
125
+ @poefy.poem
126
+ }.to raise_error(Poefy::MissingFormOrRhyme)
127
+ end
128
+ it "({ })" do
129
+ expect {
130
+ @poefy.poem ({ })
131
+ }.to raise_error(Poefy::MissingFormOrRhyme)
132
+ end
133
+ it "({ rhyme: nil })" do
134
+ expect {
135
+ @poefy.poem ({ rhyme: nil })
136
+ }.to raise_error(Poefy::MissingFormOrRhyme)
137
+ end
138
+ it "({ rhyme: ' ' })" do
139
+ expect {
140
+ @poefy.poem ({ rhyme: ' ' })
141
+ }.to raise_error(Poefy::MissingFormOrRhyme)
142
+ end
143
+ it "({ rhyme: '' })" do
144
+ expect {
145
+ @poefy.poem ({ rhyme: '' })
146
+ }.to raise_error(Poefy::MissingFormOrRhyme)
147
+ end
148
+ end
149
+
150
+ describe "should return correct number of lines" do
151
+ rhymes = %w{a b z A aa ab zz AA AB AA1 A1 B1 Z1 AB1 A1A1A1A1B1B1B1B1B1}
152
+ rhymes += ['A1A1A1 A1A1A1 B1B1B1B1B1B1','a b c a b c']
153
+ rhymes += [' abc','abc ',' abc ']
154
+ rhymes += ['n aaa n','n aXXXa N1']
155
+ rhymes.each do |i|
156
+ it "({ rhyme: '#{i}' })" do
157
+ poem = @poefy.poem ({ rhyme: i })
158
+ expect(poem.count).to be i.gsub(/[0-9]/,'').length
159
+ end
160
+ end
161
+ end
162
+
163
+ describe "should accept characters other than number" do
164
+ rhymes = %w{. , : .. ., ,, :: (()) @ ~ <<>< A1A1A1...a;}
165
+ rhymes.each do |i|
166
+ it "({ rhyme: '#{i}' })" do
167
+ poem = @poefy.poem ({ rhyme: i })
168
+ expect(poem.count).to be i.gsub(/[0-9]/,'').length
169
+ end
170
+ end
171
+ end
172
+
173
+ describe "should raise error if can't parse rhyme string" do
174
+ rhymes = %w{a1 b1 ab1 Ab1 AAAAABb1 1 1111 1122 11221 ;;::1. }
175
+ rhymes += ['AA Bb1','11 11','11 1 1','..1.']
176
+ rhymes.each do |i|
177
+ it "({ rhyme: '#{i}' })" do
178
+ expect {
179
+ @poefy.poem ({ rhyme: i })
180
+ }.to raise_error(Poefy::RhymeError)
181
+ end
182
+ end
183
+ end
184
+
185
+ describe "should raise error if can't complete rhyme string" do
186
+ rhymes = %w{aaaaaa abcd aaaaabbbbb}
187
+ rhymes.each do |i|
188
+ it "({ rhyme: '#{i}' })" do
189
+ expect {
190
+ @poefy.poem ({ rhyme: i })
191
+ }.to raise_error(Poefy::NotEnoughData)
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "should correctly repeat uppercase lines" do
197
+ lines = 200
198
+ it "({ rhyme: 'A' * #{lines} })" do
199
+ poem = @poefy.poem ({ rhyme: 'A' * lines })
200
+ expect(poem.count).to be lines
201
+ expect(poem.uniq.count).to be 1
202
+ end
203
+ it "({ rhyme: ('A'..'C').to_a.map { |i| i * #{lines} }.join })" do
204
+ rhyme = ('A'..'C').to_a.map { |i| i * lines }.join
205
+ poem = @poefy.poem ({ rhyme: rhyme })
206
+ expect(poem.count).to be lines * 3
207
+ expect(poem.uniq.count).to be 3
208
+ end
209
+ end
210
+
211
+ describe "should raise error if can't complete repeating rhyme string" do
212
+ lines = 200
213
+ it "({ rhyme: ('A'..'D').to_a.map { |i| i * #{lines} }.join })" do
214
+ rhyme = ('A'..'D').to_a.map { |i| i * lines }.join
215
+ expect {
216
+ @poefy.poem ({ rhyme: rhyme })
217
+ }.to raise_error(Poefy::NotEnoughData)
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+ describe ":form option" do
224
+
225
+ describe "should return correct number of lines" do
226
+ it "({ form: :default })" do
227
+ poem = @poefy.poem ({ form: :default })
228
+ expect(poem.count).to be 1
229
+ end
230
+ end
231
+
232
+ describe "should raise error if given a named form it can't fulfil" do
233
+ it "({ form: 'sonnet' })" do
234
+ expect {
235
+ @poefy.poem ({ form: 'sonnet' })
236
+ }.to raise_error(Poefy::NotEnoughData)
237
+ end
238
+ it "({ form: :villanelle })" do
239
+ expect {
240
+ @poefy.poem ({ form: 'villanelle' })
241
+ }.to raise_error(Poefy::NotEnoughData)
242
+ end
243
+ end
244
+
245
+ describe "should raise error if given a junk named form" do
246
+ it "({ form: 'sonnet_junk' })" do
247
+ expect {
248
+ @poefy.poem ({ form: 'sonnet_junk' })
249
+ }.to raise_error(Poefy::MissingFormOrRhyme)
250
+ end
251
+ it "({ form: :not_a_form })" do
252
+ expect {
253
+ @poefy.poem ({ form: :not_a_form })
254
+ }.to raise_error(Poefy::MissingFormOrRhyme)
255
+ end
256
+ it "({ form: :not_a_form, indent: '0010' })" do
257
+ expect {
258
+ @poefy.poem ({ form: :not_a_form, indent: '0010' })
259
+ }.to raise_error(Poefy::MissingFormOrRhyme)
260
+ end
261
+ end
262
+
263
+ describe "should be valid if given a junk named form, and a rhyme" do
264
+ it "({ form: :not_a_form, rhyme: 'abcb' })" do
265
+ poem = @poefy.poem ({ form: :not_a_form, rhyme: 'abcb' })
266
+ expect(poem.count).to be 4
267
+ end
268
+ end
269
+
270
+ describe "should overwrite a named form if another option is specified" do
271
+ it "({ form: 'default', rhyme: 'ab' })" do
272
+ poem = @poefy.poem ({ form: 'default', rhyme: 'ab' })
273
+ expect(poem.count).to be 2
274
+ end
275
+ it "({ form: :villanelle, rhyme: 'abcb' })" do
276
+ poem = @poefy.poem ({ form: :villanelle, rhyme: 'abcb' })
277
+ expect(poem.count).to be 4
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ ##############################################################################
284
+
285
+ describe "using dataset 'spec_shakespeare'" do
286
+
287
+ file_txt = "shakespeare_sonnets.txt"
288
+ file_db = "spec_shakespeare"
289
+
290
+ # All the Shakespeare lines are pentameter, so some forms should fail.
291
+ forms = Poefy::PoeticForms::POETIC_FORMS
292
+ forms_fail = [:limerick, :haiku, :common, :ballad, :double_dactyl]
293
+ forms_pass = forms.keys - forms_fail
294
+
295
+ before(:each) do
296
+ @poefy = Poefy::Poem.new(file_db, { proper: false })
297
+ end
298
+ after(:each) do
299
+ @poefy.close
300
+ end
301
+
302
+ it "initialised object not nil" do
303
+ expect(@poefy).to_not be_nil
304
+ end
305
+
306
+ describe "#make_database( '#{@root}/data/#{file_txt}', true )" do
307
+ it "should make the database '#{@root}/data/#{file_db}" do
308
+ input = `sed '/[a-z]/!d' #{@root}/data/#{file_txt}`
309
+ @poefy.make_database! input
310
+ expect(@poefy.corpus.exist?).to be true
311
+ end
312
+ end
313
+
314
+ describe "using acrostic option" do
315
+ describe "should return correct number of lines" do
316
+ it "({ form: :sonnet, acrostic: 'pauldpthompson' })" do
317
+ poem = @poefy.poem ({ form: :sonnet,
318
+ acrostic: 'pauldpthompson' })
319
+ expect(poem.count).to be 14
320
+ end
321
+ end
322
+ describe "should raise Poefy::NotEnoughData" do
323
+ it "({ form: :sonnet, acrostic: 'qqqqqqqqqqqqqq' })" do
324
+ expect {
325
+ @poefy.poem ({ form: :sonnet,
326
+ acrostic: 'qqqqqqqqqqqqqq' })
327
+ }.to raise_error(Poefy::NotEnoughData)
328
+ end
329
+ end
330
+ end
331
+
332
+ describe "using form string" do
333
+ describe "should return correct number of lines" do
334
+
335
+ # Make sure each form's lines match the expected output.
336
+ # Generate a few to be sure.
337
+ forms_pass.each do |form|
338
+ it "({ form: #{form} })" do
339
+ 10.times do
340
+ poem = @poefy.poem ({ form: form })
341
+ expect(poem.count).to satisfy do |c|
342
+ [*forms[form][:rhyme]].map do |r|
343
+ r.gsub(/[0-9]/,'').length
344
+ end.include?(c)
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end
350
+
351
+ describe "should raise Poefy::NotEnoughData" do
352
+ forms_fail.each do |form|
353
+ it "({ form: #{form} })" do
354
+ 4.times do
355
+ expect {
356
+ @poefy.poem ({ form: form })
357
+ }.to raise_error(Poefy::NotEnoughData)
358
+ end
359
+ end
360
+ end
361
+ end
362
+ end
363
+
364
+ describe "make sonnets" do
365
+ sonnet_options = [
366
+ { rhyme: 'ababcdcdefefgg' },
367
+ { rhyme: 'abab cdcd efef gg', indent: '0101 0101 0011 01' },
368
+ { form: 'sonnet' },
369
+ { form: :sonnet, syllable: 0 },
370
+ { form: :sonnet, syllable: 10 },
371
+ { form: :sonnet, regex: /^[A-Z].*$/ },
372
+ { form: :sonnet, regex: '^[A-Z].*$' },
373
+ { form: :sonnet, acrostic: 'pauldpthompson' },
374
+ { form: 'sonnet', indent: '01010101001101' },
375
+ { form: 'sonnet', proper: false }
376
+ ]
377
+ sonnet_options.each do |option|
378
+ it "#{option}" do
379
+ 4.times do
380
+ poem = @poefy.poem(option)
381
+ expect(poem).to_not be_nil
382
+ end
383
+ end
384
+ end
385
+ end
386
+ end
387
+
388
+ ##############################################################################
389
+
390
+ describe "using dataset 'spec_whitman'" do
391
+
392
+ file_txt = "whitman_leaves.txt"
393
+ file_db = "spec_whitman"
394
+
395
+ # There's a good mix of syllable count, so all forms should pass.
396
+ forms = Poefy::PoeticForms::POETIC_FORMS
397
+ forms_pass = forms.keys
398
+
399
+ before(:each) do
400
+ @poefy = Poefy::Poem.new(file_db, { proper: false })
401
+ end
402
+ after(:each) do
403
+ @poefy.close
404
+ end
405
+
406
+ it "initialised object not nil" do
407
+ expect(@poefy).to_not be_nil
408
+ end
409
+
410
+ describe "#make_database( '#{@root}/data/#{file_txt}', true )" do
411
+ it "should make the database '#{@root}/data/#{file_db}" do
412
+ input = `sed '/[a-z]/!d' #{@root}/data/#{file_txt}`
413
+ @poefy.make_database! input
414
+ expect(@poefy.corpus.exist?).to be true
415
+ end
416
+ end
417
+
418
+ describe "using form string" do
419
+ describe "should return correct number of lines" do
420
+
421
+ # Make sure each form's lines match the expected output.
422
+ # Generate a few to be sure.
423
+ forms_pass.each do |form|
424
+ it "({ form: #{form} })" do
425
+ 10.times do
426
+ poem = @poefy.poem ({ form: form })
427
+ expect(poem.count).to satisfy do |c|
428
+ [*forms[form][:rhyme]].map do |r|
429
+ r.gsub(/[0-9]/,'').length
430
+ end.include?(c)
431
+ end
432
+ end
433
+ end
434
+ end
435
+ end
436
+ end
437
+
438
+ describe "make sonnets" do
439
+ sonnet_options = [
440
+ { rhyme: 'ababcdcdefefgg' },
441
+ { rhyme: 'abab cdcd efef gg', indent: '0101 0101 0011 01' },
442
+ { form: 'sonnet' },
443
+ { form: :sonnet, syllable: 0 },
444
+ { form: :sonnet, syllable: 10 },
445
+ { form: :sonnet, regex: /^[A-Z].*$/ },
446
+ { form: :sonnet, regex: '^[A-Z].*$' },
447
+ { form: :sonnet, acrostic: 'pauldpthompson' },
448
+ { form: 'sonnet', indent: '01010101001101' },
449
+ { form: 'sonnet', proper: false }
450
+ ]
451
+ sonnet_options.each do |option|
452
+ it "#{option}" do
453
+ 4.times do
454
+ poem = @poefy.poem(option)
455
+ expect(poem).to_not be_nil
456
+ end
457
+ end
458
+ end
459
+ end
460
+
461
+ describe "using syllable string" do
462
+
463
+ it "({ rhyme: 'abcb defe', syllable: '[8,6,8,6,0,8,6,8,6]' })" do
464
+ options = {
465
+ rhyme: 'abcb defe',
466
+ syllable: '[8,6,8,6,0,8,6,8,6]'
467
+ }
468
+ poem = @poefy.poem (options)
469
+ expect(poem.count).to be options[:rhyme].length
470
+ end
471
+
472
+ it "({ rhyme: 'abcb defe', syllable: '[8,6,8,6,8,6,8,6]' })" do
473
+ options = {
474
+ rhyme: 'abcb defe',
475
+ syllable: '[8,6,8,6,8,6,8,6]'
476
+ }
477
+ poem = @poefy.poem (options)
478
+ expect(poem.count).to be options[:rhyme].length
479
+ end
480
+ end
481
+ end
482
+
483
+ ##############################################################################
484
+
485
+ describe "reusing the same Poem instance" do
486
+ it "should correctly merge the option hashes" do
487
+
488
+ # Default to use rondeau poetic form, and proper sentence validation
489
+ poefy = Poefy::Poem.new(
490
+ 'spec_shakespeare',
491
+ { form: 'rondeau', proper: true }
492
+ )
493
+
494
+ # Generate a properly sentenced rondeau
495
+ poem = poefy.poem
496
+ expect(poem.count).to be 17
497
+
498
+ # Generate a rondeau without proper validation
499
+ poem = poefy.poem ({ proper: false })
500
+ expect(poem.count).to be 17
501
+
502
+ # Generate a proper rondeau with a certain indentation
503
+ poem = poefy.poem ({ indent: '01012 0012 010112' })
504
+ expect(poem.count).to be 17
505
+
506
+ # Generate other forms
507
+ poem = poefy.poem ({ rhyme: 'abbaabbacdecde' })
508
+ expect(poem.count).to be 14
509
+ poem = poefy.poem ({ form: 'sonnet' })
510
+ expect(poem.count).to be 14
511
+ poem = poefy.poem ({ form: 'ballade' })
512
+ expect(poem.count).to be 31
513
+
514
+ # Generate a default rondeau again
515
+ poem = poefy.poem
516
+ expect(poem.count).to be 17
517
+
518
+ poefy.close
519
+ end
520
+ end
521
+
522
+ ##############################################################################
523
+
524
+ describe "using the transform option" do
525
+
526
+ it "should correctly transform the output 1" do
527
+ poefy = Poefy::Poem.new :spec_shakespeare
528
+ transform_hash = {
529
+ 4 => proc { |line, num, poem| line.upcase },
530
+ 12 => proc { |line, num, poem| line.upcase }
531
+ }
532
+ poem = poefy.poem({ form: :sonnet, transform: transform_hash })
533
+ expect(poem.count).to be 14
534
+ expect(poem[3]).to eq poem[3].upcase
535
+ expect(poem[11]).to eq poem[11].upcase
536
+ poefy.close
537
+ end
538
+
539
+ it "should correctly transform the output 2" do
540
+ poefy = Poefy::Poem.new :spec_shakespeare
541
+ transform_hash = {
542
+ 4 => proc { |line, num, poem| poem.count },
543
+ -3 => proc { |line, num, poem| poem.count },
544
+ 7 => proc { |line, num, poem| 'test string' }
545
+ }
546
+ poem = poefy.poem({ form: :sonnet, transform: transform_hash })
547
+ expect(poem.count).to be 14
548
+ expect(poem[3]).to eq '14'
549
+ expect(poem[11]).to eq '14'
550
+ expect(poem[6]).to eq 'test string'
551
+ poefy.close
552
+ end
553
+
554
+ it "should correctly transform the output 3" do
555
+ poefy = Poefy::Poem.new :spec_shakespeare
556
+ transform_proc = proc { |line, num, poem| line.downcase }
557
+ poem = poefy.poem({ form: :sonnet, transform: transform_proc })
558
+ expect(poem.count).to be 14
559
+ poem.each do |i|
560
+ expect(i).to eq i.downcase
561
+ end
562
+ poefy.close
563
+ end
564
+
565
+ it "should correctly transform the output 4" do
566
+ poefy = Poefy::Poem.new :spec_shakespeare
567
+ transform_proc = proc { |line, num, poem| "#{num} #{line.downcase}" }
568
+ poem = poefy.poem({ form: :sonnet, transform: transform_proc })
569
+ expect(poem.count).to be 14
570
+ poem.each.with_index do |line, index|
571
+ expect(line).to eq line.downcase
572
+ first_word = line.split(' ').first
573
+ expect(first_word).to eq (index + 1).to_s
574
+ end
575
+ poefy.close
576
+ end
577
+ end
578
+
579
+ ##############################################################################
580
+
581
+ describe "using the form_from_text option" do
582
+ before(:all) do
583
+ @text = <<-TEXT
584
+ [Chorus 1]
585
+ Oh yeah, I'll tell you something
586
+ I think you'll understand
587
+ When I'll say that something
588
+ I want to hold your hand
589
+ I want to hold your hand
590
+ I want to hold your hand
591
+
592
+ [Verse 1]
593
+ Oh please, say to me
594
+ You'll let me be your man
595
+ And please, say to me
596
+ You'll let me hold your hand
597
+ I'll let me hold your hand
598
+ I want to hold your hand
599
+ TEXT
600
+ @line_count = @text.split("\n").count
601
+ end
602
+
603
+ it "should use the exact poetic form 1" do
604
+ poefy = Poefy::Poem.new(:spec_whitman, {
605
+ form_from_text: @text
606
+ })
607
+ poem = poefy.poem
608
+ poem.map!(&:strip!)
609
+ expect(poem.count).to be @line_count
610
+ expect(poem[0]).to eq "[Chorus 1]"
611
+ expect(poem[8]).to eq "[Verse 1]"
612
+ expect(poem[5]).to eq poem[4]
613
+ expect(poem[6]).to eq poem[4]
614
+ poefy.close
615
+ end
616
+
617
+ it "should use the exact poetic form 2" do
618
+ poefy = Poefy::Poem.new :spec_whitman
619
+ poem = poefy.poem({
620
+ form_from_text: @text
621
+ })
622
+ poem.map!(&:strip!)
623
+ expect(poem.count).to be @line_count
624
+ expect(poem[0]).to eq "[Chorus 1]"
625
+ expect(poem[8]).to eq "[Verse 1]"
626
+ expect(poem[5]).to eq poem[4]
627
+ expect(poem[6]).to eq poem[4]
628
+ poefy.close
629
+ end
630
+
631
+ it "should correctly modify the poetic form 1" do
632
+ poefy = Poefy::Poem.new(:spec_whitman, {
633
+ form_from_text: @text,
634
+ syllable: 6
635
+ })
636
+ poem = poefy.poem
637
+ poem.map!(&:strip!)
638
+ expect(poem.count).to be @line_count
639
+ expect(poem[0]).to eq "[Chorus 1]"
640
+ expect(poem[8]).to eq "[Verse 1]"
641
+ expect(poem[5]).to eq poem[4]
642
+ expect(poem[6]).to eq poem[4]
643
+ poefy.close
644
+ end
645
+
646
+ it "should correctly modify the poetic form 2" do
647
+ poefy = Poefy::Poem.new :spec_whitman
648
+ poem = poefy.poem({
649
+ form_from_text: @text,
650
+ syllable: 6
651
+ })
652
+ poem.map!(&:strip!)
653
+ expect(poem.count).to be @line_count
654
+ expect(poem[0]).to eq "[Chorus 1]"
655
+ expect(poem[8]).to eq "[Verse 1]"
656
+ expect(poem[5]).to eq poem[4]
657
+ expect(poem[6]).to eq poem[4]
658
+ poefy.close
659
+ end
660
+
661
+ it "should correctly modify the poetic form 3" do
662
+ poefy = Poefy::Poem.new(:spec_whitman, {
663
+ form_from_text: @text
664
+ })
665
+ poem = poefy.poem({
666
+ syllable: 6
667
+ })
668
+ poem.map!(&:strip!)
669
+ expect(poem.count).to be @line_count
670
+ expect(poem[0]).to eq "[Chorus 1]"
671
+ expect(poem[8]).to eq "[Verse 1]"
672
+ expect(poem[5]).to eq poem[4]
673
+ expect(poem[6]).to eq poem[4]
674
+ poefy.close
675
+ end
676
+
677
+ it "should correctly replace the poetic form" do
678
+ poefy = Poefy::Poem.new(:spec_whitman, {
679
+ syllable: 6
680
+ })
681
+ poem = poefy.poem({
682
+ form_from_text: @text
683
+ })
684
+ poem.map!(&:strip!)
685
+ expect(poem.count).to be @line_count
686
+ expect(poem[0]).to eq "[Chorus 1]"
687
+ expect(poem[8]).to eq "[Verse 1]"
688
+ expect(poem[5]).to eq poem[4]
689
+ expect(poem[6]).to eq poem[4]
690
+ poefy.close
691
+ end
692
+
693
+ end
694
+
695
+ end
696
+
697
+ ################################################################################