poefy-pg 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|