typingpool 0.7.0 → 0.7.1
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.
- data/LICENSE +20 -0
- data/README.markdown +452 -0
- data/lib/typingpool/amazon/hit/assignment/empty.rb +19 -0
- data/lib/typingpool/amazon/hit/assignment.rb +43 -0
- data/lib/typingpool/amazon/hit/full/fromsearchhits.rb +44 -0
- data/lib/typingpool/amazon/hit/full.rb +105 -0
- data/lib/typingpool/amazon/hit.rb +458 -0
- data/lib/typingpool/amazon/question.rb +45 -0
- data/lib/typingpool/amazon.rb +3 -677
- data/lib/typingpool/app/cli/formatter.rb +16 -0
- data/lib/typingpool/app/cli.rb +64 -0
- data/lib/typingpool/app/friendlyexceptions.rb +34 -0
- data/lib/typingpool/app.rb +2 -97
- data/lib/typingpool/config/root.rb +114 -0
- data/lib/typingpool/config.rb +13 -119
- data/lib/typingpool/filer/audio.rb +84 -0
- data/lib/typingpool/filer/csv.rb +57 -0
- data/lib/typingpool/filer/dir.rb +76 -0
- data/lib/typingpool/filer/files/audio.rb +63 -0
- data/lib/typingpool/filer/files.rb +55 -0
- data/lib/typingpool/filer.rb +4 -313
- data/lib/typingpool/project/local.rb +117 -0
- data/lib/typingpool/project/remote/s3.rb +135 -0
- data/lib/typingpool/project/remote/sftp.rb +100 -0
- data/lib/typingpool/project/remote.rb +65 -0
- data/lib/typingpool/project.rb +2 -396
- data/lib/typingpool/template/assignment.rb +17 -0
- data/lib/typingpool/template/env.rb +77 -0
- data/lib/typingpool/template.rb +2 -87
- data/lib/typingpool/test/script.rb +310 -0
- data/lib/typingpool/test.rb +1 -306
- data/lib/typingpool/transcript/chunk.rb +129 -0
- data/lib/typingpool/transcript.rb +1 -125
- data/lib/typingpool/utility/castable.rb +65 -0
- data/lib/typingpool/utility.rb +1 -61
- data/test/test_integration_script_6_tp_finish.rb +1 -0
- metadata +135 -81
@@ -0,0 +1,310 @@
|
|
1
|
+
module Typingpool
|
2
|
+
class Test
|
3
|
+
class Script < Test
|
4
|
+
require 'typingpool'
|
5
|
+
require 'yaml'
|
6
|
+
require 'open3'
|
7
|
+
|
8
|
+
|
9
|
+
def audio_files(subdir='mp3')
|
10
|
+
dir = File.join(audio_dir, subdir)
|
11
|
+
Dir.entries(dir).reject{|entry| entry.match(/^\./) }.map{|entry| File.join(dir, entry)}.select{|path| File.file?(path) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def config_path(dir)
|
15
|
+
::File.join(dir, project_default[:config_filename])
|
16
|
+
end
|
17
|
+
|
18
|
+
def config_from_dir(dir)
|
19
|
+
Config.file(config_path(dir))
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def setup_amazon(dir)
|
24
|
+
Amazon.setup(:sandbox => true, :config => config_from_dir(dir))
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def in_temp_tp_dir
|
29
|
+
::Dir.mktmpdir('typingpool_') do |dir|
|
30
|
+
setup_temp_tp_dir(dir)
|
31
|
+
yield(dir)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def setup_temp_tp_dir(dir)
|
36
|
+
make_temp_tp_dir_config(dir)
|
37
|
+
Dir.mkdir(File.join(dir, 'projects'))
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup_s3_config(dir, config=config_from_dir(dir), filename='.config_s3')
|
41
|
+
return unless s3_credentials?(config)
|
42
|
+
config.to_hash.delete('sftp')
|
43
|
+
write_config(config, dir, filename)
|
44
|
+
end
|
45
|
+
|
46
|
+
def setup_s3_config_with_bad_password(dir, config=config_from_dir(dir))
|
47
|
+
bad_password = 'f'
|
48
|
+
refute_equal(config.to_hash['amazon']['secret'], bad_password)
|
49
|
+
config.to_hash['amazon']['secret'] = bad_password
|
50
|
+
setup_s3_config(dir, config, '.config_s3_bad')
|
51
|
+
end
|
52
|
+
|
53
|
+
def make_temp_tp_dir_config(dir, config=self.config)
|
54
|
+
config.transcripts = File.join(dir, 'projects')
|
55
|
+
config.cache = File.join(dir, '.cache')
|
56
|
+
config['assign']['reward'] = '0.02'
|
57
|
+
config.assign.to_hash.delete('qualify')
|
58
|
+
write_config(config, dir, project_default[:config_filename])
|
59
|
+
end
|
60
|
+
|
61
|
+
def write_config(config, dir, filename=project_default[:config_filename])
|
62
|
+
path = ::File.join(dir, filename)
|
63
|
+
::File.open(path, 'w') do |out|
|
64
|
+
out << YAML.dump(config.to_hash)
|
65
|
+
end
|
66
|
+
path
|
67
|
+
end
|
68
|
+
|
69
|
+
def temp_tp_dir_project_dir(temp_tp_dir)
|
70
|
+
::File.join(temp_tp_dir, 'projects', project_default[:title])
|
71
|
+
end
|
72
|
+
|
73
|
+
def temp_tp_dir_project(dir, config=config_from_dir(dir))
|
74
|
+
Project.new(project_default[:title], config)
|
75
|
+
end
|
76
|
+
|
77
|
+
def call_script(*args)
|
78
|
+
Utility.system_quietly(*args)
|
79
|
+
end
|
80
|
+
|
81
|
+
def path_to_tp_make
|
82
|
+
::File.join(self.class.app_dir, 'bin', 'tp-make')
|
83
|
+
end
|
84
|
+
|
85
|
+
def call_tp_make(*args)
|
86
|
+
call_script(path_to_tp_make, *args)
|
87
|
+
end
|
88
|
+
|
89
|
+
def tp_make(in_dir, config=config_path(in_dir), audio_subdir='mp3')
|
90
|
+
call_tp_make(
|
91
|
+
'--config', config,
|
92
|
+
'--chunks', project_default[:chunks],
|
93
|
+
*[:title, :subtitle].map{|param| ["--#{param}", project_default[param]] }.flatten,
|
94
|
+
*[:voice, :unusual].map{|param| project_default[param].map{|value| ["--#{param}", value] } }.flatten,
|
95
|
+
*audio_files(audio_subdir).map{|path| ['--file', path]}.flatten
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
def path_to_tp_finish
|
100
|
+
::File.join(self.class.app_dir, 'bin', 'tp-finish')
|
101
|
+
end
|
102
|
+
|
103
|
+
def call_tp_finish(*args)
|
104
|
+
call_script(path_to_tp_finish, *args)
|
105
|
+
end
|
106
|
+
|
107
|
+
def tp_finish(dir, config_path=self.config_path(dir))
|
108
|
+
tp_finish_inside_sandbox(dir, config_path)
|
109
|
+
tp_finish_outside_sandbox(dir, config_path)
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
def tp_finish_inside_sandbox(dir, config_path=self.config_path(dir))
|
114
|
+
tp_finish_outside_sandbox(dir, config_path, '--sandbox')
|
115
|
+
end
|
116
|
+
|
117
|
+
def tp_finish_outside_sandbox(dir, config_path=self.config_path(dir), *args)
|
118
|
+
call_tp_finish(
|
119
|
+
project_default[:title],
|
120
|
+
'--config', config_path,
|
121
|
+
*args
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def path_to_tp_assign
|
126
|
+
File.join(self.class.app_dir, 'bin', 'tp-assign')
|
127
|
+
end
|
128
|
+
|
129
|
+
def call_tp_assign(*args)
|
130
|
+
call_script(path_to_tp_assign, '--sandbox', *args)
|
131
|
+
end
|
132
|
+
|
133
|
+
def assign_default
|
134
|
+
Hash[
|
135
|
+
:template => 'interview/phone',
|
136
|
+
:deadline => '5h',
|
137
|
+
:lifetime => '10h',
|
138
|
+
:approval => '10h',
|
139
|
+
:qualify => ['approval_rate >= 90', 'hits_approved > 10'],
|
140
|
+
:keyword => ['test', 'mp3', 'typingpooltest']
|
141
|
+
]
|
142
|
+
end
|
143
|
+
|
144
|
+
def tp_assign(dir, config_path=config_path(dir))
|
145
|
+
call_tp_assign(
|
146
|
+
project_default[:title],
|
147
|
+
assign_default[:template],
|
148
|
+
'--config', config_path,
|
149
|
+
*[:deadline, :lifetime, :approval].map{|param| ["--#{param}", assign_default[param]] }.flatten,
|
150
|
+
*[:qualify, :keyword].map{|param| assign_default[param].map{|value| ["--#{param}", value] } }.flatten
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
def path_to_tp_collect
|
155
|
+
File.join(self.class.app_dir, 'bin', 'tp-collect')
|
156
|
+
end
|
157
|
+
|
158
|
+
def call_tp_collect(fixture_path, *args)
|
159
|
+
call_script(path_to_tp_collect, '--sandbox', '--fixture', fixture_path, *args)
|
160
|
+
end
|
161
|
+
|
162
|
+
def tp_collect_with_fixture(dir, fixture_path)
|
163
|
+
call_tp_collect(
|
164
|
+
fixture_path,
|
165
|
+
'--config', config_path(dir)
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
def path_to_tp_review
|
171
|
+
File.join(self.class.app_dir, 'bin', 'tp-review')
|
172
|
+
end
|
173
|
+
|
174
|
+
def tp_review_with_fixture(dir, fixture_path, choices)
|
175
|
+
output = {}
|
176
|
+
Open3.popen3(path_to_tp_review, '--sandbox', '--fixture', fixture_path, '--config', config_path(dir), project_default[:title]) do |stdin, stdout, stderr, wait_thr|
|
177
|
+
choices.each do |choice|
|
178
|
+
stdin.puts(choice)
|
179
|
+
if choice.strip.match(/^r/i)
|
180
|
+
stdin.puts("No reason - this is a test")
|
181
|
+
end
|
182
|
+
end
|
183
|
+
output[:out] = stdout.gets(nil)
|
184
|
+
output[:err] = stderr.gets(nil)
|
185
|
+
[stdin, stdout, stderr].each{|stream| stream.close }
|
186
|
+
output[:status] = wait_thr.value
|
187
|
+
end
|
188
|
+
output
|
189
|
+
end
|
190
|
+
|
191
|
+
def path_to_tp_config
|
192
|
+
File.join(self.class.app_dir, 'bin', 'tp-config')
|
193
|
+
end
|
194
|
+
|
195
|
+
def tp_config(*args)
|
196
|
+
call_script(path_to_tp_config, *args)
|
197
|
+
end
|
198
|
+
|
199
|
+
def tp_config_with_input(args, input)
|
200
|
+
output = {}
|
201
|
+
Open3.popen3(path_to_tp_config, *args) do |stdin, stdout, stderr, wait_thr|
|
202
|
+
input.each do |sending|
|
203
|
+
stdin.puts(sending)
|
204
|
+
end
|
205
|
+
output[:out] = stdout.gets(nil)
|
206
|
+
output[:err] = stderr.gets(nil)
|
207
|
+
[stdin, stdout, stderr].each{|stream| stream.close }
|
208
|
+
output[:status] = wait_thr.value
|
209
|
+
end #Open3.popen3...
|
210
|
+
output
|
211
|
+
end
|
212
|
+
|
213
|
+
def fixture_project_dir(name)
|
214
|
+
File.join(fixtures_dir, name)
|
215
|
+
end
|
216
|
+
|
217
|
+
def make_fixture_project_dir(name)
|
218
|
+
dir = fixture_project_dir(name)
|
219
|
+
if File.exists? dir
|
220
|
+
raise Error::Test, "Fixture project already exists for #{name} at #{dir}"
|
221
|
+
end
|
222
|
+
::Dir.mkdir(dir)
|
223
|
+
dir
|
224
|
+
end
|
225
|
+
|
226
|
+
def remove_fixture_project_dir(name)
|
227
|
+
FileUtils.remove_entry_secure(fixture_project_dir(name), :secure => true)
|
228
|
+
end
|
229
|
+
|
230
|
+
def with_fixtures_in_temp_tp_dir(dir, fixture_prefix)
|
231
|
+
fixtures = Dir.entries(fixtures_dir).select{|entry| entry.include?(fixture_prefix) && entry.index(fixture_prefix) == 0 }.select{|entry| File.file?(File.join(fixtures_dir, entry)) }
|
232
|
+
fixtures.map!{|fixture| fixture[fixture_prefix.size .. -1] }
|
233
|
+
fixtures.each do |fixture|
|
234
|
+
project_path = File.join(temp_tp_dir_project_dir(dir), 'data', fixture)
|
235
|
+
fixture_path = File.join(fixtures_dir, [fixture_prefix, fixture].join )
|
236
|
+
yield(fixture_path, project_path)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def copy_fixtures_to_temp_tp_dir(dir, fixture_prefix)
|
241
|
+
with_fixtures_in_temp_tp_dir(dir, fixture_prefix) do |fixture_path, project_path|
|
242
|
+
if File.exists? project_path
|
243
|
+
FileUtils.mv(project_path, File.join(File.dirname(project_path), "orig_#{File.basename(project_path)}"))
|
244
|
+
end
|
245
|
+
FileUtils.cp(fixture_path, project_path)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def rm_fixtures_from_temp_tp_dir(dir, fixture_prefix)
|
250
|
+
with_fixtures_in_temp_tp_dir(dir, fixture_prefix) do |fixture_path, project_path|
|
251
|
+
FileUtils.rm(project_path)
|
252
|
+
path_to_orig = File.join(File.dirname(project_path), "orig_#{File.basename(project_path)}")
|
253
|
+
if File.exists?(path_to_orig)
|
254
|
+
FileUtils.mv(path_to_orig, project_path)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def assert_has_transcript(dir, transcript_file='transcript.html')
|
260
|
+
transcript_path = File.join(temp_tp_dir_project_dir(dir), transcript_file)
|
261
|
+
assert(File.exists?(transcript_path))
|
262
|
+
assert(not((transcript = IO.read(transcript_path)).empty?))
|
263
|
+
transcript
|
264
|
+
end
|
265
|
+
|
266
|
+
def assert_has_partial_transcript(dir)
|
267
|
+
assert_has_transcript(dir, 'transcript_in_progress.html')
|
268
|
+
end
|
269
|
+
|
270
|
+
def assert_assignment_csv_has_transcription_count(count, project, which_csv='assignment.csv')
|
271
|
+
assert_equal(count, project.local.file('data', which_csv).as(:csv).reject{|assignment| assignment['transcript'].to_s.empty?}.size)
|
272
|
+
end
|
273
|
+
|
274
|
+
def assert_html_has_audio_count(count, html)
|
275
|
+
assert_equal(count, noko(html).css('audio').size)
|
276
|
+
end
|
277
|
+
|
278
|
+
def assert_all_assets_have_upload_status(assignment_csv, types, status)
|
279
|
+
types.each do |type|
|
280
|
+
recorded_uploads = assignment_csv.map{|assignment| assignment["#{type}_uploaded"] }
|
281
|
+
refute_empty(recorded_uploads)
|
282
|
+
assert_equal(recorded_uploads.count, recorded_uploads.select{|uploaded| uploaded == status }.count)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def assert_shell_error_match(regex)
|
287
|
+
exception = assert_raise(Typingpool::Error::Shell) do
|
288
|
+
yield
|
289
|
+
end
|
290
|
+
assert_match(exception.message, regex)
|
291
|
+
end
|
292
|
+
|
293
|
+
def assert_script_abort_match(args, regex)
|
294
|
+
in_temp_tp_dir do |dir|
|
295
|
+
assert_shell_error_match(regex) do
|
296
|
+
yield([*args, '--config', config_path(dir)])
|
297
|
+
end
|
298
|
+
end #in_temp_tp_dir do...
|
299
|
+
end
|
300
|
+
|
301
|
+
def noko(html)
|
302
|
+
Nokogiri::HTML(html)
|
303
|
+
end
|
304
|
+
|
305
|
+
def vcr_dir
|
306
|
+
File.join(fixtures_dir, 'vcr')
|
307
|
+
end
|
308
|
+
end #Script
|
309
|
+
end #Test
|
310
|
+
end #Typingpool
|
data/lib/typingpool/test.rb
CHANGED
@@ -108,311 +108,6 @@ module Typingpool
|
|
108
108
|
Typingpool::Utility.fetch_url(*args)
|
109
109
|
end
|
110
110
|
|
111
|
-
|
112
|
-
require 'typingpool'
|
113
|
-
require 'yaml'
|
114
|
-
require 'open3'
|
115
|
-
|
116
|
-
|
117
|
-
def audio_files(subdir='mp3')
|
118
|
-
dir = File.join(audio_dir, subdir)
|
119
|
-
Dir.entries(dir).reject{|entry| entry.match(/^\./) }.map{|entry| File.join(dir, entry)}.select{|path| File.file?(path) }
|
120
|
-
end
|
121
|
-
|
122
|
-
def config_path(dir)
|
123
|
-
::File.join(dir, project_default[:config_filename])
|
124
|
-
end
|
125
|
-
|
126
|
-
def config_from_dir(dir)
|
127
|
-
Config.file(config_path(dir))
|
128
|
-
end
|
129
|
-
|
130
|
-
|
131
|
-
def setup_amazon(dir)
|
132
|
-
Amazon.setup(:sandbox => true, :config => config_from_dir(dir))
|
133
|
-
end
|
134
|
-
|
135
|
-
|
136
|
-
def in_temp_tp_dir
|
137
|
-
::Dir.mktmpdir('typingpool_') do |dir|
|
138
|
-
setup_temp_tp_dir(dir)
|
139
|
-
yield(dir)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def setup_temp_tp_dir(dir)
|
144
|
-
make_temp_tp_dir_config(dir)
|
145
|
-
Dir.mkdir(File.join(dir, 'projects'))
|
146
|
-
end
|
147
|
-
|
148
|
-
def setup_s3_config(dir, config=config_from_dir(dir), filename='.config_s3')
|
149
|
-
return unless s3_credentials?(config)
|
150
|
-
config.to_hash.delete('sftp')
|
151
|
-
write_config(config, dir, filename)
|
152
|
-
end
|
153
|
-
|
154
|
-
def setup_s3_config_with_bad_password(dir, config=config_from_dir(dir))
|
155
|
-
bad_password = 'f'
|
156
|
-
refute_equal(config.to_hash['amazon']['secret'], bad_password)
|
157
|
-
config.to_hash['amazon']['secret'] = bad_password
|
158
|
-
setup_s3_config(dir, config, '.config_s3_bad')
|
159
|
-
end
|
160
|
-
|
161
|
-
def make_temp_tp_dir_config(dir, config=self.config)
|
162
|
-
config.transcripts = File.join(dir, 'projects')
|
163
|
-
config.cache = File.join(dir, '.cache')
|
164
|
-
config['assign']['reward'] = '0.02'
|
165
|
-
config.assign.to_hash.delete('qualify')
|
166
|
-
write_config(config, dir, project_default[:config_filename])
|
167
|
-
end
|
168
|
-
|
169
|
-
def write_config(config, dir, filename=project_default[:config_filename])
|
170
|
-
path = ::File.join(dir, filename)
|
171
|
-
::File.open(path, 'w') do |out|
|
172
|
-
out << YAML.dump(config.to_hash)
|
173
|
-
end
|
174
|
-
path
|
175
|
-
end
|
176
|
-
|
177
|
-
def temp_tp_dir_project_dir(temp_tp_dir)
|
178
|
-
::File.join(temp_tp_dir, 'projects', project_default[:title])
|
179
|
-
end
|
180
|
-
|
181
|
-
def temp_tp_dir_project(dir, config=config_from_dir(dir))
|
182
|
-
Project.new(project_default[:title], config)
|
183
|
-
end
|
184
|
-
|
185
|
-
def call_script(*args)
|
186
|
-
Utility.system_quietly(*args)
|
187
|
-
end
|
188
|
-
|
189
|
-
def path_to_tp_make
|
190
|
-
::File.join(self.class.app_dir, 'bin', 'tp-make')
|
191
|
-
end
|
192
|
-
|
193
|
-
def call_tp_make(*args)
|
194
|
-
call_script(path_to_tp_make, *args)
|
195
|
-
end
|
196
|
-
|
197
|
-
def tp_make(in_dir, config=config_path(in_dir), audio_subdir='mp3')
|
198
|
-
call_tp_make(
|
199
|
-
'--config', config,
|
200
|
-
'--chunks', project_default[:chunks],
|
201
|
-
*[:title, :subtitle].map{|param| ["--#{param}", project_default[param]] }.flatten,
|
202
|
-
*[:voice, :unusual].map{|param| project_default[param].map{|value| ["--#{param}", value] } }.flatten,
|
203
|
-
*audio_files(audio_subdir).map{|path| ['--file', path]}.flatten
|
204
|
-
)
|
205
|
-
end
|
206
|
-
|
207
|
-
def path_to_tp_finish
|
208
|
-
::File.join(self.class.app_dir, 'bin', 'tp-finish')
|
209
|
-
end
|
210
|
-
|
211
|
-
def call_tp_finish(*args)
|
212
|
-
call_script(path_to_tp_finish, *args)
|
213
|
-
end
|
214
|
-
|
215
|
-
def tp_finish(dir, config_path=self.config_path(dir))
|
216
|
-
tp_finish_inside_sandbox(dir, config_path)
|
217
|
-
tp_finish_outside_sandbox(dir, config_path)
|
218
|
-
end
|
219
|
-
|
220
|
-
|
221
|
-
def tp_finish_inside_sandbox(dir, config_path=self.config_path(dir))
|
222
|
-
tp_finish_outside_sandbox(dir, config_path, '--sandbox')
|
223
|
-
end
|
224
|
-
|
225
|
-
def tp_finish_outside_sandbox(dir, config_path=self.config_path(dir), *args)
|
226
|
-
call_tp_finish(
|
227
|
-
project_default[:title],
|
228
|
-
'--config', config_path,
|
229
|
-
*args
|
230
|
-
)
|
231
|
-
end
|
232
|
-
|
233
|
-
def path_to_tp_assign
|
234
|
-
File.join(self.class.app_dir, 'bin', 'tp-assign')
|
235
|
-
end
|
236
|
-
|
237
|
-
def call_tp_assign(*args)
|
238
|
-
call_script(path_to_tp_assign, '--sandbox', *args)
|
239
|
-
end
|
240
|
-
|
241
|
-
def assign_default
|
242
|
-
Hash[
|
243
|
-
:template => 'interview/phone',
|
244
|
-
:deadline => '5h',
|
245
|
-
:lifetime => '10h',
|
246
|
-
:approval => '10h',
|
247
|
-
:qualify => ['approval_rate >= 90', 'hits_approved > 10'],
|
248
|
-
:keyword => ['test', 'mp3', 'typingpooltest']
|
249
|
-
]
|
250
|
-
end
|
251
|
-
|
252
|
-
def tp_assign(dir, config_path=config_path(dir))
|
253
|
-
call_tp_assign(
|
254
|
-
project_default[:title],
|
255
|
-
assign_default[:template],
|
256
|
-
'--config', config_path,
|
257
|
-
*[:deadline, :lifetime, :approval].map{|param| ["--#{param}", assign_default[param]] }.flatten,
|
258
|
-
*[:qualify, :keyword].map{|param| assign_default[param].map{|value| ["--#{param}", value] } }.flatten
|
259
|
-
)
|
260
|
-
end
|
261
|
-
|
262
|
-
def path_to_tp_collect
|
263
|
-
File.join(self.class.app_dir, 'bin', 'tp-collect')
|
264
|
-
end
|
265
|
-
|
266
|
-
def call_tp_collect(fixture_path, *args)
|
267
|
-
call_script(path_to_tp_collect, '--sandbox', '--fixture', fixture_path, *args)
|
268
|
-
end
|
269
|
-
|
270
|
-
def tp_collect_with_fixture(dir, fixture_path)
|
271
|
-
call_tp_collect(
|
272
|
-
fixture_path,
|
273
|
-
'--config', config_path(dir)
|
274
|
-
)
|
275
|
-
end
|
276
|
-
|
277
|
-
|
278
|
-
def path_to_tp_review
|
279
|
-
File.join(self.class.app_dir, 'bin', 'tp-review')
|
280
|
-
end
|
281
|
-
|
282
|
-
def tp_review_with_fixture(dir, fixture_path, choices)
|
283
|
-
output = {}
|
284
|
-
Open3.popen3(path_to_tp_review, '--sandbox', '--fixture', fixture_path, '--config', config_path(dir), project_default[:title]) do |stdin, stdout, stderr, wait_thr|
|
285
|
-
choices.each do |choice|
|
286
|
-
stdin.puts(choice)
|
287
|
-
if choice.strip.match(/^r/i)
|
288
|
-
stdin.puts("No reason - this is a test")
|
289
|
-
end
|
290
|
-
end
|
291
|
-
output[:out] = stdout.gets(nil)
|
292
|
-
output[:err] = stderr.gets(nil)
|
293
|
-
[stdin, stdout, stderr].each{|stream| stream.close }
|
294
|
-
output[:status] = wait_thr.value
|
295
|
-
end
|
296
|
-
output
|
297
|
-
end
|
298
|
-
|
299
|
-
def path_to_tp_config
|
300
|
-
File.join(self.class.app_dir, 'bin', 'tp-config')
|
301
|
-
end
|
302
|
-
|
303
|
-
def tp_config(*args)
|
304
|
-
call_script(path_to_tp_config, *args)
|
305
|
-
end
|
306
|
-
|
307
|
-
def tp_config_with_input(args, input)
|
308
|
-
output = {}
|
309
|
-
Open3.popen3(path_to_tp_config, *args) do |stdin, stdout, stderr, wait_thr|
|
310
|
-
input.each do |sending|
|
311
|
-
stdin.puts(sending)
|
312
|
-
end
|
313
|
-
output[:out] = stdout.gets(nil)
|
314
|
-
output[:err] = stderr.gets(nil)
|
315
|
-
[stdin, stdout, stderr].each{|stream| stream.close }
|
316
|
-
output[:status] = wait_thr.value
|
317
|
-
end #Open3.popen3...
|
318
|
-
output
|
319
|
-
end
|
320
|
-
|
321
|
-
def fixture_project_dir(name)
|
322
|
-
File.join(fixtures_dir, name)
|
323
|
-
end
|
324
|
-
|
325
|
-
def make_fixture_project_dir(name)
|
326
|
-
dir = fixture_project_dir(name)
|
327
|
-
if File.exists? dir
|
328
|
-
raise Error::Test, "Fixture project already exists for #{name} at #{dir}"
|
329
|
-
end
|
330
|
-
::Dir.mkdir(dir)
|
331
|
-
dir
|
332
|
-
end
|
333
|
-
|
334
|
-
def remove_fixture_project_dir(name)
|
335
|
-
FileUtils.remove_entry_secure(fixture_project_dir(name), :secure => true)
|
336
|
-
end
|
337
|
-
|
338
|
-
def with_fixtures_in_temp_tp_dir(dir, fixture_prefix)
|
339
|
-
fixtures = Dir.entries(fixtures_dir).select{|entry| entry.include?(fixture_prefix) && entry.index(fixture_prefix) == 0 }.select{|entry| File.file?(File.join(fixtures_dir, entry)) }
|
340
|
-
fixtures.map!{|fixture| fixture[fixture_prefix.size .. -1] }
|
341
|
-
fixtures.each do |fixture|
|
342
|
-
project_path = File.join(temp_tp_dir_project_dir(dir), 'data', fixture)
|
343
|
-
fixture_path = File.join(fixtures_dir, [fixture_prefix, fixture].join )
|
344
|
-
yield(fixture_path, project_path)
|
345
|
-
end
|
346
|
-
end
|
347
|
-
|
348
|
-
def copy_fixtures_to_temp_tp_dir(dir, fixture_prefix)
|
349
|
-
with_fixtures_in_temp_tp_dir(dir, fixture_prefix) do |fixture_path, project_path|
|
350
|
-
if File.exists? project_path
|
351
|
-
FileUtils.mv(project_path, File.join(File.dirname(project_path), "orig_#{File.basename(project_path)}"))
|
352
|
-
end
|
353
|
-
FileUtils.cp(fixture_path, project_path)
|
354
|
-
end
|
355
|
-
end
|
356
|
-
|
357
|
-
def rm_fixtures_from_temp_tp_dir(dir, fixture_prefix)
|
358
|
-
with_fixtures_in_temp_tp_dir(dir, fixture_prefix) do |fixture_path, project_path|
|
359
|
-
FileUtils.rm(project_path)
|
360
|
-
path_to_orig = File.join(File.dirname(project_path), "orig_#{File.basename(project_path)}")
|
361
|
-
if File.exists?(path_to_orig)
|
362
|
-
FileUtils.mv(path_to_orig, project_path)
|
363
|
-
end
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
def assert_has_transcript(dir, transcript_file='transcript.html')
|
368
|
-
transcript_path = File.join(temp_tp_dir_project_dir(dir), transcript_file)
|
369
|
-
assert(File.exists?(transcript_path))
|
370
|
-
assert(not((transcript = IO.read(transcript_path)).empty?))
|
371
|
-
transcript
|
372
|
-
end
|
373
|
-
|
374
|
-
def assert_has_partial_transcript(dir)
|
375
|
-
assert_has_transcript(dir, 'transcript_in_progress.html')
|
376
|
-
end
|
377
|
-
|
378
|
-
def assert_assignment_csv_has_transcription_count(count, project, which_csv='assignment.csv')
|
379
|
-
assert_equal(count, project.local.file('data', which_csv).as(:csv).reject{|assignment| assignment['transcript'].to_s.empty?}.size)
|
380
|
-
end
|
381
|
-
|
382
|
-
def assert_html_has_audio_count(count, html)
|
383
|
-
assert_equal(count, noko(html).css('audio').size)
|
384
|
-
end
|
385
|
-
|
386
|
-
def assert_all_assets_have_upload_status(assignment_csv, types, status)
|
387
|
-
types.each do |type|
|
388
|
-
recorded_uploads = assignment_csv.map{|assignment| assignment["#{type}_uploaded"] }
|
389
|
-
refute_empty(recorded_uploads)
|
390
|
-
assert_equal(recorded_uploads.count, recorded_uploads.select{|uploaded| uploaded == status }.count)
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
def assert_shell_error_match(regex)
|
395
|
-
exception = assert_raise(Typingpool::Error::Shell) do
|
396
|
-
yield
|
397
|
-
end
|
398
|
-
assert_match(exception.message, regex)
|
399
|
-
end
|
400
|
-
|
401
|
-
def assert_script_abort_match(args, regex)
|
402
|
-
in_temp_tp_dir do |dir|
|
403
|
-
assert_shell_error_match(regex) do
|
404
|
-
yield([*args, '--config', config_path(dir)])
|
405
|
-
end
|
406
|
-
end #in_temp_tp_dir do...
|
407
|
-
end
|
408
|
-
|
409
|
-
def noko(html)
|
410
|
-
Nokogiri::HTML(html)
|
411
|
-
end
|
412
|
-
|
413
|
-
def vcr_dir
|
414
|
-
File.join(fixtures_dir, 'vcr')
|
415
|
-
end
|
416
|
-
end #Script
|
111
|
+
require 'typingpool/test/script'
|
417
112
|
end #Test
|
418
113
|
end #Typingpool
|