ABIF 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8209086fa0fd89bb8c512306fbb483b238265a20
4
+ data.tar.gz: e439aefb5b8f8d864365fdbd94a29ed8c6d5d422
5
+ SHA512:
6
+ metadata.gz: ca2ff2b3f0a162039a130d691093508540d1d3eb66050a5e99e35f419b1d270c2ceca5f894fa6d7e04246d42adec0aef8f84b92d635a4040e8a0ca1be849ac94
7
+ data.tar.gz: f3041d14381c0aae42617f1e2cc2a724b427392cdd65cfc33640e281f47e2515bf27e9a1e91bd99be3207c893f88d2e9f119d1e74f026e1ac9e28400e91eb963
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ABIF/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ABIF"
8
+ spec.version = ABIF::VERSION
9
+ spec.authors = ["Sascha Willuweit"]
10
+ spec.email = ["s@rprojekt.org"]
11
+ spec.description = %q{ABIF file format reader/parse/plotter.}
12
+ spec.summary = %q{Handle/Parse/Plot ABIF (Applied Biosystems Genetic Analysis Data File Format) FSA, AB1 and HID files.}
13
+ spec.homepage = "https://github.com/545ch4/ABIF"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "thor"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "minitest"
25
+ spec.add_development_dependency "rake"
26
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ABIF.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sascha Willuweit
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ # ABIF
2
+
3
+ Handle ABIF (Applied Biosystems Genetic Analysis Data File Format) FSA, AB1 and HID files.
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'ABIF'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install ABIF
19
+
20
+
21
+ ## Usage
22
+
23
+ file = ABIF::File.new(<.fsa|ab1|hid file or IO stream>)
24
+ puts file.data.keys
25
+ puts file.data['RunN_1']
26
+
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create new Pull Request
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib/ABIF'
8
+ t.test_files = FileList['test/lib/ABIF/*_test.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'ABIF/CLI'
3
+ ABIF::CLI.start
@@ -0,0 +1,11 @@
1
+ require "ABIF/version"
2
+ require "ABIF/file"
3
+ # This program is a ABIF file (Applied Biosystems Genetic Analysis Data File Format)
4
+ # reader. It takes a ABIF file (.fsa) or HID file (.hid) and reading its content to several arrays of (named) datapoints.
5
+ # For in-depths description of the file format see http://www.appliedbiosystems.com/support/software_community/ABIF_File_Format.pdf
6
+ #
7
+ # Author:: Sascha Willuweit (s@rprojekt.org)
8
+ # Copyright:: Copyright (c) 2013 Sascha Willuweit
9
+ # License:: CreativeCommons Attribution-NonCommercial-ShareAlike 3.0 Unported License (see http://creativecommons.org/licenses/by-nc-sa/3.0/)
10
+ module ABIF
11
+ end
@@ -0,0 +1,91 @@
1
+ require 'thor'
2
+ require 'tempfile'
3
+ require 'open3'
4
+ require 'abif'
5
+
6
+ module ABIF
7
+ class CLI < Thor
8
+ class_option :verbose, :type => :boolean
9
+ class_option :version, :type => :boolean
10
+
11
+ desc "test FILE", "Test validity of FILE"
12
+ def test(filename)
13
+ print_version if options[:version]
14
+ puts ABIF::File.supported? filename, options.select{|option| [].include? option}
15
+ end
16
+
17
+ option :format, :type => :string, :default => 'dat'
18
+ option :normalize, :type => :string, :default => 'none'
19
+ desc "parse FILE", "parse FILE "
20
+ def parse(filename)
21
+ print_version if options[:version]
22
+
23
+ f = ABIF::File.new filename, options.select{|option| [:normalize].include? option}
24
+ refrence_datapoints = f.data['DATA_1'].size
25
+ channels = f.data.keys.select{|channel| channel.include?('DATA_') && f.data[channel].size == refrence_datapoints}
26
+ case options[:format]
27
+ when 'csv'
28
+ puts "index," << channels.join(",")
29
+ refrence_datapoints.times do |i|
30
+ puts "#{i}," << channels.map{|channel| f.data[channel][i]}.join(",")
31
+ end
32
+ when 'raw'
33
+ f.data.each do |key, d|
34
+ puts "#{key} (#{f.data_params[key].join(',')}): #{d.inspect}"
35
+ end
36
+ else
37
+ puts "index\t" << channels.join("\t")
38
+ refrence_datapoints.times do |i|
39
+ puts "#{i}\t" << channels.map{|channel| f.data[channel][i]}.join("\t")
40
+ end
41
+ end
42
+ exit 0
43
+ end
44
+
45
+ option :format, :type => :string, :default => 'png'
46
+ option :size, :type => :string, :default => '5000,6000'
47
+ option :normalize, :type => :string, :default => 'none'
48
+ desc "plot FILE OUTFILE", "plot FILE into OUTFILE"
49
+ def plot(filename, outfilename)
50
+ print_version if options[:version]
51
+
52
+ #colors = ['blue', 'green', 'black', 'red', 'orange', 'purple']
53
+
54
+ f = ABIF::File.new filename, options.select{|option| [:normalize].include? option}
55
+ tmpfile = Tempfile.new('abifcli.dat')
56
+
57
+ refrence_datapoints = f.data['DATA_1'].size
58
+ channels = f.data.keys.select{|channel| channel.include?('DATA_') && f.data[channel].size == refrence_datapoints}
59
+ tmpfile.puts "index\t" << channels.join("\t")
60
+ refrence_datapoints.times do |i|
61
+ tmpfile.puts "#{i}\t" << channels.map{|channel| f.data[channel][i]}.join("\t")
62
+ end
63
+ tmpfile.close
64
+
65
+ IO.popen(%w{gnuplot}, 'r+') do |gnuplot|
66
+ gnuplot.puts "set terminal #{options[:format].inspect} size #{options[:size]}"
67
+ gnuplot.puts "set output #{outfilename.inspect}"
68
+ gnuplot.puts "set multiplot layout #{channels.size}, 1 title #{filename.inspect}"
69
+ channels.each_with_index.map do |channel, i|
70
+ gnuplot.puts "set title #{channel.inspect}"
71
+ gnuplot.puts "unset key"
72
+ gnuplot.puts "plot #{tmpfile.path.inspect} using 1:#{i + 2} with lines lt 1 lc rgb 'grey' lw 1"
73
+ end
74
+ gnuplot.puts "unset multiplot"
75
+ gnuplot.puts "exit"
76
+ gnuplot.close_write
77
+ end
78
+
79
+ tmpfile.unlink
80
+
81
+ exit 0
82
+ end
83
+
84
+ private
85
+
86
+ def print_version
87
+ puts "abifcli version #{ABIF::VERSION}"
88
+ exit 0
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,236 @@
1
+ require 'zlib'
2
+ require 'openssl'
3
+
4
+ module ABIF
5
+ # This class holds the FSA/HID file format data. It's initialized given the filename or an IO object.
6
+ # Options are:
7
+ # [:normalize] All channels are normalized with respect to their 500-datapoint-tail assuming it means-up to 0.
8
+ class File
9
+ attr_reader :filetype, :fileversion, :data, :data_params
10
+
11
+ def self.supported?(filename_or_io, options = {})
12
+ ft = nil
13
+ fv = 0
14
+ begin
15
+ io = filename_or_io.respond_to?(:seek) ? filename_or_io : ::File.open(filename_or_io, 'rb')
16
+ (ft, fv) = io.read(6).unpack('A4S>')
17
+ rescue Exception => e
18
+ raise IOError.new "Error reding ABIF file: #{e}"
19
+ ensure
20
+ io.close unless io.nil? || !io.respond_to?(:close)
21
+ end
22
+ return ft == 'ABIF' && fv >= 100
23
+ end
24
+
25
+ def initialize(filename_or_io, options = {})
26
+ @data = {}
27
+ @data_params = {}
28
+ @named_data = {}
29
+ @some_counter = 1
30
+
31
+ @decipher = OpenSSL::Cipher.new('DES-CBC')
32
+ @decipher.key = "W\xB6\xBF\xBC\xFE\xBA1&" # [87, -74, -65, -68, -2, -70, 49, 38].pack('c*')
33
+ @decipher.iv = "\x8E\x129\x9C\aroZ" # [-114, 18, 57, -100, 7, 114, 111, 90].pack('c*')
34
+
35
+ io = nil
36
+ begin
37
+ io = filename_or_io.respond_to?(:seek) ? filename_or_io : ::File.open(filename_or_io, 'rb')
38
+ (@filetype, @fileversion) = io.read(6).unpack('A4S>')
39
+ raise IOError.new('Not an ABIF file') unless @filetype == 'ABIF' && @fileversion >= 100
40
+ header_dir_entry = unpack_dir_entry(io)
41
+ io.seek(header_dir_entry[:data_offset])
42
+ header_dir_entry[:num_elements].times do
43
+ dir_entry = unpack_dir_entry(io)
44
+ old_pos = io.pos
45
+ if dir_entry[:element_size] * dir_entry[:num_elements] > 4
46
+ io.seek(dir_entry[:data_offset])
47
+ else
48
+ io.seek(-8, IO::SEEK_CUR)
49
+ end
50
+
51
+ @data_params["#{dir_entry[:name]}_#{dir_entry[:number]}"] = [dir_entry[:element_type], dir_entry[:element_size], dir_entry[:num_elements], dir_entry[:data_size]]
52
+ @data["#{dir_entry[:name]}_#{dir_entry[:number]}"] = unpack_data(dir_entry[:element_type], dir_entry[:element_size], dir_entry[:num_elements], dir_entry[:data_size], io)
53
+ io.seek(old_pos)
54
+ end
55
+ rescue Exception => e
56
+ raise IOError.new "Error reding ABIF file: #{e}"
57
+ ensure
58
+ io.close unless io.nil? || !io.respond_to?(:close)
59
+ end
60
+
61
+ if options[:normalize] && options[:normalize] != 'none'
62
+ data_length = @data['DATA_1'].size
63
+ @data.keys.select{|key| key.include?('DATA_') && @data[key].size == data_length}.each do |key|
64
+ mean = 0.0
65
+ if options[:normalize] == 'head'
66
+ mean = @data[key][500..(500+[499,data_length].min)].inject(0.0){|t, datapoint| t + datapoint} / [499,data_length].min.to_f
67
+ elsif options[:normalize] == 'tail'
68
+ mean = @data[key][-500..-1].inject(0.0){|t, datapoint| t + datapoint} / 500.0
69
+ end
70
+ @data[key] = @data[key].map{|i| i - mean}
71
+ end
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def some_counter
78
+ @some_counter = @some_counter + 1
79
+ end
80
+
81
+ def unpack_dir_entry(io)
82
+ dir_entry = {}
83
+ dir_entry[:name], dir_entry[:number], dir_entry[:element_type], dir_entry[:element_size], dir_entry[:num_elements], dir_entry[:data_size], dir_entry[:data_offset], dir_entry[:data_handle] = io.read(28).unpack('A4L>S>S>L>L>L>L>')
84
+ dir_entry
85
+ end
86
+
87
+ def unpack_data(type, size, num, data_size, io)
88
+ # TODO Checksum
89
+ # Fields: CkSm, CkSm-1, CkSm-2, CLst
90
+ # split by ':'
91
+ # Objects: java.util.Collections.synchronizedSortedSet/java.util.SortedSet/TreeSet/java.util.SortedSet
92
+ # MD5 BASE64Encoder "ABIFAdmin", "IdeABu++inghedsmiteCLI4S3", "81tingpH!sh1es", "eleMENT5ConsOLI45Dated", "AloysiusANdauGUST1NE"
93
+ data = io.read(data_size)
94
+ case type
95
+ when 0 # IllegalType -1-byte(s) wide
96
+ "illegal type 'IllegalType'(#{type})"
97
+ when 1 # Byte 1-byte(s) wide
98
+ data.unpack('C' * num)
99
+ when 2 # Char 1-byte(s) wide
100
+ data.unpack('C' * num)
101
+ when 3 # Word 2-byte(s) wide
102
+ data.unpack('S>' * num)
103
+ when 4 # Short 2-byte(s) wide
104
+ data.unpack('s>' * num)
105
+ when 5 # Long 4-byte(s) wide
106
+ data.unpack('l>' * num)
107
+ when 6 # Rational 8-byte(s) wide
108
+ struct = {}
109
+ struct[:numerator], struct[:denumerator] = data.unpack('l>l>' * num)
110
+ struct
111
+ when 7 # Float 4-byte(s) wide
112
+ data.unpack('g' * num)
113
+ when 8 # Double 8-byte(s) wide
114
+ data.unpack('G' * num)
115
+ when 9 # BCD 0-byte(s) wide
116
+ "unsupported type 'BCD'(#{type})"
117
+ when 10 # Date 4-byte(s) wide
118
+ struct = {}
119
+ struct[:year], struct[:month], struct[:day] = data.unpack('s>CC' * num)
120
+ struct
121
+ when 11 # Time 4-byte(s) wide
122
+ struct = {}
123
+ struct[:hour], struct[:minute], struct[:second], struct[:hsecond] = data.unpack('CCCC' * num)
124
+ struct
125
+ when 12 # Thumb 10-byte(s) wide
126
+ struct = {}
127
+ struct[:d], struct[:u], struct[:c], struct[:n] = data.unpack('l>l>CC' * num)
128
+ struct
129
+ when 13 # Boolean 1-byte(s) wide
130
+ data.unpack('C' * num).map{|x| x == 0 ? false : true}
131
+ when 14 # Point 4-byte(s) wide
132
+ struct = {}
133
+ struct[:v], struct[:h] = data.unpack('s>s>' * num)
134
+ struct
135
+ when 15 # Rect 8-byte(s) wide
136
+ struct = {}
137
+ struct[:top], struct[:left], struct[:bottom], struct[:right] = data.unpack('s>s>s>s>' * num)
138
+ struct
139
+ when 16 # VPoint 8-byte(s) wide
140
+ struct = {}
141
+ struct[:v], struct[:h] = data.unpack('l>l>' * num)
142
+ struct
143
+ when 17 # VRect 16-byte(s) wide
144
+ struct = {}
145
+ struct[:top], struct[:left], struct[:bottom], struct[:right] = data.unpack('l>l>l>l>' * num)
146
+ struct
147
+ when 18 # PString 1-byte(s) wide
148
+ data[1..data[0].unpack("C").first]
149
+ when 19 # CString 1-byte(s) wide
150
+ data[0..-2]
151
+ when 20 # Tag 8-byte(s) wide
152
+ struct = {}
153
+ struct[:name], struct[:number] = data.unpack('l>l>' * num)
154
+ struct
155
+ when 21 # DeltaLZWcompression 1-byte(s) wide
156
+ # TODO: What is a "DeltaLZWcompression" compression? Implement it the right way.
157
+ "unsupported compression 'DeltaLZWcompression'(#{type})"
158
+ when 22 # LZWcompression 1-byte(s) wide
159
+ unlzw(data.unpack('C' * size * num))
160
+ when 23 # Directory 28-byte(s) wide
161
+ unpack_dir_entry(data)
162
+ when 24 # UserType 1-byte(s) wide
163
+ "user type 'UserType'(#{type}) => #{num} elements of #{size}-byte wide struct: " << data.unpack('C' * size * num).join(', ')
164
+ when 25 # CustomUserType 1-byte(s) wide
165
+ "user type 'CustomUserType'(#{type}) => #{num} elements of #{size}-byte wide struct: " << data.unpack('C' * size * num).join(', ')
166
+ when 26 # IString 1-byte(s) wide
167
+ # TODO: What is an "IString"? Implement it the right way.
168
+ data
169
+ when 27 # compressedByte 1-byte(s) wide
170
+ decrypt(data).unpack('C' * data_size)
171
+ when 28 # compressedShort 1-byte(s) wide
172
+ decrypt(data).unpack('C' * (data_size / 2))
173
+ when 29 # compressedIString 1-byte(s) wide
174
+ # TODO: What is an "IString"? Implement it the right way.
175
+ decrypt(data)
176
+ when 30 # compressedChar 1-byte(s) wide
177
+ decrypt(data).unpack('C' * data_size)
178
+ when 31 # compressedLong 1-byte(s) wide
179
+ decrypt(data).unpack('l>' * (data_size / 4))
180
+ when 32 # compressedDouble 1-byte(s) wide
181
+ decrypt(data).unpack('G' * (data_size / 8))
182
+ when 33 # compressedCString 1-byte(s) wide
183
+ decrypt(data)[0..-2]
184
+ when 34 # compressedPString 1-byte(s) wide
185
+ decrypted = decrypt(data)
186
+ decrypted[1..decrypted[0].unpack("C").first]
187
+ when 35 # compressedFloat 1-byte(s) wide
188
+ decrypt(data).unpack('g' * (data_size / 4))
189
+ when 128 # deltaComp
190
+ # TODO: What is a "deltaComp" compression? Implement it the right way.
191
+ "unsupported compression 'deltaComp' data type '#{type}'"
192
+ when 256 # LZWComp
193
+ unlzw(data.unpack('C' * size * num))
194
+ when 384 # deltaLZW
195
+ # TODO: What is a "deltaLZW" compression? Implement it the right way.
196
+ "unsupported compression 'deltaLZW'(#{type})"
197
+ when 1024 # user
198
+ "user type 'user'(#{type}) => #{num} elements of #{size}-byte wide struct: " << data.unpack('C' * size * num).join(', ')
199
+ else
200
+ "unsupported type '#{type}': " << data.unpack('C' * size * num).join(', ')
201
+ end
202
+ end
203
+
204
+ def inflate(compressed)
205
+ Zlib::Inflate.inflate compressed
206
+ end
207
+
208
+ def unlzw(compressed)
209
+ dict_size = 256
210
+ dictionary = Hash[ Array.new(dict_size) {|i| [i.chr, i.chr]} ]
211
+
212
+ w = result = compressed.shift
213
+ for k in compressed
214
+ if dictionary.has_key?(k)
215
+ entry = dictionary[k]
216
+ elsif k == dict_size
217
+ entry = w + w[0,1]
218
+ else
219
+ raise 'Bad compressed k: %s' % k
220
+ end
221
+ result += entry
222
+
223
+ dictionary[dict_size] = w + entry[0,1]
224
+ dict_size += 1
225
+
226
+ w = entry
227
+ end
228
+ result
229
+ end
230
+
231
+ def decrypt(encrypted)
232
+ @decipher.reset
233
+ @decipher.update(encrypted) + @decipher.final
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,3 @@
1
+ module ABIF
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,44 @@
1
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
2
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
3
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
4
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
5
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
6
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
7
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
8
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
9
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
10
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
11
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
12
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
13
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
14
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
15
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
16
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
17
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
18
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
19
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
20
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
21
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
22
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
23
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
24
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
25
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
26
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
27
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
28
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
29
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
30
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
31
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
32
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
33
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
34
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
35
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
36
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
37
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
38
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
39
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
40
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
41
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
42
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
43
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
44
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
Binary file
@@ -0,0 +1,189 @@
1
+ require_relative '../../test_helper'
2
+
3
+ describe ABIF::File do
4
+ describe 'omitting file/filename' do
5
+ it 'raises an Error' do
6
+ Proc.new { ABIF::File.new }.must_raise ArgumentError
7
+ end
8
+ end
9
+
10
+ describe 'invalid file/filehandle' do
11
+ it 'invalid file raises an Exception' do
12
+ Proc.new { ABIF::File.new('test/files/invalid.abif') }.must_raise IOError
13
+ end
14
+
15
+ it 'non-existing file raises an Exception' do
16
+ Proc.new { ABIF::File.new('test/files/foo.abif') }.must_raise IOError
17
+ end
18
+
19
+ it 'empty filehandle raises an Exception' do
20
+ Proc.new { ABIF::File.new(File.new) }.must_raise ArgumentError
21
+ end
22
+ end
23
+
24
+ describe ABIF::File, 'valid filename' do
25
+ subject { ABIF::File.new('test/files/valid.abif') }
26
+
27
+ it 'is an instance of ABIF::File' do
28
+ subject.must_be_instance_of ABIF::File
29
+ end
30
+
31
+ it 'filetype is ABIF' do
32
+ subject.filetype.must_equal 'ABIF'
33
+ end
34
+
35
+ it 'fileversion is 101' do
36
+ subject.fileversion.must_equal 101
37
+ end
38
+
39
+ it 'data is a Hash' do
40
+ subject.data.must_be_kind_of Hash
41
+ end
42
+
43
+ {
44
+ 'AEPt_1' => '329a2798ac4a2024f904a4900de7600d',
45
+ 'AEPt_2' => '329a2798ac4a2024f904a4900de7600d',
46
+ 'APFN_2' => '509a32e5f2979be945f61cddbd14622c',
47
+ 'APXV_1' => '39c6844c921cf69656adaa2a8e4aea0c',
48
+ 'APrN_1' => '509a32e5f2979be945f61cddbd14622c',
49
+ 'APrV_1' => '3cf3aef9902754f1c9178e32f5fe1ddc',
50
+ 'APrX_1' => '773e4cd95581ad061589066058e65d4f',
51
+ 'ARTN_1' => '8d5162ca104fa7e79fe80fd92bb657fb',
52
+ 'ASPF_1' => '35dba5d75538a9bbe0b4da4422759a0e',
53
+ 'ASPt_1' => '220e850bfe79cb3526b375bc6dcdd2ef',
54
+ 'ASPt_2' => '220e850bfe79cb3526b375bc6dcdd2ef',
55
+ 'AUDT_1' => '49c8922d68864bb83c04879c1589a0fb',
56
+ 'B1Pt_1' => 'af7e8bea94ff3c20159e249200b6aa18',
57
+ 'B1Pt_2' => 'af7e8bea94ff3c20159e249200b6aa18',
58
+ 'BCTS_1' => '162bb794a66800199501e1e9de7a15df',
59
+ 'BufT_1' => '83a08dbe51340d001d2e7a3f8708e8cb',
60
+ 'CCut_1' => 'b95b0b3bc23f39b3c04bc2baf211ba5b',
61
+ 'CMNT_1' => '81bba32c7b86600386d96930ec17fda4',
62
+ 'CTID_1' => '46f79adeafce95e4fdd7b6aebad1699e',
63
+ 'CTNM_1' => '46f79adeafce95e4fdd7b6aebad1699e',
64
+ 'CTOw_1' => 'c446a4c96a0fe001210b71144c2268f9',
65
+ 'CTTL_1' => '74c70c8291e9dacf1935132d58229634',
66
+ 'CpEP_1' => '35dba5d75538a9bbe0b4da4422759a0e',
67
+ 'DATA_1' => 'c29a483afbeb83172305fb0803f3f264',
68
+ 'DATA_2' => 'd9f5d923f13c66ff2385ee9cac1ba2f3',
69
+ 'DATA_3' => 'e14a88b6353558b6af927de5ec1e070a',
70
+ 'DATA_4' => '2b60b8f09786c6c182f53da105483bba',
71
+ 'DATA_5' => '6f501928683d29942b95d5dad46e2e26',
72
+ 'DATA_6' => 'f66e5d54b3606d9e060351c85a2ef733',
73
+ 'DATA_7' => '7de240b0d5c835a9242555aaaa425d7a',
74
+ 'DATA_8' => '272c59f929d32af7a1d655d175cf7a0e',
75
+ 'DATA_9' => '66200730a3dc10020304032cc257dbd1',
76
+ 'DATA_10' => '80238386cad29c86e1afc5d9a4d6622e',
77
+ 'DATA_11' => '6d20453b6705c0144f954e9751b61c51',
78
+ 'DATA_12' => '49061ea4bee661346a8d4ece6a606a3b',
79
+ 'DCHT_1' => '8d5162ca104fa7e79fe80fd92bb657fb',
80
+ 'DSam_1' => '35dba5d75538a9bbe0b4da4422759a0e',
81
+ 'DySN_1' => 'c300e27b7c225652d4130f053f807199',
82
+ 'Dye#_1' => 'e962e23c139e7252904b9221d9967442',
83
+ 'DyeN_1' => 'b654f7796f95e5ed17096a82a0b28315',
84
+ 'DyeN_2' => '207d360b49d1b72c0c35c89833757e5c',
85
+ 'DyeN_3' => 'ac4b808acb1fc85fa0060bc92f489c69',
86
+ 'DyeN_4' => '0ac0051af6ece5afeacf8e53e1dade59',
87
+ 'DyeW_1' => 'f9639b0987d2ad3a3ae945ee29c889b4',
88
+ 'DyeW_2' => '01df866ea9d6a730be6e319110ecfda0',
89
+ 'DyeW_3' => 'c0280f103f34474ab0107746f80736fd',
90
+ 'DyeW_4' => '47f2ba5a7a71c4646d8add9de01d8368',
91
+ 'EPVt_1' => 'aea034f6800b624bf4d8d9fd4553d264',
92
+ 'EVNT_1' => '10d4ece1db63d754b5ef1ba8fb635269',
93
+ 'EVNT_2' => '9a81c64cb96fc6b7327bb2613c52e89d',
94
+ 'EVNT_3' => 'fec688b3587dff8bb2c12a59cee0763e',
95
+ 'EVNT_4' => '906341f47061764eb805b0b57b3cd7cc',
96
+ 'FTab_1' => '21beecaab27020d9069dee9a570296d8',
97
+ 'FVoc_1' => '139268d7ad20b68f72faa0b1691cac14',
98
+ 'FWO__1' => '9f40a00e83bbaf678fe218b11f81d49e',
99
+ 'Feat_1' => 'f9131fe168d95c26058ae03cff8e6be0',
100
+ 'GTyp_1' => 'c7b375c0c538659369eee293b1cd8986',
101
+ 'HCFG_1' => 'dbe992717239d8f63333a14fae4232c1',
102
+ 'HCFG_2' => '9c0224cfb93aa409728cbac69fdf614b',
103
+ 'HCFG_3' => '96cd52a8c96d12ba88c6ba36c316603d',
104
+ 'HCFG_4' => 'fed17cd2cc23396408f8c2b480d71836',
105
+ 'InSc_1' => '2a30f5f3b7d1a97cb6132480b992d984',
106
+ 'InVt_1' => '423c57007341da0749aa1d8bb0da8042',
107
+ 'LANE_1' => '6615ab6435d4f1da792f1e6fa230cb29',
108
+ 'LIMS_1' => '6b3b0fa06550a54ba95f2e78dfb213b4',
109
+ 'LNTD_1' => '8a8783242b7b77de148a06a0bab42ba9',
110
+ 'LsrP_1' => '0a4f74e275e1168915d8d512ed22bf0c',
111
+ 'MCHN_1' => 'ff90c90ed28916bb58eb2f56f425b41f',
112
+ 'MODF_1' => '013f5a3ac5836a46be81dee59261f68d',
113
+ 'MODL_1' => '59afde3cd75ce96556b9d5b3ce95fef5',
114
+ 'NAVG_1' => '35dba5d75538a9bbe0b4da4422759a0e',
115
+ 'NLNE_1' => '2375ef9e856b982a6f9e5b8fb903e6d7',
116
+ 'NOIS_1' => '60afc12c44f69325eb1906a147339931',
117
+ 'PBAS_1' => '214591fbf4e0c6032961ffb3dc685aaf',
118
+ 'PBAS_2' => '214591fbf4e0c6032961ffb3dc685aaf',
119
+ 'PCON_1' => '59cf9b876ec3410633cb72058af1cf8e',
120
+ 'PCON_2' => '59cf9b876ec3410633cb72058af1cf8e',
121
+ 'PDMF_1' => '94827116b0e6fec7abd084917c8cfc33',
122
+ 'PDMF_2' => '94827116b0e6fec7abd084917c8cfc33',
123
+ 'PLOC_1' => '87f2292a0f208ed70cb915c4d6c625e7',
124
+ 'PLOC_2' => '87f2292a0f208ed70cb915c4d6c625e7',
125
+ 'PSZE_1' => '2375ef9e856b982a6f9e5b8fb903e6d7',
126
+ 'PTYP_1' => 'f75f3b63236ce233758cc898ebe835d0',
127
+ 'PXLB_1' => 'f2577a6fc29b900fe7d4c6321346be48',
128
+ 'RGNm_1' => '779dfa8b1b7a5cfd8063493b4bf2be46',
129
+ 'RGOw_1' => 'b0b576a3a438583bd475a14acf06bf8b',
130
+ 'RMXV_1' => '2f7bb230c70819aeb10b45a709bcf48f',
131
+ 'RMdN_1' => '013f5a3ac5836a46be81dee59261f68d',
132
+ 'RMdV_1' => '2f7bb230c70819aeb10b45a709bcf48f',
133
+ 'RMdX_1' => '41b6d91073540a2a199bf9f089e11a29',
134
+ 'RPrN_1' => '21d72202012057acf64ec7d3aa52ee42',
135
+ 'RPrV_1' => '2f7bb230c70819aeb10b45a709bcf48f',
136
+ 'RUND_1' => '21e7f6441ffe6ef6c36db98592ae0810',
137
+ 'RUND_2' => '21e7f6441ffe6ef6c36db98592ae0810',
138
+ 'RUND_3' => '21e7f6441ffe6ef6c36db98592ae0810',
139
+ 'RUND_4' => '21e7f6441ffe6ef6c36db98592ae0810',
140
+ 'RUNT_1' => '42a575cff8de9a296db610df9cff6f1f',
141
+ 'RUNT_2' => '8647ea4a1090319b27562610d831172e',
142
+ 'RUNT_3' => '1523ed7e16b541e809eb6acacf5f32c1',
143
+ 'RUNT_4' => '337a52990fce3bea946d4fa60d0f51aa',
144
+ 'Rate_1' => '9f1074af1ce98833fbf4775c5f3595cb',
145
+ 'RunN_1' => '2048de7707e4fdc395175ce4784dce18',
146
+ 'S/N%_1' => 'fbd3b15939b954654a38824ec1e82eb7',
147
+ 'SCAN_1' => '329a2798ac4a2024f904a4900de7600d',
148
+ 'SMED_1' => '0edefa708c51887ad9b3fbe1ea9e7e82',
149
+ 'SMLt_1' => 'aed6e480b8aad696f3bb3a2781cd55d6',
150
+ 'SMPL_1' => '172160c679614e93d5c07ef7b7a2441f',
151
+ 'SPAC_1' => '3e58eb892f1ff04c1da6acf6509f976b',
152
+ 'SPAC_2' => 'e991d1ef3f35a5da0b8b724490a6f21a',
153
+ 'SPAC_3' => '3e58eb892f1ff04c1da6acf6509f976b',
154
+ 'SVER_1' => 'a629005e3c810e8491172eebd622a57b',
155
+ 'SVER_2' => 'cbd989d62be7257144760e24edeaf516',
156
+ 'SVER_3' => '783e7db369d5e7d7d57e5c76a1dec609',
157
+ 'Scal_1' => '8796ada1698c9940b7cf9264407731b1',
158
+ 'Scan_1' => '329a2798ac4a2024f904a4900de7600d',
159
+ 'TUBE_1' => 'aafe2f8af7d2109f20d5ae4c488bf1c6',
160
+ 'Tmpr_1' => '1be08982f722684e69bdf6c5549d67ba',
161
+ 'User_1' => 'c446a4c96a0fe001210b71144c2268f9',
162
+ 'phAR_1' => '14a685bc2583777f837ed9d24798d915',
163
+ 'phCH_1' => '89a93d4bcb2615549a98b93d2e2f5c96',
164
+ 'phDY_1' => '7153f0402307a99a60929d7b5dcd886b',
165
+ 'phQL_1' => 'e6cd5c7f942fc1c21557adbc97739b8c',
166
+ 'phTR_1' => 'b95b0b3bc23f39b3c04bc2baf211ba5b',
167
+ 'phTR_2' => '14a685bc2583777f837ed9d24798d915'
168
+ }.each do |key, md5|
169
+ it "MD5 of data['#{key}'] equals '#{md5}'" do
170
+ subject.data[key].wont_be_nil
171
+ Digest::MD5.hexdigest(subject.data[key].inspect).must_equal md5
172
+ end
173
+ end
174
+ end
175
+
176
+ describe 'supported?' do
177
+ it 'return false on unsupported file' do
178
+ ABIF::File.supported?('test/files/invalid.abif').must_equal false
179
+ end
180
+
181
+ it 'return true on supported file' do
182
+ ABIF::File.supported?('test/files/valid.abif').must_equal true
183
+ end
184
+
185
+ it 'raise an exception on non-existing file' do
186
+ Proc.new { ABIF::File.supported?('test/files/foo.abif') }.must_raise IOError
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,4 @@
1
+ gem 'minitest'
2
+ require 'minitest/autorun'
3
+ require 'minitest/pride'
4
+ require File.expand_path('../../lib/ABIF.rb', __FILE__)
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ABIF
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sascha Willuweit
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: ABIF file format reader/parse/plotter.
70
+ email:
71
+ - s@rprojekt.org
72
+ executables:
73
+ - abifcli
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - ABIF.gemspec
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/abifcli
84
+ - lib/ABIF.rb
85
+ - lib/ABIF/cli.rb
86
+ - lib/ABIF/file.rb
87
+ - lib/ABIF/version.rb
88
+ - test/files/invalid.abif
89
+ - test/files/valid.abif
90
+ - test/lib/ABIF/file_test.rb
91
+ - test/test_helper.rb
92
+ homepage: https://github.com/545ch4/ABIF
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.0.6
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Handle/Parse/Plot ABIF (Applied Biosystems Genetic Analysis Data File Format)
116
+ FSA, AB1 and HID files.
117
+ test_files:
118
+ - test/files/invalid.abif
119
+ - test/files/valid.abif
120
+ - test/lib/ABIF/file_test.rb
121
+ - test/test_helper.rb