rbbt-util 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/tsv.rb +2 -2
- data/bin/workflow.rb +24 -0
- data/lib/rbbt/util/open.rb +2 -1
- data/lib/rbbt/util/path.rb +5 -2
- data/lib/rbbt/util/persistence.rb +10 -1
- data/lib/rbbt/util/rake.rb +10 -3
- data/lib/rbbt/util/tmpfile.rb +1 -1
- data/lib/rbbt/util/tsv/index.rb +33 -21
- data/lib/rbbt/util/tsv/parse.rb +5 -3
- data/lib/rbbt/util/tsv.rb +2 -2
- data/lib/rbbt/util/workflow.rb +87 -0
- data/test/rbbt/util/test_R.rb +1 -1
- data/test/rbbt/util/test_pkg_data.rb +0 -5
- data/test/rbbt/util/test_workflow.rb +66 -2
- data/test/rbbt/util/tsv/test_attach.rb +1 -4
- data/test/rbbt/util/tsv/test_index.rb +7 -5
- data/test/rbbt/util/tsv/test_parse.rb +15 -0
- metadata +6 -4
data/bin/tsv.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rbbt/util/simpleopt'
|
4
4
|
|
5
|
-
options = SOPT.
|
5
|
+
options = SOPT.get "-h--help:-to--tsv-options*:-p--persistence"
|
6
6
|
|
7
7
|
command = ARGV.shift
|
8
8
|
file = ARGV.shift
|
@@ -10,5 +10,5 @@ file = ARGV.shift
|
|
10
10
|
case command
|
11
11
|
when 'cat'
|
12
12
|
puts TSV.new(file, options["tsv-options"].merge(options["persistence"]))
|
13
|
-
when
|
13
|
+
when
|
14
14
|
|
data/bin/workflow.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rbbt-util'
|
4
|
+
require 'rbbt/util/simpleopt'
|
5
|
+
require 'rbbt/util/workflow'
|
6
|
+
|
7
|
+
options = SOPT.get "-h--help:-t--target*:-n--name*"
|
8
|
+
|
9
|
+
raise "No target" unless options[:target]
|
10
|
+
|
11
|
+
file = ARGV.shift
|
12
|
+
|
13
|
+
if ARGV.empty?
|
14
|
+
data = STDIN.read
|
15
|
+
else
|
16
|
+
data = ARGV.shift
|
17
|
+
end
|
18
|
+
|
19
|
+
job = options[:name] || "Job"
|
20
|
+
|
21
|
+
puts "Runing WorkFlow in #{file} for target #{options[:target]}. Job: #{job}"
|
22
|
+
WorkFlow.load file, File.join(options[:target], job), data
|
23
|
+
puts
|
24
|
+
puts "WorkFlow done. Please find results in: #{File.join(options[:target], job)}"
|
data/lib/rbbt/util/open.rb
CHANGED
@@ -101,7 +101,7 @@ module Open
|
|
101
101
|
case
|
102
102
|
when Array === grep
|
103
103
|
TmpFile.with_file(grep * "\n", false) do |f|
|
104
|
-
CMD.cmd("grep", "-
|
104
|
+
CMD.cmd("grep", "-E" => true, "-f" => f, :in => stream, :pipe => true, :post => proc{FileUtils.rm f})
|
105
105
|
end
|
106
106
|
else
|
107
107
|
CMD.cmd("grep '#{grep}' -", :in => stream, :pipe => true)
|
@@ -201,6 +201,7 @@ module Open
|
|
201
201
|
end
|
202
202
|
|
203
203
|
def self.write(file, content)
|
204
|
+
FileUtils.mkdir_p File.dirname(file)
|
204
205
|
if String === content
|
205
206
|
File.open(file, 'w') do |f| f.write content end
|
206
207
|
else
|
data/lib/rbbt/util/path.rb
CHANGED
@@ -123,7 +123,6 @@ module Path
|
|
123
123
|
key_field, fields = TSV.parse_header(self.open, sep, header_hash).values_at(0, 1).flatten.collect{|f| f.extend TSV::Field; f.namespace = namespace; f}.select{|f| f.namespace == namespace}
|
124
124
|
end
|
125
125
|
|
126
|
-
|
127
126
|
def filename
|
128
127
|
self.to_s
|
129
128
|
end
|
@@ -138,7 +137,9 @@ module Path
|
|
138
137
|
end
|
139
138
|
|
140
139
|
def produce
|
141
|
-
return if File.exists? self
|
140
|
+
return self if File.exists? self
|
141
|
+
|
142
|
+
raise "No especified pkg_data for file #{ self }, cannot produce" if pkg_data.nil?
|
142
143
|
|
143
144
|
Log.debug("Trying to produce '#{ self }'")
|
144
145
|
file, producer = pkg_module.reclaim self
|
@@ -146,6 +147,8 @@ module Path
|
|
146
147
|
raise "File #{self} has not been claimed, cannot produce" if file.nil? or producer.nil?
|
147
148
|
|
148
149
|
pkg_module.produce(self, producer[:get], producer[:subdir], producer[:sharedir])
|
150
|
+
|
151
|
+
self
|
149
152
|
end
|
150
153
|
end
|
151
154
|
|
@@ -21,7 +21,16 @@ module Persistence
|
|
21
21
|
|
22
22
|
def self.get_persistence_file(file, prefix, options = {})
|
23
23
|
name = prefix.to_s << ":" << file.to_s << ":"
|
24
|
-
|
24
|
+
o = {}
|
25
|
+
options.each do |k,v|
|
26
|
+
if v.inspect =~ /:0x0/
|
27
|
+
o[k] = v.inspect.sub(/:0x[a-f0-9]+@/,'')
|
28
|
+
else
|
29
|
+
o[k] = v
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
File.join(CACHEDIR, name.to_s.gsub(/\s/,'_').gsub(/\//,'>') + Digest::MD5.hexdigest([file, o].inspect))
|
25
34
|
end
|
26
35
|
|
27
36
|
def self.get_filename(file)
|
data/lib/rbbt/util/rake.rb
CHANGED
@@ -12,9 +12,12 @@ module RakeHelper
|
|
12
12
|
FileUtils.chdir chdir if chdir
|
13
13
|
|
14
14
|
Rake::FileTask.module_eval do
|
15
|
-
|
16
|
-
|
15
|
+
if not self.respond_to? :old_define_task
|
16
|
+
class << self
|
17
|
+
alias_method :old_define_task, :define_task
|
18
|
+
end
|
17
19
|
end
|
20
|
+
|
18
21
|
def self.define_task(file, *args, &block)
|
19
22
|
@@files ||= []
|
20
23
|
if Hash === file
|
@@ -64,7 +67,11 @@ module RakeHelper
|
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
67
|
-
|
70
|
+
if block_given?
|
71
|
+
yield
|
72
|
+
else
|
73
|
+
load rakefile
|
74
|
+
end
|
68
75
|
|
69
76
|
task(:default) do |t|
|
70
77
|
Rake::FileTask.files.each do |file| Rake::Task[file].invoke end
|
data/lib/rbbt/util/tmpfile.rb
CHANGED
data/lib/rbbt/util/tsv/index.rb
CHANGED
@@ -139,14 +139,14 @@ class TSV
|
|
139
139
|
# both have fields => list of names
|
140
140
|
# not both have fields => nil
|
141
141
|
|
142
|
-
# fields2add = case
|
143
|
-
# when (fields2add.nil? and (other.fields.nil? or self.fields.nil?))
|
144
|
-
# nil
|
145
|
-
# when fields2add.nil?
|
146
|
-
# other.all_fields
|
147
|
-
# else
|
148
|
-
# fields2add
|
149
|
-
# end
|
142
|
+
# fields2add = case
|
143
|
+
# when (fields2add.nil? and (other.fields.nil? or self.fields.nil?))
|
144
|
+
# nil
|
145
|
+
# when fields2add.nil?
|
146
|
+
# other.all_fields
|
147
|
+
# else
|
148
|
+
# fields2add
|
149
|
+
# end
|
150
150
|
|
151
151
|
# Determine common fields
|
152
152
|
|
@@ -171,6 +171,8 @@ class TSV
|
|
171
171
|
match_source = (all_fields & match.all_fields).first
|
172
172
|
index = match.index :target => other.key_field, :fields => match_source
|
173
173
|
[match_source, index]
|
174
|
+
when (String === match and match == key_field)
|
175
|
+
[:key, other.index]
|
174
176
|
when String === match
|
175
177
|
[match, other.index]
|
176
178
|
when Array === match
|
@@ -182,32 +184,42 @@ class TSV
|
|
182
184
|
# through
|
183
185
|
new = {}
|
184
186
|
each do |key,values|
|
185
|
-
source_keys = match_source == :key ? key : values[
|
187
|
+
source_keys = match_source == :key ? key : values[match_source_position]
|
186
188
|
source_keys = [source_keys] unless Array === source_keys
|
187
189
|
other_keys = case
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
190
|
+
when index.nil?
|
191
|
+
source_keys
|
192
|
+
else
|
193
|
+
index.values_at(*source_keys).flatten.compact
|
194
|
+
end
|
195
|
+
|
193
196
|
other_keys = other_keys.collect do |other_key| match_index[other_key] end.flatten unless match_index.nil?
|
194
197
|
|
198
|
+
|
195
199
|
other_values = other_keys.collect do |other_key|
|
196
200
|
next unless other.include? other_key
|
197
201
|
new_fields.collect do |field|
|
198
202
|
if field == other.key_field
|
199
|
-
|
203
|
+
if type == :double
|
204
|
+
[other_key]
|
205
|
+
else
|
206
|
+
other_key
|
207
|
+
end
|
200
208
|
else
|
201
209
|
other[other_key][field]
|
202
210
|
end
|
203
211
|
end
|
204
212
|
end.compact
|
205
213
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
214
|
+
other_values = case
|
215
|
+
when type == :double
|
216
|
+
TSV.zip_fields(other_values).collect{|v| v.flatten.uniq}
|
217
|
+
else
|
218
|
+
TSV.zip_fields(other_values).collect{|v| v.flatten.first}
|
219
|
+
end
|
220
|
+
|
221
|
+
new_values = values + other_values
|
222
|
+
|
211
223
|
new[key] = new_values
|
212
224
|
end
|
213
225
|
|
@@ -232,7 +244,7 @@ class TSV
|
|
232
244
|
field_values[field] = []
|
233
245
|
}
|
234
246
|
|
235
|
-
if type == :double
|
247
|
+
if tsv.type == :double
|
236
248
|
tsv.through do |key,entry_values|
|
237
249
|
fields.zip(entry_values).each do |field,entry_field_values|
|
238
250
|
field_values[field].concat entry_field_values
|
data/lib/rbbt/util/tsv/parse.rb
CHANGED
@@ -86,7 +86,7 @@ class TSV
|
|
86
86
|
|
87
87
|
if key_field.nil?
|
88
88
|
key_pos = key
|
89
|
-
|
89
|
+
other_pos = fields
|
90
90
|
else
|
91
91
|
all_fields = [key_field].concat other_fields
|
92
92
|
|
@@ -158,7 +158,7 @@ class TSV
|
|
158
158
|
|
159
159
|
next if data.include?(id) and type != :flat
|
160
160
|
|
161
|
-
if
|
161
|
+
if other_pos.nil? or (fields == nil and type == :flat)
|
162
162
|
other_pos = (0..(parts.length - 1)).to_a
|
163
163
|
other_pos.delete key_pos
|
164
164
|
end
|
@@ -199,7 +199,7 @@ class TSV
|
|
199
199
|
id = ids.shift
|
200
200
|
ids.each do |id2| data[id2] = "__Ref:#{id}" end
|
201
201
|
|
202
|
-
if
|
202
|
+
if other_pos.nil? or (fields == nil and type == :flat)
|
203
203
|
other_pos = (0..(parts.length - 1)).to_a
|
204
204
|
other_pos.delete key_pos
|
205
205
|
end
|
@@ -252,6 +252,8 @@ class TSV
|
|
252
252
|
end
|
253
253
|
end
|
254
254
|
|
255
|
+
fields = nil if Fixnum === fields or (Array === fields and fields.select{|f| Fixnum === f}.any?)
|
256
|
+
fields ||= other_fields
|
255
257
|
[data, {:key_field => key_field, :fields => fields, :type => type, :case_insensitive => case_insensitive, :namespace => namespace, :datadir => options[:datadir], :identifiers => options[:identifiers], :cast => !!cast}]
|
256
258
|
end
|
257
259
|
|
data/lib/rbbt/util/tsv.rb
CHANGED
@@ -102,7 +102,7 @@ class TSV
|
|
102
102
|
@data = file.data
|
103
103
|
when Persistence::TSV === file
|
104
104
|
@data = file
|
105
|
-
%w(case_insensitive namespace datadir fields key_field type filename cast).each do |key|
|
105
|
+
%w(case_insensitive namespace identifiers datadir fields key_field type filename cast).each do |key|
|
106
106
|
if @data.respond_to?(key.to_sym) and self.respond_to?("#{key}=".to_sym)
|
107
107
|
self.send "#{key}=".to_sym, @data.send(key.to_sym)
|
108
108
|
end
|
@@ -145,7 +145,7 @@ class TSV
|
|
145
145
|
end
|
146
146
|
|
147
147
|
if not extra.nil?
|
148
|
-
%w(case_insensitive namespace datadir fields key_field type filename cast).each do |key|
|
148
|
+
%w(case_insensitive namespace identifiers datadir fields key_field type filename cast).each do |key|
|
149
149
|
if extra.include? key.to_sym
|
150
150
|
self.send("#{key}=".to_sym, extra[key.to_sym])
|
151
151
|
if @data.respond_to? "#{key}=".to_sym
|
data/lib/rbbt/util/workflow.rb
CHANGED
@@ -1,3 +1,90 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rbbt/util/rake'
|
3
|
+
|
1
4
|
module WorkFlow
|
5
|
+
module Runner
|
6
|
+
def data
|
7
|
+
$_workflow_prereq
|
8
|
+
end
|
9
|
+
|
10
|
+
def input
|
11
|
+
$_workflow_input
|
12
|
+
end
|
13
|
+
|
14
|
+
$_workflow_default_persistence = :string
|
15
|
+
def default_persistence
|
16
|
+
$_workflow_default_persistence
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_persistence=(type)
|
20
|
+
$_workflow_default_persistence = type
|
21
|
+
end
|
22
|
+
|
23
|
+
def step(step_name, options = nil)
|
24
|
+
dependencies, options = case
|
25
|
+
when ((String === options or Symbol === options) and %w(string marshal tsv tsv_string).include? options.to_s)
|
26
|
+
[nil, {:persistence_type => options}]
|
27
|
+
when Hash === options
|
28
|
+
[nil, options]
|
29
|
+
else
|
30
|
+
[options, {}]
|
31
|
+
end
|
32
|
+
|
33
|
+
options = Misc.add_defaults options, :persistence_type => default_persistence
|
34
|
+
persistence_type = Misc.process_options options, :persistence_type
|
35
|
+
dependencies = Misc.process_options options, :dependencies if options.include? :dependencies
|
36
|
+
|
37
|
+
re = Regexp.new(/(?:^|\/)#{Regexp.quote step_name.to_s}\/.*$/)
|
2
38
|
|
39
|
+
@last_step = nil unless defined? @last_step
|
40
|
+
@last_persistence_type = nil unless defined? @last_persistence_type
|
41
|
+
|
42
|
+
if dependencies.nil? && ! @last_step.nil?
|
43
|
+
dependencies = @last_step
|
44
|
+
end
|
45
|
+
@last_step = step_name
|
46
|
+
|
47
|
+
# Generate the Hash definition
|
48
|
+
rule_def = case
|
49
|
+
when dependencies.nil?
|
50
|
+
re
|
51
|
+
when String === dependencies || Symbol === dependencies
|
52
|
+
{re => lambda{|filename| filename.sub(step_name.to_s, dependencies.to_s) }}
|
53
|
+
when Array === dependencies
|
54
|
+
{re => lambda{|filename| dependencies.collect{|dep| filename.sub(step_name.to_s, dep.to_s) } }}
|
55
|
+
when Proc === dependencies
|
56
|
+
{re => dependencies}
|
57
|
+
end
|
58
|
+
|
59
|
+
@last_step = step_name
|
60
|
+
last_persistence_type, @last_persistence_type = @last_persistence_type, persistence_type
|
61
|
+
|
62
|
+
rule rule_def do |t|
|
63
|
+
Persistence.persist(t.name, "", persistence_type, :persistence_file => t.name) do
|
64
|
+
$_workflow_prereq = case
|
65
|
+
when (t.prerequisites.nil? or (Array === t.prerequisites and t.prerequisites.empty?))
|
66
|
+
nil
|
67
|
+
else
|
68
|
+
Persistence.persist(t.prerequisites.first, "", last_persistence_type, :persistence_file => t.prerequisites.first) do
|
69
|
+
raise "Error, this file should be produced already"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
yield
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.run(file = :default, workflow_input = nil, &block)
|
79
|
+
$_workflow_input = workflow_input
|
80
|
+
RakeHelper.run("Runtime", file) do
|
81
|
+
yield
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.load(wf_file, file = :default, workflow_input = nil)
|
86
|
+
$_workflow_input = workflow_input
|
87
|
+
RakeHelper.run(wf_file, file)
|
88
|
+
end
|
3
89
|
end
|
90
|
+
|
data/test/rbbt/util/test_R.rb
CHANGED
@@ -13,11 +13,6 @@ class TestPKGData < Test::Unit::TestCase
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def test_path
|
17
|
-
assert_equal File.join(Rbbt.datadir, 'Organism/Hsa'), Rbbt.files.Organism.Hsa
|
18
|
-
Rbbt.files.Organism.Hsa.identifiers.produce
|
19
|
-
end
|
20
|
-
|
21
16
|
def test_claim_proc
|
22
17
|
begin
|
23
18
|
assert_nil Rbbt.reclaim(Rbbt.files.foo)
|
@@ -6,9 +6,73 @@ require 'rbbt/util/workflow'
|
|
6
6
|
|
7
7
|
class TestWorkflow < Test::Unit::TestCase
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def workflow
|
10
|
+
TmpFile.with_file do |dir|
|
11
|
+
old_pdw = FileUtils.pwd
|
12
|
+
begin
|
13
|
+
FileUtils.mkdir dir
|
14
|
+
cd dir
|
15
|
+
yield dir
|
16
|
+
ensure
|
17
|
+
cd old_pdw
|
18
|
+
end
|
19
|
+
end
|
11
20
|
end
|
12
21
|
|
22
|
+
def _test_run
|
23
|
+
workflow do |dir|
|
24
|
+
WorkFlow.run do
|
25
|
+
file :foo do |t|
|
26
|
+
touch t.name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
assert File.exists? File.join(dir, 'foo')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def _test_step
|
34
|
+
jobid = 'jobid'
|
35
|
+
target_step = 'last'
|
36
|
+
workflow do |dir|
|
37
|
+
|
38
|
+
WorkFlow.run(File.join(target_step, jobid)) do
|
39
|
+
self.extend WorkFlow::Runner
|
40
|
+
|
41
|
+
step :first do
|
42
|
+
"Test"
|
43
|
+
end
|
44
|
+
|
45
|
+
step :last do
|
46
|
+
data.reverse
|
47
|
+
end
|
48
|
+
end
|
49
|
+
assert File.exists? File.join(dir, target_step, 'jobid')
|
50
|
+
assert_equal 'tseT', Open.read(File.join(dir, target_step, 'jobid'))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_input
|
55
|
+
jobid = 'jobid'
|
56
|
+
target_step = 'last'
|
57
|
+
message = "Message"
|
58
|
+
|
59
|
+
workflow do |dir|
|
60
|
+
|
61
|
+
WorkFlow.run(File.join(target_step, jobid), message) do
|
62
|
+
self.extend WorkFlow::Runner
|
63
|
+
|
64
|
+
step :first, :marshal do
|
65
|
+
input
|
66
|
+
end
|
67
|
+
|
68
|
+
step :last do
|
69
|
+
data.reverse
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
assert File.exists? File.join(dir, target_step, 'jobid')
|
74
|
+
assert_equal message.reverse, Open.read(File.join(dir, target_step, 'jobid'))
|
75
|
+
end
|
76
|
+
end
|
13
77
|
end
|
14
78
|
|
@@ -206,9 +206,6 @@ row1 e
|
|
206
206
|
row2 E
|
207
207
|
EOF
|
208
208
|
|
209
|
-
|
210
|
-
require 'rbbt/sources/organism'
|
211
|
-
|
212
209
|
Rbbt.claim "data", StringIO.new(content1), "Test1"
|
213
210
|
Rbbt.claim "data", StringIO.new(content2), "Test2"
|
214
211
|
Rbbt.claim "identifiers", StringIO.new(content_index), "Test2"
|
@@ -218,7 +215,7 @@ row2 E
|
|
218
215
|
tsv1 = Rbbt.files.Test1.data.tsv :double, :sep => /\s+/
|
219
216
|
tsv2 = Rbbt.files.Test2.data.tsv :double, :sep => /\s+/
|
220
217
|
|
221
|
-
tsv2.identifiers = Rbbt.files.Test2.identifiers
|
218
|
+
tsv2.identifiers = Rbbt.files.Test2.identifiers.produce
|
222
219
|
|
223
220
|
tsv1.attach tsv2, "OtherID", :in_namespace => false
|
224
221
|
|
@@ -51,7 +51,6 @@ row3 A a|B Id4
|
|
51
51
|
TmpFile.with_file(content) do |filename|
|
52
52
|
tsv = TSV.new(File.open(filename), :sep => /\s+/, :key => "OtherID", :persistence => true)
|
53
53
|
index = tsv.index(:case_insensitive => false, :order => true)
|
54
|
-
ddd index
|
55
54
|
assert_equal "Id1", index['a'].first
|
56
55
|
assert_equal "Id3", index['A'].first
|
57
56
|
assert_equal "OtherID", index.fields.first
|
@@ -67,14 +66,16 @@ row3 A a|B Id4
|
|
67
66
|
|
68
67
|
#{{{ Test Attach
|
69
68
|
|
70
|
-
def
|
69
|
+
def test_smart_merge_single
|
71
70
|
content1 =<<-EOF
|
71
|
+
#: :case_insensitive=false
|
72
72
|
#Id ValueA ValueB
|
73
73
|
row1 a|aa|aaa b
|
74
74
|
row2 A B
|
75
75
|
EOF
|
76
76
|
|
77
77
|
content2 =<<-EOF
|
78
|
+
#: :case_insensitive=false
|
78
79
|
#ValueC ValueB OtherID
|
79
80
|
c|cc|ccc b Id1|Id2
|
80
81
|
C B Id3
|
@@ -91,9 +92,10 @@ C B Id3
|
|
91
92
|
|
92
93
|
tsv1 = tsv1.smart_merge tsv2, "ValueB"
|
93
94
|
|
94
|
-
assert_equal "C", tsv1["row2"]["ValueC"]
|
95
|
-
assert %w(c cc ccc).include? tsv1["row1"]["ValueC"]
|
96
|
-
|
95
|
+
assert_equal "C", tsv1["row2"]["ValueC"].first
|
96
|
+
assert %w(c cc ccc).include? tsv1["row1"]["ValueC"].first
|
97
|
+
ddd tsv1
|
98
|
+
assert_equal %w(Id1 Id2), tsv1["row1"]["OtherID"].sort
|
97
99
|
end
|
98
100
|
|
99
101
|
def test_index_to_key
|
@@ -49,6 +49,21 @@ row2 A B
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
def test_unven_flat
|
53
|
+
content =<<-EOF
|
54
|
+
row1 a b
|
55
|
+
row2 A B C
|
56
|
+
EOF
|
57
|
+
|
58
|
+
TmpFile.with_file(content) do |filename|
|
59
|
+
data = {}
|
60
|
+
data, extra = TSV.parse(File.open(filename), :type => :flat, :sep => /\s+/)
|
61
|
+
assert data["row2"].include? "C"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
|
52
67
|
def test_options_line
|
53
68
|
content =<<-EOF
|
54
69
|
#: :sep=/\\s+/#:case_insensitive=true
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbbt-util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 2.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Miguel Vazquez
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-10 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -93,6 +93,7 @@ email: miguel.vazquez@fdi.ucm.es
|
|
93
93
|
executables:
|
94
94
|
- tsv.rb
|
95
95
|
- tchash.rb
|
96
|
+
- workflow.rb
|
96
97
|
extensions: []
|
97
98
|
|
98
99
|
extra_rdoc_files:
|
@@ -160,6 +161,7 @@ files:
|
|
160
161
|
- test/test_rbbt.rb
|
161
162
|
- bin/tsv.rb
|
162
163
|
- bin/tchash.rb
|
164
|
+
- bin/workflow.rb
|
163
165
|
has_rdoc: true
|
164
166
|
homepage: http://github.com/mikisvaz/rbbt-util
|
165
167
|
licenses: []
|