genomer-plugin-view 0.0.2
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/.document +5 -0
- data/.gitignore +52 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +9 -0
- data/features/agp/generation.feature +285 -0
- data/features/fasta/contigs.feature +173 -0
- data/features/fasta/single_sequence.feature +144 -0
- data/features/mappings/core.feature +181 -0
- data/features/support/env.rb +13 -0
- data/features/table/cds_entries.feature +304 -0
- data/features/table/core.feature +302 -0
- data/features/table/feature_type.feature +180 -0
- data/genomer-plugin-view.gemspec +34 -0
- data/lib/genomer-plugin-view/agp.rb +62 -0
- data/lib/genomer-plugin-view/fasta.rb +36 -0
- data/lib/genomer-plugin-view/gff_record_helper.rb +61 -0
- data/lib/genomer-plugin-view/mapping.rb +14 -0
- data/lib/genomer-plugin-view/table.rb +56 -0
- data/lib/genomer-plugin-view/version.rb +3 -0
- data/lib/genomer-plugin-view.rb +29 -0
- data/man/genomer-view-agp.ronn +46 -0
- data/man/genomer-view.ronn +153 -0
- data/spec/genomer-view-plugin/agp_spec.rb +79 -0
- data/spec/genomer-view-plugin/fasta_spec.rb +96 -0
- data/spec/genomer-view-plugin/gff_record_helper_spec.rb +244 -0
- data/spec/genomer-view-plugin/mapping_spec.rb +89 -0
- data/spec/genomer-view-plugin/table_spec.rb +279 -0
- data/spec/genomer-view-plugin_spec.rb +103 -0
- data/spec/spec_helper.rb +32 -0
- metadata +192 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'genomer-plugin-view/agp'
|
3
|
+
|
4
|
+
describe GenomerPluginView::Agp do
|
5
|
+
|
6
|
+
def contig(sequence)
|
7
|
+
s = mock!
|
8
|
+
stub(s).entry_type{ :sequence }
|
9
|
+
stub(s).sequence{ sequence }
|
10
|
+
s
|
11
|
+
end
|
12
|
+
|
13
|
+
def unresolved(length)
|
14
|
+
s = mock!
|
15
|
+
stub(s).entry_type{ :unresolved }
|
16
|
+
stub(s).sequence{ 'N' * length }
|
17
|
+
s
|
18
|
+
end
|
19
|
+
|
20
|
+
subject do
|
21
|
+
described_class.new(['agp'],{})
|
22
|
+
end
|
23
|
+
|
24
|
+
before do
|
25
|
+
mock(subject).scaffold do
|
26
|
+
contigs
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "where the scaffold contains a single contig" do
|
31
|
+
|
32
|
+
let (:contigs) do
|
33
|
+
[contig('AATGC')]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return agp output" do
|
37
|
+
subject.run.should == <<-EOS.unindent
|
38
|
+
##agp-version 2.0
|
39
|
+
scaffold 1 5 1 W contig00001 1 5 +
|
40
|
+
EOS
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
context "where the scaffold contains a contig with a gap" do
|
46
|
+
|
47
|
+
let (:contigs) do
|
48
|
+
[contig('AAANNNGGG')]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return agp output" do
|
52
|
+
subject.run.should == <<-EOS.unindent
|
53
|
+
##agp-version 2.0
|
54
|
+
scaffold 1 3 1 W contig00001 1 3 +
|
55
|
+
scaffold 4 6 2 N 3 scaffold yes internal
|
56
|
+
scaffold 7 9 3 W contig00002 1 3 +
|
57
|
+
EOS
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
context "where the scaffold contains an unresolved region" do
|
63
|
+
|
64
|
+
let (:contigs) do
|
65
|
+
[ contig('AAA'), unresolved(3), contig('TTT') ]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return agp output" do
|
69
|
+
subject.run.should == <<-EOS.unindent
|
70
|
+
##agp-version 2.0
|
71
|
+
scaffold 1 3 1 W contig00001 1 3 +
|
72
|
+
scaffold 4 6 2 N 3 scaffold yes specified
|
73
|
+
scaffold 7 9 3 W contig00002 1 3 +
|
74
|
+
EOS
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'genomer-plugin-view/fasta'
|
3
|
+
|
4
|
+
describe GenomerPluginView::Fasta do
|
5
|
+
|
6
|
+
before do
|
7
|
+
mock(subject).scaffold do
|
8
|
+
annotations
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let (:annotations) do
|
13
|
+
[Sequence.new(:sequence => 'AAATGA')]
|
14
|
+
end
|
15
|
+
|
16
|
+
subject do
|
17
|
+
described_class.new(['fasta'],flags)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "with no options" do
|
21
|
+
|
22
|
+
let(:flags){ {} }
|
23
|
+
|
24
|
+
it "should return fasta output" do
|
25
|
+
subject.run.should == ">.\nAAATGA\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "run with the --identifier option" do
|
31
|
+
|
32
|
+
let(:flags){ {:identifier => 'name'} }
|
33
|
+
|
34
|
+
it "should return fasta output with the identifier" do
|
35
|
+
subject.run.should == ">name\nAAATGA\n"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "run with the --organism option" do
|
41
|
+
|
42
|
+
let(:flags){ {:organism => 'name'} }
|
43
|
+
|
44
|
+
it "should return fasta output with the organism modifier" do
|
45
|
+
subject.run.should == ">. [organism=name]\nAAATGA\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "run with the --strain option" do
|
51
|
+
|
52
|
+
let(:flags){ {:strain => 'name'} }
|
53
|
+
|
54
|
+
it "should return fasta output with the strain modifier" do
|
55
|
+
subject.run.should == ">. [strain=name]\nAAATGA\n"
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "run with the identifier and a modifier option" do
|
61
|
+
|
62
|
+
let(:flags){ {:strain => 'isolate', :identifier => 'name'} }
|
63
|
+
|
64
|
+
it "should return fasta output with the strain modifier" do
|
65
|
+
subject.run.should == ">name [strain=isolate]\nAAATGA\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "run with the --contigs option" do
|
71
|
+
|
72
|
+
let(:flags){ {:contigs => true} }
|
73
|
+
|
74
|
+
context "with an ungapped contig scaffold" do
|
75
|
+
|
76
|
+
it "should return fasta output of the contig" do
|
77
|
+
subject.run.should == ">contig00001\nAAATGA\n"
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with a gapped contig scaffold" do
|
83
|
+
|
84
|
+
let(:annotations) do
|
85
|
+
[Sequence.new(:sequence => 'AAANNNNTTT')]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should return fasta output of the contig" do
|
89
|
+
subject.run.should == ">contig00001\nAAA\n>contig00002\nTTT\n"
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'genomer-plugin-view/gff_record_helper'
|
3
|
+
|
4
|
+
describe GenomerPluginView::GffRecordHelper do
|
5
|
+
|
6
|
+
describe "module" do
|
7
|
+
it "should be included in Bio::GFF::GFF3::Record" do
|
8
|
+
Bio::GFF::GFF3::Record.ancestors.should include(described_class)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#negative_strand?" do
|
13
|
+
|
14
|
+
subject do
|
15
|
+
Annotation.new
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return false for a positive strand annotation" do
|
19
|
+
subject.strand('+').to_gff3_record.
|
20
|
+
negative_strand?.should be_false
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return true for a negative strand annotation" do
|
24
|
+
subject.strand('-').to_gff3_record.
|
25
|
+
negative_strand?.should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#to_genbank_table_entry" do
|
31
|
+
|
32
|
+
before(:each) do
|
33
|
+
@attn = Annotation.new(:start => 1, :end => 3, :strand => '+',:feature => 'gene')
|
34
|
+
end
|
35
|
+
|
36
|
+
subject do
|
37
|
+
annotation.to_gff3_record.to_genbank_table_entry
|
38
|
+
end
|
39
|
+
|
40
|
+
context "gene feature on the positive strand" do
|
41
|
+
|
42
|
+
let(:annotation) do
|
43
|
+
@attn
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return a table entry" do
|
47
|
+
subject.should == <<-EOS.unindent
|
48
|
+
1\t3\tgene
|
49
|
+
EOS
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
context "gene feature on the negative strand" do
|
55
|
+
|
56
|
+
let(:annotation) do
|
57
|
+
@attn.strand('-')
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return a table entry" do
|
61
|
+
subject.should == <<-EOS.unindent
|
62
|
+
3\t1\tgene
|
63
|
+
EOS
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
context "gene feature with attributes" do
|
69
|
+
|
70
|
+
let(:annotation) do
|
71
|
+
@attn.feature('gene').attributes('ID' => 'id')
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should return a table entry" do
|
75
|
+
subject.should == <<-EOS.unindent
|
76
|
+
1\t3\tgene
|
77
|
+
\t\t\tlocus_tag\tid
|
78
|
+
EOS
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context "CDS feature on the positive strand" do
|
84
|
+
|
85
|
+
let(:annotation) do
|
86
|
+
@attn.feature('CDS')
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should return a CDS table entry" do
|
90
|
+
subject.should == <<-EOS.unindent
|
91
|
+
1\t3\tCDS
|
92
|
+
EOS
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
context "tRNA feature on the positive strand" do
|
98
|
+
|
99
|
+
let(:annotation) do
|
100
|
+
@attn.feature('tRNA')
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should return a CDS table entry" do
|
104
|
+
subject.should == <<-EOS.unindent
|
105
|
+
1\t3\ttRNA
|
106
|
+
EOS
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
context "tmRNA feature on the positive strand" do
|
112
|
+
|
113
|
+
let(:annotation) do
|
114
|
+
@attn.feature('tmRNA')
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should return a CDS table entry" do
|
118
|
+
subject.should == <<-EOS.unindent
|
119
|
+
1\t3\ttmRNA
|
120
|
+
EOS
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
context "rRNA feature on the positive strand" do
|
126
|
+
|
127
|
+
let(:annotation) do
|
128
|
+
@attn.feature('rRNA')
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should return a CDS table entry" do
|
132
|
+
subject.should == <<-EOS.unindent
|
133
|
+
1\t3\trRNA
|
134
|
+
EOS
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
context "miscRNA feature on the positive strand" do
|
140
|
+
|
141
|
+
let(:annotation) do
|
142
|
+
@attn.feature('miscRNA')
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should return a CDS table entry" do
|
146
|
+
subject.should == <<-EOS.unindent
|
147
|
+
1\t3\tmiscRNA
|
148
|
+
EOS
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "#table_attributes" do
|
156
|
+
|
157
|
+
before(:each) do
|
158
|
+
@attn = Annotation.new(:start => 1, :end => 3, :strand => '+', :feature => 'gene')
|
159
|
+
end
|
160
|
+
|
161
|
+
subject do
|
162
|
+
annotation.to_gff3_record.table_attributes
|
163
|
+
end
|
164
|
+
|
165
|
+
context "for an unknown feature type" do
|
166
|
+
|
167
|
+
let(:annotation) do
|
168
|
+
@attn.feature('unknown')
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should raise an error" do
|
172
|
+
lambda{ subject.call }.should raise_error(Genomer::Error,"Unknown feature type 'unknown'")
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
context "for a feature with no attributes" do
|
178
|
+
|
179
|
+
let(:annotation) do
|
180
|
+
@attn
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should return an empty array" do
|
184
|
+
subject.should be_empty
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
context "for a feature with an unknown attribute" do
|
190
|
+
|
191
|
+
let(:annotation) do
|
192
|
+
@attn.attributes('something' => 'else')
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should return an empty array" do
|
196
|
+
subject.should be_empty
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
feature_keys = {
|
202
|
+
:gene => {
|
203
|
+
'Name' => 'gene',
|
204
|
+
'ID' => 'locus_tag' },
|
205
|
+
:tRNA => {
|
206
|
+
'product' => 'product',
|
207
|
+
'Note' => 'note'},
|
208
|
+
:rRNA => {
|
209
|
+
'product' => 'product',
|
210
|
+
'Note' => 'note'},
|
211
|
+
:miscRNA => {
|
212
|
+
'product' => 'product',
|
213
|
+
'Note' => 'note'},
|
214
|
+
:tmRNA => {
|
215
|
+
'product' => 'product',
|
216
|
+
'Note' => 'note'},
|
217
|
+
:CDS => {
|
218
|
+
'ec_number' => 'EC_number',
|
219
|
+
'function' => 'function',
|
220
|
+
'product' => 'product',
|
221
|
+
'Note' => 'note',
|
222
|
+
'ID' => 'protein_id' }}
|
223
|
+
|
224
|
+
feature_keys.each do |type,mappings|
|
225
|
+
mappings.each do |a,b|
|
226
|
+
context "#{type.to_s} feature" do
|
227
|
+
|
228
|
+
let(:annotation) do
|
229
|
+
@attn.feature(type.to_s).attributes(a => :value)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should return #{b} for the attribute #{a}" do
|
233
|
+
subject.first.should_not be_nil
|
234
|
+
subject.first.first.should == b
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'genomer-plugin-view/mapping'
|
3
|
+
|
4
|
+
describe GenomerPluginView::Mapping do
|
5
|
+
|
6
|
+
describe "#run" do
|
7
|
+
|
8
|
+
let(:annotations) do
|
9
|
+
[
|
10
|
+
gene(:start => 1, :end => 3, :attributes => {'ID' => 'gene1'}),
|
11
|
+
gene(:start => 4, :end => 6, :attributes => {'ID' => 'gene2'}),
|
12
|
+
gene(:start => 7, :end => 9, :attributes => {'ID' => 'gene3'}),
|
13
|
+
gene(:start => 10, :end => 12, :attributes => {'ID' => 'gene4'})
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
stub(Scaffolder::AnnotationLocator).new do
|
19
|
+
annotations
|
20
|
+
end
|
21
|
+
stub(subject).flags do
|
22
|
+
flags
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
subject do
|
27
|
+
described_class.new([],{})
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "with no annotations or flags" do
|
31
|
+
|
32
|
+
let(:flags){ {} }
|
33
|
+
|
34
|
+
let(:annotations){ [] }
|
35
|
+
|
36
|
+
it "should return an empty mapping" do
|
37
|
+
subject.run.should == ""
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "with some annotations" do
|
43
|
+
|
44
|
+
let(:flags){ {} }
|
45
|
+
|
46
|
+
it "should return a mapping of the same ids" do
|
47
|
+
subject.run.should == <<-EOS.unindent.strip
|
48
|
+
gene1\tgene1
|
49
|
+
gene2\tgene2
|
50
|
+
gene3\tgene3
|
51
|
+
gene4\tgene4
|
52
|
+
EOS
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "with the prefix flag" do
|
58
|
+
|
59
|
+
let(:flags){ {:prefix => 'pre_'} }
|
60
|
+
|
61
|
+
it "should return a mapping to the prefixed ids" do
|
62
|
+
subject.run.should == <<-EOS.unindent.strip
|
63
|
+
gene1\tpre_gene1
|
64
|
+
gene2\tpre_gene2
|
65
|
+
gene3\tpre_gene3
|
66
|
+
gene4\tpre_gene4
|
67
|
+
EOS
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "with the reset_locus_numbering flag " do
|
73
|
+
|
74
|
+
let(:flags){ {:reset_locus_numbering => true} }
|
75
|
+
|
76
|
+
it "should return a mapping to the reset ids" do
|
77
|
+
subject.run.should == <<-EOS.unindent.strip
|
78
|
+
gene1\t000001
|
79
|
+
gene2\t000002
|
80
|
+
gene3\t000003
|
81
|
+
gene4\t000004
|
82
|
+
EOS
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|