quorum 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +42 -48
- data/HISTORY.md +11 -0
- data/app/assets/javascripts/quorum/quorum.js +8 -5
- data/db/migrate/20120807202555_add_gaps_to_blast_reports.rb +8 -0
- data/lib/generators/templates/blast.rb +76 -40
- data/lib/quorum/version.rb +1 -1
- data/quorum.gemspec +6 -7
- data/spec/data/fake_seq.txt +2 -0
- data/spec/data/nucl_prot_seqs.txt +15 -0
- data/spec/data/tmp/test.tgz +0 -0
- data/spec/dummy/config/initializers/quorum_initializer.rb +1 -1
- data/spec/dummy/config/quorum_settings.yml +5 -9
- data/spec/dummy/db/schema.rb +23 -19
- data/spec/dummy/quorum/bin/fetch +3 -3
- data/spec/dummy/quorum/bin/search +8 -8
- data/spec/dummy/quorum/blastdb/test/contigs.fa +13 -0
- data/spec/dummy/quorum/blastdb/test/peptides.fa +2 -0
- data/spec/dummy/quorum/blastdb/test.nhd +1 -0
- data/spec/dummy/quorum/blastdb/test.nhi +0 -0
- data/spec/dummy/quorum/blastdb/test.nhr +0 -0
- data/spec/dummy/quorum/blastdb/test.nin +0 -0
- data/spec/dummy/quorum/blastdb/test.nog +0 -0
- data/spec/dummy/quorum/blastdb/test.nsd +1 -0
- data/spec/dummy/quorum/blastdb/test.nsi +0 -0
- data/spec/dummy/quorum/blastdb/test.nsq +0 -0
- data/spec/dummy/quorum/blastdb/test.phd +1 -0
- data/spec/dummy/quorum/blastdb/test.phi +0 -0
- data/spec/dummy/quorum/blastdb/test.phr +0 -0
- data/spec/dummy/quorum/blastdb/test.pin +0 -0
- data/spec/dummy/quorum/blastdb/test.pog +0 -0
- data/spec/dummy/quorum/blastdb/test.psd +1 -0
- data/spec/dummy/quorum/blastdb/test.psi +0 -0
- data/spec/dummy/quorum/blastdb/test.psq +0 -0
- data/spec/dummy/quorum/lib/fetch_tools/blast_db.rb +6 -6
- data/spec/dummy/quorum/lib/logger.rb +4 -4
- data/spec/dummy/quorum/lib/search_tools/blast.rb +76 -40
- data/spec/dummy/quorum/lib/trollop.rb +4 -4
- data/spec/javascripts/fixtures/formatted_sequence.html +1 -1
- data/spec/javascripts/quorum_spec.js +8 -6
- data/spec/requests/jobs_spec.rb +13 -3
- data/spec/spec_helper.rb +0 -4
- data/spec/templates/blast_spec.rb +53 -3
- metadata +17 -31
@@ -33,8 +33,8 @@ Options:
|
|
33
33
|
HEAD
|
34
34
|
|
35
35
|
# Search tool
|
36
|
-
opt :search_tool, "Search tool to execute. Available tools: " <<
|
37
|
-
"#{SEARCH_TOOLS.keys.join(', ')}", :type => :string,
|
36
|
+
opt :search_tool, "Search tool to execute. Available tools: " <<
|
37
|
+
"#{SEARCH_TOOLS.keys.join(', ')}", :type => :string,
|
38
38
|
:required => true, :short => "-s"
|
39
39
|
|
40
40
|
# General settings
|
@@ -48,19 +48,19 @@ Options:
|
|
48
48
|
:short => "-i"
|
49
49
|
opt :database, "Database name", :type => :string, :required => true,
|
50
50
|
:short => "-d"
|
51
|
-
opt :database_adapter, "ActiveRecord database adapter",
|
51
|
+
opt :database_adapter, "ActiveRecord database adapter",
|
52
52
|
:type => :string, :required => true, :short => "-a"
|
53
|
-
opt :database_host, "Database host", :type => :string,
|
53
|
+
opt :database_host, "Database host", :type => :string,
|
54
54
|
:required => true, :short => "-k"
|
55
|
-
opt :database_user, "Database username", :type => :string,
|
55
|
+
opt :database_user, "Database username", :type => :string,
|
56
56
|
:required => true, :short => "-u"
|
57
57
|
opt :database_password, "Database password", :type => :string,
|
58
58
|
:required => true, :short => "-p"
|
59
|
-
|
59
|
+
|
60
60
|
# Global settings
|
61
61
|
opt :search_database, "Path to search tool database", :type => :string,
|
62
62
|
:short => "-b"
|
63
|
-
opt :threads, "Number of threads to spawn for search tool",
|
63
|
+
opt :threads, "Number of threads to spawn for search tool",
|
64
64
|
:type => :int, :short => "-t"
|
65
65
|
end
|
66
66
|
|
@@ -136,6 +136,6 @@ Options:
|
|
136
136
|
end
|
137
137
|
|
138
138
|
if __FILE__ == $0
|
139
|
-
Quorum::Search.new
|
139
|
+
Quorum::Search.new
|
140
140
|
end
|
141
141
|
|
@@ -1,2 +1,15 @@
|
|
1
1
|
>TOG900080
|
2
2
|
TGATAGGATAATTCTAGACAAAACATTAGCCGATCAAGTGTCATCATGGAAAAGCAGCAGGGGCCTTAGTGATACAGTGGTGACTGATCATGCTTGTTCTGGGGAAACATGCTCGTACTACGCAATTGGAGATGTATTTATTTGTGAAAAGACTGGACAAGTTCATGTTTGTGACGAAACATGTAGGGAAGTAGTAATGGATCCCACCAACGAGCTTTTGGTCTGTACAATATCTGGCCACTGTTTTGACAGATTGCTATCACCTGCTGAAATGGAGCCTGATGCTGAGCAGCAGCAAGGTGGTGCGGCAGATGAGGCAGAACCGTTTATGGGATCTGGCCGTTTTGCACGGGCTTATTTGCTGGGATACAATTGTGCTGATGAAAAGGAGCTTGAAGCTACTTTGAGGTTTTGCTGATCCCTATTGGCCCTTCTGGAGTGGATGATCTCATGTCTCAGCATTTACCTATTTAAGATCAAATAAATCGGGTTTCCTTTTCGTGTTTCTCTTGGCATAAGAATGTTTGATTAGATCTAGATTATGAAACTCTAATCGTCTTCTATATTAATAATTGTATGCTTAAATTTATAGTTGAAATTCCATTGATGAATTTTTCTT
|
3
|
+
>reverse translation of ADA84676.1 protein L-isoaspartyl methyltransferase 1 [Cicer arietinum] to a 687 base sequence of most likely codons.
|
4
|
+
atggaacagtattggagcggcagcgcgattaacgaaaacaaaggcatggtggaaaacctg
|
5
|
+
cagcgctatggcattattaaaagcagcaaagtggcggaaaccatggaaaaaattgatcgc
|
6
|
+
ggcctgtttgtgccgaacggcgtgcagccgtatattgatagcccgatgagcattggctat
|
7
|
+
aacgcgaccattagcgcgccgcatatgcatgcgacctgcctgcagctgctggaaaactat
|
8
|
+
ctgcagccgggcatgcatgcgctggatgtgggcagcggcaccggctatctgaccgcgtgc
|
9
|
+
tttgcgatgatggtgggcccgaacggccgcgcggtgggcgtggaacatattccggaactg
|
10
|
+
gtgagctttagcattaacaacattgaaaaaagcgcggcggcgccgcagctgaaagatggc
|
11
|
+
agcctgagcgtgcatgaaggcgatggccgccagggctggccggaatttgcgacctatgat
|
12
|
+
gcgattcatgtgggcgcggcggcgccggaaattccgcagccgctgattgatcagctgaaa
|
13
|
+
accggcggccgcatgattattccggtgggcaacgtgtttcaggatctgaaagtggtggat
|
14
|
+
aaaaacagcgatggcagcattagcattcgcaccgaaaccagcgtgcgctatgtgccgctg
|
15
|
+
accagcaaagaagcgcagctgaaagaa
|
@@ -1,2 +1,4 @@
|
|
1
1
|
>ADA84676.1 protein L-isoaspartyl methyltransferase 1 [Cicer arietinum]
|
2
2
|
MEQYWSGSAINENKGMVENLQRYGIIKSSKVAETMEKIDRGLFVPNGVQPYIDSPMSIGYNATISAPHMHATCLQLLENYLQPGMHALDVGSGTGYLTACFAMMVGPNGRAVGVEHIPELVSFSINNIEKSAAAPQLKDGSLSVHEGDGRQGWPEFATYDAIHVGAAAPEIPQPLIDQLKTGGRMIIPVGNVFQDLKVVDKNSDGSISIRTETSVRYVPLTSKEAQLKE
|
3
|
+
>VIRT10447
|
4
|
+
TVLPHLPHHLAAAQHQAPFQQVIAICQNSGQILYRPKARWWDPLLLPYMFRHKHELVQSFHK
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -77,10 +77,10 @@ module Quorum
|
|
77
77
|
#
|
78
78
|
# Execute the blastdbcmd(s) and return the matching sequence.
|
79
79
|
#
|
80
|
-
# To make Blast execute as quickly as possible, each selected
|
81
|
-
# algorithm blasts against all supplied databases at once.
|
82
|
-
#
|
83
|
-
# See quorum/lib/search_tools/blast.rb for more information.
|
80
|
+
# To make Blast execute as quickly as possible, each selected
|
81
|
+
# algorithm blasts against all supplied databases at once.
|
82
|
+
#
|
83
|
+
# See quorum/lib/search_tools/blast.rb for more information.
|
84
84
|
#
|
85
85
|
# One consequence of this is not knowing which Blast database to use
|
86
86
|
# when retrieving a hit sequence via blastdbcmd.
|
@@ -93,10 +93,10 @@ module Quorum
|
|
93
93
|
def execute_blast_db_cmd
|
94
94
|
generate_blast_db_cmds
|
95
95
|
@logger.log("NCBI Blast", @cmds.join('; '))
|
96
|
-
|
96
|
+
|
97
97
|
@seqs = ""
|
98
98
|
@cmds.each { |c| @seqs << `#{c} 2> /dev/null` }
|
99
|
-
|
99
|
+
|
100
100
|
seq = parse_and_send_results
|
101
101
|
$stdout.print seq
|
102
102
|
end
|
@@ -29,13 +29,13 @@ module Quorum
|
|
29
29
|
# Removes instance files.
|
30
30
|
#
|
31
31
|
def remove_files(files)
|
32
|
-
|
33
|
-
|
34
|
-
else
|
35
|
-
log(
|
32
|
+
if Dir.glob(files).empty?
|
33
|
+
log(
|
36
34
|
"remove_files",
|
37
35
|
"Unable to remove #{files}"
|
38
36
|
)
|
37
|
+
else
|
38
|
+
`rm #{files}`
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -126,6 +126,9 @@ module Quorum
|
|
126
126
|
Digest::MD5.hexdigest(sequence).to_s + "-" + Time.now.to_f.to_s
|
127
127
|
end
|
128
128
|
|
129
|
+
#
|
130
|
+
# Blastn command
|
131
|
+
#
|
129
132
|
def generate_blastn_cmd
|
130
133
|
blastn = "blastn " <<
|
131
134
|
"-db \"#{@db}\" " <<
|
@@ -145,6 +148,9 @@ module Quorum
|
|
145
148
|
blastn
|
146
149
|
end
|
147
150
|
|
151
|
+
#
|
152
|
+
# Blastx command
|
153
|
+
#
|
148
154
|
def generate_blastx_cmd
|
149
155
|
blastx = "blastx " <<
|
150
156
|
"-db \"#{@db}\" " <<
|
@@ -164,6 +170,9 @@ module Quorum
|
|
164
170
|
blastx
|
165
171
|
end
|
166
172
|
|
173
|
+
#
|
174
|
+
# Tblastn command
|
175
|
+
#
|
167
176
|
def generate_tblastn_cmd
|
168
177
|
tblastn = "tblastn " <<
|
169
178
|
"-db \"#{@db}\" " <<
|
@@ -185,6 +194,9 @@ module Quorum
|
|
185
194
|
tblastn
|
186
195
|
end
|
187
196
|
|
197
|
+
#
|
198
|
+
# Blastp command
|
199
|
+
#
|
188
200
|
def generate_blastp_cmd
|
189
201
|
blastp = "blastp " <<
|
190
202
|
"-db \"#{@db}\" " <<
|
@@ -256,12 +268,65 @@ module Quorum
|
|
256
268
|
end
|
257
269
|
|
258
270
|
#
|
259
|
-
#
|
260
|
-
#
|
271
|
+
# Save Blast Job Report
|
272
|
+
#
|
273
|
+
# Hsps are only reported if a query hit against the Blast db.
|
274
|
+
# Only save the @data if bit_score exists and it's > the user
|
275
|
+
# defined minimum score.
|
276
|
+
#
|
277
|
+
# Set the attribute results to true for downstream processes.
|
278
|
+
#
|
279
|
+
def save_hsp_results
|
280
|
+
if @data[:bit_score] && (@data[:bit_score].to_i > @min_score.to_i)
|
281
|
+
@data[:results] = true
|
282
|
+
@data["#{@algorithm}_job_id".to_sym] = @job.method(@job_association).call.job_id
|
283
|
+
|
284
|
+
job_report = @job.method(@job_report_association).call.build(@data)
|
285
|
+
|
286
|
+
unless job_report.save!
|
287
|
+
@logger.log(
|
288
|
+
"ActiveRecord",
|
289
|
+
"Unable to save #{@algorithm} results to database.",
|
290
|
+
1,
|
291
|
+
@tmp_files
|
292
|
+
)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
#
|
298
|
+
# Save empty Blast Job Report
|
299
|
+
#
|
300
|
+
# Set the attribute results to false for downstream processes.
|
301
|
+
#
|
302
|
+
def save_empty_results
|
303
|
+
job_report = @job.method(@job_report_association).call.build(
|
304
|
+
"#{@algorithm}_job_id" => @job.method(@job_association).call.job_id,
|
305
|
+
"results" => false
|
306
|
+
)
|
307
|
+
unless job_report.save!
|
308
|
+
@logger.log(
|
309
|
+
"ActiveRecord",
|
310
|
+
"Unable to save #{@algorithm} results to database.",
|
311
|
+
1,
|
312
|
+
@tmp_files
|
313
|
+
)
|
314
|
+
end
|
315
|
+
@logger.log(
|
316
|
+
"NCBI Blast",
|
317
|
+
"#{@algorithm} report empty.",
|
318
|
+
0,
|
319
|
+
@tmp_files
|
320
|
+
)
|
321
|
+
end
|
322
|
+
|
323
|
+
#
|
324
|
+
# Parse and save Blast results.
|
325
|
+
#
|
326
|
+
# Parse the Blast XML output and save results.
|
261
327
|
#
|
262
328
|
def parse_and_save_results
|
263
|
-
|
264
|
-
saved = false
|
329
|
+
@results = false # Did the xml contain results?
|
265
330
|
|
266
331
|
if File.size(@out) > 0
|
267
332
|
report = Bio::Blast::XmlIterator.new(@out)
|
@@ -292,28 +357,16 @@ module Quorum
|
|
292
357
|
@data[:hit_frame] = hsp.hit_frame
|
293
358
|
@data[:identity] = hsp.identity
|
294
359
|
@data[:positive] = hsp.positive
|
360
|
+
@data[:gaps] = hsp.gaps
|
295
361
|
@data[:align_len] = hsp.align_len
|
296
362
|
@data[:qseq] = hsp.qseq
|
297
363
|
@data[:hseq] = hsp.hseq
|
298
364
|
@data[:midline] = hsp.midline
|
299
365
|
|
300
|
-
# Hsps are only reported if a query hit against the Blast db.
|
301
|
-
# Only save the @data if bit_score exists.
|
302
366
|
if @data[:bit_score] &&
|
303
367
|
(@data[:bit_score].to_i > @min_score.to_i)
|
304
|
-
@
|
305
|
-
|
306
|
-
saved = true
|
307
|
-
# Build a new report for each Hsp.
|
308
|
-
job_report = @job.method(@job_report_association).call.build(@data)
|
309
|
-
unless job_report.save!
|
310
|
-
@logger.log(
|
311
|
-
"ActiveRecord",
|
312
|
-
"Unable to save #{@algorithm} results to database.",
|
313
|
-
1,
|
314
|
-
@tmp_files
|
315
|
-
)
|
316
|
-
end
|
368
|
+
@results = true
|
369
|
+
save_hsp_results
|
317
370
|
end
|
318
371
|
|
319
372
|
end
|
@@ -321,27 +374,7 @@ module Quorum
|
|
321
374
|
end
|
322
375
|
end
|
323
376
|
|
324
|
-
|
325
|
-
unless saved
|
326
|
-
job_report = @job.method(@job_report_association).call.build(
|
327
|
-
"#{@algorithm}_job_id" => @job.method(@job_association).call.job_id,
|
328
|
-
"results" => false
|
329
|
-
)
|
330
|
-
unless job_report.save!
|
331
|
-
@logger.log(
|
332
|
-
"ActiveRecord",
|
333
|
-
"Unable to save #{@algorithm} results to database.",
|
334
|
-
1,
|
335
|
-
@tmp_files
|
336
|
-
)
|
337
|
-
end
|
338
|
-
@logger.log(
|
339
|
-
"NCBI Blast",
|
340
|
-
"#{@algorithm} report empty.",
|
341
|
-
0,
|
342
|
-
@tmp_files
|
343
|
-
)
|
344
|
-
end
|
377
|
+
save_empty_results unless @results
|
345
378
|
end
|
346
379
|
|
347
380
|
#
|
@@ -388,6 +421,9 @@ module Quorum
|
|
388
421
|
end
|
389
422
|
end
|
390
423
|
|
424
|
+
#
|
425
|
+
# Remove tmp files.
|
426
|
+
#
|
391
427
|
def remove_tmp_files
|
392
428
|
`rm #{@tmp_files}` if @tmp_files
|
393
429
|
end
|
@@ -12,7 +12,7 @@ VERSION = "1.16.2"
|
|
12
12
|
## Thrown by Parser in the event of a commandline error. Not needed if
|
13
13
|
## you're using the Trollop::options entry.
|
14
14
|
class CommandlineError < StandardError; end
|
15
|
-
|
15
|
+
|
16
16
|
## Thrown by Parser if the user passes in '-h' or '--help'. Handled
|
17
17
|
## automatically by Trollop#options.
|
18
18
|
class HelpNeeded < StandardError; end
|
@@ -250,7 +250,7 @@ class Parser
|
|
250
250
|
syms.each { |sym| raise ArgumentError, "unknown option '#{sym}'" unless @specs[sym] }
|
251
251
|
@constraints << [:depends, syms]
|
252
252
|
end
|
253
|
-
|
253
|
+
|
254
254
|
## Marks two (or more!) options as conflicting.
|
255
255
|
def conflicts *syms
|
256
256
|
syms.each { |sym| raise ArgumentError, "unknown option '#{sym}'" unless @specs[sym] }
|
@@ -426,7 +426,7 @@ class Parser
|
|
426
426
|
# call this unless the cursor's at the beginning of a line.
|
427
427
|
|
428
428
|
left = {}
|
429
|
-
@specs.each do |name, spec|
|
429
|
+
@specs.each do |name, spec|
|
430
430
|
left[name] = "--#{spec[:long]}" +
|
431
431
|
(spec[:short] && spec[:short] != :none ? ", -#{spec[:short]}" : "") +
|
432
432
|
case spec[:type]
|
@@ -647,7 +647,7 @@ private
|
|
647
647
|
start = 0
|
648
648
|
ret = []
|
649
649
|
until start > str.length
|
650
|
-
nextt =
|
650
|
+
nextt =
|
651
651
|
if start + width >= str.length
|
652
652
|
str.length
|
653
653
|
else
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<p class='small'>Alignment (Mouse over for positions):</p><span class='small'><pre>
|
1
|
+
<p class='small'>Alignment (Mouse over for positions):</p><span class='small sequence'><pre>
|
2
2
|
qseq <a rel='quorum-tipsy' title=10>E</a><a rel='quorum-tipsy' title=11>L</a><a rel='quorum-tipsy' title=12>V</a><a rel='quorum-tipsy' title=13>I</a><a rel='quorum-tipsy' title=14>S</a>
|
3
3
|
ELVIS
|
4
4
|
hseq <a rel='quorum-tipsy' title=121>E</a><a rel='quorum-tipsy' title=122>L</a><a rel='quorum-tipsy' title=123>V</a><a rel='quorum-tipsy' title=124>I</a><a rel='quorum-tipsy' title=125>S</a>
|
@@ -77,7 +77,7 @@ describe("QUORUM", function() {
|
|
77
77
|
var report = QUORUM.formatSequenceReport(
|
78
78
|
"ACGT", "|| |", "ACCT", 6, 9, 2, 8, "blastn"
|
79
79
|
);
|
80
|
-
expect(report).toEqual("<p class='small'>Alignment (Mouse over for positions):</p><span class='small'><pre>\nqseq <a rel='quorum-tipsy' title=6>A</a><a rel='quorum-tipsy' title=7>C</a><a rel='quorum-tipsy' title=8>G</a><a rel='quorum-tipsy' title=9>T</a>\n || |\nhseq <a rel='quorum-tipsy' title=2>A</a><a rel='quorum-tipsy' title=3>C</a><a rel='quorum-tipsy' title=4>C</a><a rel='quorum-tipsy' title=5>T</a>\n\n</pre></span>");
|
80
|
+
expect(report).toEqual("<p class='small'>Alignment (Mouse over for positions):</p><span class='small sequence'><pre>\nqseq <a rel='quorum-tipsy' title=6>A</a><a rel='quorum-tipsy' title=7>C</a><a rel='quorum-tipsy' title=8>G</a><a rel='quorum-tipsy' title=9>T</a>\n || |\nhseq <a rel='quorum-tipsy' title=2>A</a><a rel='quorum-tipsy' title=3>C</a><a rel='quorum-tipsy' title=4>C</a><a rel='quorum-tipsy' title=5>T</a>\n\n</pre></span>");
|
81
81
|
});
|
82
82
|
|
83
83
|
//
|
@@ -89,7 +89,7 @@ describe("QUORUM", function() {
|
|
89
89
|
var report = QUORUM.formatSequenceReport(
|
90
90
|
"ACGT", "|| |", "ACCT", 6, 9, 2, 8, "blastx"
|
91
91
|
);
|
92
|
-
expect(report).toEqual("<p class='small'>Alignment (Mouse over for positions):</p><span class='small'><pre>\nqseq <a rel='quorum-tipsy' title=6>A</a><a rel='quorum-tipsy' title=9>C</a><a rel='quorum-tipsy' title=12>G</a><a rel='quorum-tipsy' title=15>T</a>\n || |\nhseq <a rel='quorum-tipsy' title=2>A</a><a rel='quorum-tipsy' title=3>C</a><a rel='quorum-tipsy' title=4>C</a><a rel='quorum-tipsy' title=5>T</a>\n\n</pre></span>");
|
92
|
+
expect(report).toEqual("<p class='small'>Alignment (Mouse over for positions):</p><span class='small sequence'><pre>\nqseq <a rel='quorum-tipsy' title=6>A</a><a rel='quorum-tipsy' title=9>C</a><a rel='quorum-tipsy' title=12>G</a><a rel='quorum-tipsy' title=15>T</a>\n || |\nhseq <a rel='quorum-tipsy' title=2>A</a><a rel='quorum-tipsy' title=3>C</a><a rel='quorum-tipsy' title=4>C</a><a rel='quorum-tipsy' title=5>T</a>\n\n</pre></span>");
|
93
93
|
});
|
94
94
|
|
95
95
|
//
|
@@ -101,7 +101,7 @@ describe("QUORUM", function() {
|
|
101
101
|
var report = QUORUM.formatSequenceReport(
|
102
102
|
"ELVIS", "ELVIS", "ELVIS", 10, 14, 121, 136, "tblastn"
|
103
103
|
);
|
104
|
-
expect(report).toEqual("<p class='small'>Alignment (Mouse over for positions):</p><span class='small'><pre>\nqseq <a rel='quorum-tipsy' title=10>E</a><a rel='quorum-tipsy' title=11>L</a><a rel='quorum-tipsy' title=12>V</a><a rel='quorum-tipsy' title=13>I</a><a rel='quorum-tipsy' title=14>S</a>\n ELVIS\nhseq <a rel='quorum-tipsy' title=121>E</a><a rel='quorum-tipsy' title=124>L</a><a rel='quorum-tipsy' title=127>V</a><a rel='quorum-tipsy' title=130>I</a><a rel='quorum-tipsy' title=133>S</a>\n\n</pre></span>");
|
104
|
+
expect(report).toEqual("<p class='small'>Alignment (Mouse over for positions):</p><span class='small sequence'><pre>\nqseq <a rel='quorum-tipsy' title=10>E</a><a rel='quorum-tipsy' title=11>L</a><a rel='quorum-tipsy' title=12>V</a><a rel='quorum-tipsy' title=13>I</a><a rel='quorum-tipsy' title=14>S</a>\n ELVIS\nhseq <a rel='quorum-tipsy' title=121>E</a><a rel='quorum-tipsy' title=124>L</a><a rel='quorum-tipsy' title=127>V</a><a rel='quorum-tipsy' title=130>I</a><a rel='quorum-tipsy' title=133>S</a>\n\n</pre></span>");
|
105
105
|
});
|
106
106
|
|
107
107
|
//
|
@@ -113,16 +113,18 @@ describe("QUORUM", function() {
|
|
113
113
|
var report = QUORUM.formatSequenceReport(
|
114
114
|
"ELVIS", "ELVIS", "ELVIS", 10, 14, 121, 125, "blastp"
|
115
115
|
);
|
116
|
-
expect(report).toEqual("<p class='small'>Alignment (Mouse over for positions):</p><span class='small'><pre>\nqseq <a rel='quorum-tipsy' title=10>E</a><a rel='quorum-tipsy' title=11>L</a><a rel='quorum-tipsy' title=12>V</a><a rel='quorum-tipsy' title=13>I</a><a rel='quorum-tipsy' title=14>S</a>\n ELVIS\nhseq <a rel='quorum-tipsy' title=121>E</a><a rel='quorum-tipsy' title=122>L</a><a rel='quorum-tipsy' title=123>V</a><a rel='quorum-tipsy' title=124>I</a><a rel='quorum-tipsy' title=125>S</a>\n\n</pre></span>");
|
116
|
+
expect(report).toEqual("<p class='small'>Alignment (Mouse over for positions):</p><span class='small sequence'><pre>\nqseq <a rel='quorum-tipsy' title=10>E</a><a rel='quorum-tipsy' title=11>L</a><a rel='quorum-tipsy' title=12>V</a><a rel='quorum-tipsy' title=13>I</a><a rel='quorum-tipsy' title=14>S</a>\n ELVIS\nhseq <a rel='quorum-tipsy' title=121>E</a><a rel='quorum-tipsy' title=122>L</a><a rel='quorum-tipsy' title=123>V</a><a rel='quorum-tipsy' title=124>I</a><a rel='quorum-tipsy' title=125>S</a>\n\n</pre></span>");
|
117
117
|
});
|
118
118
|
|
119
119
|
//
|
120
120
|
// jQuery tipsy plugin should display anchor's title attribute on mouseover
|
121
121
|
// and hide on mouseout.
|
122
122
|
//
|
123
|
-
it("should display title via jquery.tipsy on mouse over hide on mouse out", function() {
|
123
|
+
it("should display title via jquery.tipsy on mouse over and hide on mouse out", function() {
|
124
124
|
loadFixtures('formatted_sequence.html');
|
125
|
-
$('
|
125
|
+
$('.sequence').mouseenter(function() {
|
126
|
+
$(this).find('a[rel=quorum-tipsy]').tipsy({ gravity: 's' });
|
127
|
+
});
|
126
128
|
|
127
129
|
$('a[rel=quorum-tipsy]').trigger('mouseover');
|
128
130
|
expect($('.tipsy')).toBeVisible();
|
data/spec/requests/jobs_spec.rb
CHANGED
@@ -110,10 +110,20 @@ describe "Jobs" do
|
|
110
110
|
page.should have_content("Search Results")
|
111
111
|
|
112
112
|
click_link "Blastx"
|
113
|
-
|
113
|
+
|
114
|
+
# Render modal box.
|
115
|
+
find("#blastx-results").find("td a").click
|
116
|
+
page.should have_content("Quorum Report Details")
|
117
|
+
page.should have_content("qseq")
|
118
|
+
page.should have_content("hseq")
|
114
119
|
|
115
120
|
click_link "Tblastn"
|
116
|
-
|
121
|
+
|
122
|
+
# Render modal box.
|
123
|
+
find("#tblastn-results").find("td a").click
|
124
|
+
page.should have_content("Quorum Report Details")
|
125
|
+
page.should have_content("qseq")
|
126
|
+
page.should have_content("hseq")
|
117
127
|
|
118
128
|
## Interact with the Blast results. ##
|
119
129
|
click_link "Blastn"
|
@@ -125,7 +135,7 @@ describe "Jobs" do
|
|
125
135
|
page.should have_content("hseq")
|
126
136
|
|
127
137
|
# Download sequence
|
128
|
-
find("p.small a#
|
138
|
+
find("p.small a#download_sequence_2").click
|
129
139
|
page.should have_content("Fetching sequence...")
|
130
140
|
page.should have_content("Sequence Downloaded Successfully")
|
131
141
|
|
data/spec/spec_helper.rb
CHANGED
@@ -3,13 +3,9 @@ ENV["RAILS_ENV"] ||= 'test'
|
|
3
3
|
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
4
4
|
require 'rspec/rails'
|
5
5
|
require 'capybara/rspec'
|
6
|
-
require 'factory_girl'
|
7
6
|
require 'database_cleaner'
|
8
7
|
require 'resque_spec'
|
9
8
|
|
10
|
-
FactoryGirl.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
|
11
|
-
FactoryGirl.find_definitions
|
12
|
-
|
13
9
|
ENGINE_RAILS_ROOT = File.expand_path("../../", __FILE__)
|
14
10
|
|
15
11
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require File.expand_path("../../dummy/quorum/lib/search_tools/blast", __FILE__)
|
3
3
|
|
4
4
|
describe "Quorum::SearchTools::Blast" do
|
5
|
-
describe "#execute_blast" do
|
5
|
+
describe "#execute_blast non empty report" do
|
6
6
|
before(:each) do
|
7
7
|
# Set args as though we executed bin/search.
|
8
8
|
@args = {
|
@@ -69,7 +69,7 @@ describe "Quorum::SearchTools::Blast" do
|
|
69
69
|
blast = Quorum::SearchTools::Blast.new(@args)
|
70
70
|
expect {
|
71
71
|
blast.execute_blast
|
72
|
-
}.
|
72
|
+
}.to_not raise_error
|
73
73
|
|
74
74
|
Dir.glob(
|
75
75
|
File.join(@args[:tmp_directory], "*")
|
@@ -86,7 +86,7 @@ describe "Quorum::SearchTools::Blast" do
|
|
86
86
|
blast = Quorum::SearchTools::Blast.new(@args)
|
87
87
|
expect {
|
88
88
|
blast.execute_blast
|
89
|
-
}.
|
89
|
+
}.to_not raise_error
|
90
90
|
|
91
91
|
Dir.glob(
|
92
92
|
File.join(@args[:tmp_directory], "*")
|
@@ -109,6 +109,56 @@ describe "Quorum::SearchTools::Blast" do
|
|
109
109
|
File.join(@args[:tmp_directory], "*")
|
110
110
|
).length.should be == 0
|
111
111
|
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#execute_blast empty report" do
|
115
|
+
before(:each) do
|
116
|
+
# Set args as though we executed bin/search.
|
117
|
+
@args = {
|
118
|
+
:search_tool => "blastn",
|
119
|
+
:id => nil,
|
120
|
+
:log_directory => File.expand_path(
|
121
|
+
"../../dummy/quorum/log", __FILE__
|
122
|
+
),
|
123
|
+
:tmp_directory => File.expand_path(
|
124
|
+
"../../dummy/quorum/tmp", __FILE__
|
125
|
+
),
|
126
|
+
:search_database => File.expand_path(
|
127
|
+
"../../dummy/quorum/blastdb", __FILE__
|
128
|
+
),
|
129
|
+
:threads => 1
|
130
|
+
}
|
131
|
+
|
132
|
+
@job = Quorum::Job.new()
|
133
|
+
|
134
|
+
@job.sequence = File.open(
|
135
|
+
File.expand_path("../../data/fake_seq.txt", __FILE__)
|
136
|
+
).read
|
137
|
+
|
138
|
+
@job.build_blastn_job
|
139
|
+
@job.blastn_job.queue = true
|
140
|
+
@job.blastn_job.blast_dbs = ["test"]
|
141
|
+
end
|
142
|
+
|
143
|
+
it "executes blastn on a given dataset and returns an empty report" do
|
144
|
+
@job.stub(:queue_workers)
|
145
|
+
@job.save!
|
146
|
+
|
147
|
+
@args[:id] = @job.id
|
148
|
+
|
149
|
+
blast = Quorum::SearchTools::Blast.new(@args)
|
150
|
+
expect {
|
151
|
+
blast.execute_blast
|
152
|
+
}.to raise_error
|
153
|
+
|
154
|
+
Dir.glob(
|
155
|
+
File.join(@args[:tmp_directory], "*")
|
156
|
+
).length.should be == 0
|
157
|
+
|
158
|
+
log_file = File.join(@args[:log_directory], "quorum.log")
|
159
|
+
|
160
|
+
`tail -n 3 #{log_file}`.to_s.include?("blastn report empty").should be_true
|
161
|
+
end
|
112
162
|
|
113
163
|
end
|
114
164
|
end
|