poefy-pg 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +77 -0
- data/.rspec +1 -0
- data/Gemfile +2 -0
- data/LICENSE +13 -0
- data/README.md +7 -0
- data/Rakefile +8 -0
- data/lib/poefy/pg/version.rb +24 -0
- data/lib/poefy/pg.rb +295 -0
- data/poefy-pg.gemspec +31 -0
- data/spec/poefy_pg_spec.rb +682 -0
- data/spec/spec_helper.rb +11 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 562ca9a5d0e1e8fc84fce3f1d2cc1191f67b72b8
|
4
|
+
data.tar.gz: 532339860c2f1ad84288c8232162b31de8854154
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8a95524ade873f8ff08785a8d4abdb94bb808f15c92fb73bf5fb6daa11f6c9f62f288ef86d44fc305f186a31eb6ea2369927f9471a769b00bb88c6a713cfa270
|
7
|
+
data.tar.gz: 1f7f41a631894cb7191805f0d8024290dc2757c0f1fdcd2c10ba4d3c6a69dbf4f5341407d5174262ce1f8ec00c0ef146339dea24cf540d688d713b35580863b6
|
data/.gitignore
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
################################################################################
|
3
|
+
# Ruby specific files
|
4
|
+
|
5
|
+
*.gem
|
6
|
+
*.rbc
|
7
|
+
/.config
|
8
|
+
/coverage/
|
9
|
+
/InstalledFiles
|
10
|
+
/pkg/
|
11
|
+
/spec/reports/
|
12
|
+
/test/tmp/
|
13
|
+
/test/version_tmp/
|
14
|
+
/tmp/
|
15
|
+
|
16
|
+
## Specific to RubyMotion:
|
17
|
+
.dat*
|
18
|
+
.repl_history
|
19
|
+
build/
|
20
|
+
|
21
|
+
## Documentation cache and generated files:
|
22
|
+
/.yardoc/
|
23
|
+
/_yardoc/
|
24
|
+
/doc/
|
25
|
+
/rdoc/
|
26
|
+
|
27
|
+
## Environment normalisation:
|
28
|
+
/.bundle/
|
29
|
+
/vendor/bundle
|
30
|
+
/lib/bundler/man/
|
31
|
+
|
32
|
+
# for a library or gem, you might want to ignore these files since the code is
|
33
|
+
# intended to run in multiple environments; otherwise, check them in:
|
34
|
+
Gemfile.lock
|
35
|
+
.ruby-version
|
36
|
+
.ruby-gemset
|
37
|
+
|
38
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
39
|
+
.rvmrc
|
40
|
+
|
41
|
+
################################################################################
|
42
|
+
# Rails stuff
|
43
|
+
|
44
|
+
# Ignore all logfiles and tempfiles.
|
45
|
+
/log/*
|
46
|
+
/tmp/*
|
47
|
+
!/log/.keep
|
48
|
+
!/tmp/.keep
|
49
|
+
|
50
|
+
# Ignore Byebug command history file.
|
51
|
+
.byebug_history
|
52
|
+
|
53
|
+
# Ignore application configuration
|
54
|
+
/config/application.yml
|
55
|
+
|
56
|
+
################################################################################
|
57
|
+
# System and config files
|
58
|
+
desktop.ini
|
59
|
+
.agignore
|
60
|
+
.ignore
|
61
|
+
*.lnk
|
62
|
+
|
63
|
+
################################################################################
|
64
|
+
# App specific files
|
65
|
+
|
66
|
+
# Development files
|
67
|
+
work*.rb
|
68
|
+
/~/
|
69
|
+
|
70
|
+
# Config files
|
71
|
+
settings.yml
|
72
|
+
|
73
|
+
# Data files
|
74
|
+
/data/
|
75
|
+
|
76
|
+
# Output files
|
77
|
+
/output/
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (C) 2017 Paul Thompson
|
2
|
+
|
3
|
+
This program is free software: you can redistribute it and/or modify
|
4
|
+
it under the terms of the GNU General Public License as published by
|
5
|
+
the Free Software Foundation, either version 3 of the License, or
|
6
|
+
(at your option) any later version.
|
7
|
+
|
8
|
+
This program is distributed in the hope that it will be useful,
|
9
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
GNU General Public License for more details.
|
12
|
+
|
13
|
+
Full text of this licence: <https://www.gnu.org/licenses/gpl.html>
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
module Poefy
|
5
|
+
|
6
|
+
module Pg
|
7
|
+
|
8
|
+
def self.version_number
|
9
|
+
major = 0
|
10
|
+
minor = 1
|
11
|
+
tiny = 0
|
12
|
+
pre = nil
|
13
|
+
|
14
|
+
string = [major, minor, tiny, pre].compact.join('.')
|
15
|
+
Gem::Version.new string
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.version_date
|
19
|
+
'2017-10-02'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/poefy/pg.rb
ADDED
@@ -0,0 +1,295 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Encoding: UTF-8
|
3
|
+
|
4
|
+
################################################################################
|
5
|
+
# Extend 'Database' class for connecting to a PostgreSQL database.
|
6
|
+
# These methods are specific to PostgreSQL.
|
7
|
+
# Other databases should be implemented in separate gems.
|
8
|
+
################################################################################
|
9
|
+
|
10
|
+
require 'pg'
|
11
|
+
|
12
|
+
################################################################################
|
13
|
+
|
14
|
+
module Poefy
|
15
|
+
|
16
|
+
class Database
|
17
|
+
|
18
|
+
# Open a connection, execute a query, close the connection.
|
19
|
+
def self.single_exec! sql, sql_args = nil
|
20
|
+
output = nil
|
21
|
+
begin
|
22
|
+
con = PG.connect(
|
23
|
+
:dbname => 'poefy',
|
24
|
+
:user => 'poefy',
|
25
|
+
:password => 'poefy'
|
26
|
+
)
|
27
|
+
output = if sql_args
|
28
|
+
con.exec(sql, [*sql_args]).values
|
29
|
+
else
|
30
|
+
con.exec(sql).values
|
31
|
+
end
|
32
|
+
ensure
|
33
|
+
con.close if con
|
34
|
+
end
|
35
|
+
output
|
36
|
+
end
|
37
|
+
|
38
|
+
# List all tables in the database.
|
39
|
+
# Does not include tables used for testing.
|
40
|
+
def self.list
|
41
|
+
rs = Database::single_exec! <<-SQL
|
42
|
+
SELECT table_name
|
43
|
+
FROM information_schema.tables
|
44
|
+
WHERE table_schema = 'public';
|
45
|
+
SQL
|
46
|
+
rs.flatten.reject do |i|
|
47
|
+
i.start_with?('spec_')
|
48
|
+
end.sort - ['test']
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get the description of a table.
|
52
|
+
def self.desc table_name
|
53
|
+
begin
|
54
|
+
sql = "SELECT obj_description($1::regclass, 'pg_class');"
|
55
|
+
single_exec!(sql, [table_name]).flatten.first.to_s
|
56
|
+
rescue
|
57
|
+
''
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# List all database files and their descriptions.
|
62
|
+
def self.list_with_desc
|
63
|
+
Database::list.map do |i|
|
64
|
+
begin
|
65
|
+
[i, Database::desc(i)]
|
66
|
+
rescue
|
67
|
+
[i, '']
|
68
|
+
end
|
69
|
+
end.to_h
|
70
|
+
end
|
71
|
+
|
72
|
+
############################################################################
|
73
|
+
|
74
|
+
# This is the type of database that is being used.
|
75
|
+
# It is also used as a signifier that a database has been specified.
|
76
|
+
def type
|
77
|
+
'pg'
|
78
|
+
end
|
79
|
+
|
80
|
+
# Get/set the description of the table.
|
81
|
+
def desc
|
82
|
+
Database::desc table
|
83
|
+
end
|
84
|
+
def desc=(description)
|
85
|
+
safe_desc = description.to_s.gsub("'","''")
|
86
|
+
execute! "COMMENT ON TABLE #{table} IS '#{safe_desc}';"
|
87
|
+
end
|
88
|
+
|
89
|
+
# The number of lines in the table.
|
90
|
+
def count
|
91
|
+
return 0 if not exists?
|
92
|
+
sql = "SELECT COUNT(*) AS num FROM #{table};"
|
93
|
+
execute!(sql).first['num'].to_i
|
94
|
+
end
|
95
|
+
|
96
|
+
# See if the table exists or not.
|
97
|
+
# Attempt to access table, and return false on error.
|
98
|
+
def exists?
|
99
|
+
open_connection
|
100
|
+
@db.exec("SELECT $1::regclass", [*table])
|
101
|
+
true
|
102
|
+
rescue PG::UndefinedTable
|
103
|
+
false
|
104
|
+
end
|
105
|
+
|
106
|
+
# Get all rhyming lines for the word.
|
107
|
+
def rhymes word, key = nil
|
108
|
+
return nil if word.nil?
|
109
|
+
|
110
|
+
sql = <<-SQL
|
111
|
+
SELECT rhyme, final_word, syllables, line
|
112
|
+
FROM #{table}
|
113
|
+
WHERE rhyme = $1
|
114
|
+
ORDER BY rhyme, final_word, syllables, line
|
115
|
+
SQL
|
116
|
+
output = word.to_phrase.rhymes.keys.map do |rhyme|
|
117
|
+
execute!(sql, [rhyme]).to_a
|
118
|
+
end.flatten
|
119
|
+
|
120
|
+
if !key.nil? and %w[rhyme final_word syllables line].include?(key)
|
121
|
+
output.map!{ |i| i[key] }
|
122
|
+
end
|
123
|
+
output
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
# The name of the table.
|
129
|
+
def table
|
130
|
+
@name
|
131
|
+
end
|
132
|
+
|
133
|
+
# Create a new table.
|
134
|
+
def new_connection
|
135
|
+
open_connection
|
136
|
+
end
|
137
|
+
|
138
|
+
# Open a connection to the database.
|
139
|
+
def open_connection
|
140
|
+
@db ||= PG.connect(
|
141
|
+
:dbname => 'poefy',
|
142
|
+
:user => 'poefy',
|
143
|
+
:password => 'poefy'
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Execute a query.
|
148
|
+
def execute! sql, *args
|
149
|
+
db.exec sql, *args
|
150
|
+
end
|
151
|
+
|
152
|
+
# Insert an array of lines.
|
153
|
+
def insert_lines table_name, rows
|
154
|
+
sql = "INSERT INTO #{table_name} VALUES ( $1, $2, $3, $4 )"
|
155
|
+
db.transaction do |db_tr|
|
156
|
+
rows.each do |line|
|
157
|
+
db_tr.exec sql, line
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
##########################################################################
|
163
|
+
|
164
|
+
# Create the table and the index.
|
165
|
+
def create_table table_name, description = nil
|
166
|
+
index_name = 'idx_' + table_name
|
167
|
+
execute! <<-SQL
|
168
|
+
SET client_min_messages TO WARNING;
|
169
|
+
DROP INDEX IF EXISTS #{index_name};
|
170
|
+
DROP TABLE IF EXISTS #{table_name};
|
171
|
+
CREATE TABLE #{table_name} (
|
172
|
+
line TEXT,
|
173
|
+
syllables SMALLINT,
|
174
|
+
final_word TEXT,
|
175
|
+
rhyme TEXT
|
176
|
+
);
|
177
|
+
CREATE INDEX #{index_name} ON #{table_name} (
|
178
|
+
rhyme, final_word, line
|
179
|
+
);
|
180
|
+
SQL
|
181
|
+
self.desc = description
|
182
|
+
end
|
183
|
+
|
184
|
+
##########################################################################
|
185
|
+
|
186
|
+
# Define SQL of the stored procedures.
|
187
|
+
def sprocs_sql_hash
|
188
|
+
sql = {}
|
189
|
+
sql[:rbc] = <<-SQL
|
190
|
+
SELECT rhyme, COUNT(rhyme) AS count
|
191
|
+
FROM (
|
192
|
+
SELECT rhyme, final_word, COUNT(final_word) AS wc
|
193
|
+
FROM #{table}
|
194
|
+
GROUP BY rhyme, final_word
|
195
|
+
) AS sub_table
|
196
|
+
GROUP BY rhyme
|
197
|
+
HAVING COUNT(rhyme) >= $1
|
198
|
+
SQL
|
199
|
+
sql[:rbcs] = <<-SQL
|
200
|
+
SELECT rhyme, COUNT(rhyme) AS count
|
201
|
+
FROM (
|
202
|
+
SELECT rhyme, final_word, COUNT(final_word) AS wc
|
203
|
+
FROM #{table}
|
204
|
+
WHERE syllables BETWEEN $1 AND $2
|
205
|
+
GROUP BY rhyme, final_word
|
206
|
+
) AS sub_table
|
207
|
+
GROUP BY rhyme
|
208
|
+
HAVING COUNT(rhyme) >= $3
|
209
|
+
SQL
|
210
|
+
sql[:la] = <<-SQL
|
211
|
+
SELECT line, syllables, final_word, rhyme
|
212
|
+
FROM #{table} WHERE rhyme = $1
|
213
|
+
SQL
|
214
|
+
sql[:las] = <<-SQL
|
215
|
+
SELECT line, syllables, final_word, rhyme
|
216
|
+
FROM #{table} WHERE rhyme = $1
|
217
|
+
AND syllables BETWEEN $2 AND $3
|
218
|
+
SQL
|
219
|
+
sql
|
220
|
+
end
|
221
|
+
|
222
|
+
# Create the stored procedures in the database.
|
223
|
+
def create_sprocs
|
224
|
+
sprocs_sql_hash.each do |key, value|
|
225
|
+
db.prepare key.to_s, value
|
226
|
+
end
|
227
|
+
rescue
|
228
|
+
handle_error \
|
229
|
+
"ERROR: Database table structure is invalid.\n" +
|
230
|
+
" Please manually DROP the corrupt table and recreate it."
|
231
|
+
end
|
232
|
+
|
233
|
+
# Find rhymes and counts greater than a certain length.
|
234
|
+
def sproc_rhymes_by_count rhyme_count
|
235
|
+
rs = db.exec_prepared 'rbc', [rhyme_count]
|
236
|
+
rs.values.map do |row|
|
237
|
+
{
|
238
|
+
'rhyme' => row[0],
|
239
|
+
'count' => row[1].to_i
|
240
|
+
}
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Also adds syllable selection.
|
245
|
+
def sproc_rhymes_by_count_syllables rhyme_count, syllable_min_max
|
246
|
+
arg_array = [
|
247
|
+
syllable_min_max[:min],
|
248
|
+
syllable_min_max[:max],
|
249
|
+
rhyme_count
|
250
|
+
]
|
251
|
+
rs = db.exec_prepared 'rbcs', arg_array
|
252
|
+
rs.values.map do |row|
|
253
|
+
{
|
254
|
+
'rhyme' => row[0],
|
255
|
+
'count' => row[1].to_i
|
256
|
+
}
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Find all lines for a certain rhyme.
|
261
|
+
def sproc_lines_by_rhyme rhyme
|
262
|
+
rs = db.exec_prepared 'la', [rhyme]
|
263
|
+
rs.values.map do |row|
|
264
|
+
{
|
265
|
+
'line' => row[0],
|
266
|
+
'syllables' => row[1].to_i,
|
267
|
+
'final_word' => row[2],
|
268
|
+
'rhyme' => row[3]
|
269
|
+
}
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# Also adds syllable selection.
|
274
|
+
def sproc_lines_by_rhyme_syllables rhyme, syllable_min_max
|
275
|
+
arg_array = [
|
276
|
+
rhyme,
|
277
|
+
syllable_min_max[:min],
|
278
|
+
syllable_min_max[:max]
|
279
|
+
]
|
280
|
+
rs = db.exec_prepared 'las', arg_array
|
281
|
+
rs.values.map do |row|
|
282
|
+
{
|
283
|
+
'line' => row[0],
|
284
|
+
'syllables' => row[1].to_i,
|
285
|
+
'final_word' => row[2],
|
286
|
+
'rhyme' => row[3]
|
287
|
+
}
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
################################################################################
|
data/poefy-pg.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Encoding: UTF-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'poefy/pg/version.rb'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'poefy-pg'
|
9
|
+
s.authors = ['Paul Thompson']
|
10
|
+
s.email = ['nossidge@gmail.com']
|
11
|
+
|
12
|
+
s.summary = %q{PostgreSQL interface for the 'poefy' gem}
|
13
|
+
s.description = %q{PostgreSQL interface for the 'poefy' gem}
|
14
|
+
s.homepage = 'https://github.com/nossidge/poefy-pg'
|
15
|
+
|
16
|
+
s.version = Poefy::Pg.version_number
|
17
|
+
s.date = Poefy::Pg.version_date
|
18
|
+
s.license = 'GPL-3.0'
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.require_paths = ['lib']
|
23
|
+
|
24
|
+
s.add_development_dependency('bundler', '~> 1.13')
|
25
|
+
s.add_development_dependency('rake', '~> 10.0')
|
26
|
+
s.add_development_dependency('rspec', '~> 3.0')
|
27
|
+
s.add_development_dependency('ruby_rhymes', '~> 0.1')
|
28
|
+
|
29
|
+
s.add_runtime_dependency('poefy', '~> 1.0', '>= 1.0.0')
|
30
|
+
s.add_runtime_dependency('pg', '~> 0.21', '>= 0.21.0')
|
31
|
+
end
|
@@ -0,0 +1,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.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
|
+
################################################################################
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: poefy-pg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Thompson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-10-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: ruby_rhymes
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: poefy
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.0.0
|
79
|
+
type: :runtime
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '1.0'
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.0.0
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: pg
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0.21'
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 0.21.0
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0.21'
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 0.21.0
|
109
|
+
description: PostgreSQL interface for the 'poefy' gem
|
110
|
+
email:
|
111
|
+
- nossidge@gmail.com
|
112
|
+
executables: []
|
113
|
+
extensions: []
|
114
|
+
extra_rdoc_files: []
|
115
|
+
files:
|
116
|
+
- ".gitignore"
|
117
|
+
- ".rspec"
|
118
|
+
- Gemfile
|
119
|
+
- LICENSE
|
120
|
+
- README.md
|
121
|
+
- Rakefile
|
122
|
+
- lib/poefy/pg.rb
|
123
|
+
- lib/poefy/pg/version.rb
|
124
|
+
- poefy-pg.gemspec
|
125
|
+
- spec/poefy_pg_spec.rb
|
126
|
+
- spec/spec_helper.rb
|
127
|
+
homepage: https://github.com/nossidge/poefy-pg
|
128
|
+
licenses:
|
129
|
+
- GPL-3.0
|
130
|
+
metadata: {}
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 2.5.2
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: PostgreSQL interface for the 'poefy' gem
|
151
|
+
test_files: []
|