scout-gear 7.3.0 → 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +44 -16
  3. data/Rakefile +6 -1
  4. data/VERSION +1 -1
  5. data/bin/scout +21 -7
  6. data/doc/lib/scout/path.md +35 -0
  7. data/doc/lib/scout/workflow/task.md +13 -0
  8. data/lib/rbbt-scout.rb +1 -0
  9. data/lib/scout/cmd.rb +24 -25
  10. data/lib/scout/concurrent_stream.rb +59 -39
  11. data/lib/scout/config.rb +1 -1
  12. data/lib/scout/exceptions.rb +10 -0
  13. data/lib/scout/log/color.rb +15 -12
  14. data/lib/scout/log/progress/report.rb +8 -6
  15. data/lib/scout/log/progress/util.rb +61 -54
  16. data/lib/scout/log/progress.rb +1 -1
  17. data/lib/scout/log/trap.rb +107 -0
  18. data/lib/scout/log.rb +115 -52
  19. data/lib/scout/meta_extension.rb +47 -6
  20. data/lib/scout/misc/digest.rb +12 -3
  21. data/lib/scout/misc/format.rb +24 -7
  22. data/lib/scout/misc/insist.rb +1 -1
  23. data/lib/scout/misc/monitor.rb +22 -0
  24. data/lib/scout/misc/system.rb +58 -0
  25. data/lib/scout/named_array.rb +73 -3
  26. data/lib/scout/offsite/ssh.rb +171 -0
  27. data/lib/scout/offsite/step.rb +83 -0
  28. data/lib/scout/offsite/sync.rb +55 -0
  29. data/lib/scout/offsite.rb +3 -0
  30. data/lib/scout/open/lock/lockfile.rb +587 -0
  31. data/lib/scout/open/lock.rb +9 -2
  32. data/lib/scout/open/remote.rb +16 -1
  33. data/lib/scout/open/stream.rb +146 -83
  34. data/lib/scout/open/util.rb +22 -3
  35. data/lib/scout/open.rb +5 -4
  36. data/lib/scout/path/find.rb +24 -11
  37. data/lib/scout/path/util.rb +40 -0
  38. data/lib/scout/persist/serialize.rb +19 -6
  39. data/lib/scout/persist.rb +29 -13
  40. data/lib/scout/resource/path.rb +57 -0
  41. data/lib/scout/resource/produce.rb +0 -8
  42. data/lib/scout/resource/util.rb +12 -5
  43. data/lib/scout/tmpfile.rb +7 -8
  44. data/lib/scout/tsv/attach.rb +177 -0
  45. data/lib/scout/tsv/change_id.rb +40 -0
  46. data/lib/scout/tsv/dumper.rb +74 -46
  47. data/lib/scout/tsv/index.rb +85 -87
  48. data/lib/scout/tsv/open.rb +160 -85
  49. data/lib/scout/tsv/parser.rb +142 -80
  50. data/lib/scout/tsv/path.rb +1 -2
  51. data/lib/scout/tsv/persist/adapter.rb +15 -45
  52. data/lib/scout/tsv/persist/fix_width_table.rb +3 -0
  53. data/lib/scout/tsv/persist/tokyocabinet.rb +6 -1
  54. data/lib/scout/tsv/persist.rb +4 -0
  55. data/lib/scout/tsv/stream.rb +204 -0
  56. data/lib/scout/tsv/transformer.rb +152 -0
  57. data/lib/scout/tsv/traverse.rb +96 -92
  58. data/lib/scout/tsv/util/filter.rb +9 -0
  59. data/lib/scout/tsv/util/reorder.rb +81 -0
  60. data/lib/scout/tsv/util/select.rb +78 -33
  61. data/lib/scout/tsv/util/unzip.rb +86 -0
  62. data/lib/scout/tsv/util.rb +60 -11
  63. data/lib/scout/tsv.rb +34 -4
  64. data/lib/scout/work_queue/socket.rb +6 -1
  65. data/lib/scout/work_queue/worker.rb +5 -2
  66. data/lib/scout/work_queue.rb +51 -20
  67. data/lib/scout/workflow/definition.rb +23 -3
  68. data/lib/scout/workflow/deployment/orchestrator.rb +245 -0
  69. data/lib/scout/workflow/deployment.rb +1 -0
  70. data/lib/scout/workflow/step/dependencies.rb +56 -10
  71. data/lib/scout/workflow/step/file.rb +5 -0
  72. data/lib/scout/workflow/step/info.rb +40 -7
  73. data/lib/scout/workflow/step/load.rb +1 -1
  74. data/lib/scout/workflow/step/provenance.rb +9 -7
  75. data/lib/scout/workflow/step/status.rb +43 -0
  76. data/lib/scout/workflow/step.rb +160 -49
  77. data/lib/scout/workflow/task/dependencies.rb +114 -0
  78. data/lib/scout/workflow/task/inputs.rb +40 -32
  79. data/lib/scout/workflow/task.rb +38 -102
  80. data/lib/scout/workflow/usage.rb +48 -18
  81. data/lib/scout/workflow.rb +4 -2
  82. data/lib/scout-gear.rb +2 -0
  83. data/lib/scout.rb +6 -0
  84. data/scout-gear.gemspec +52 -23
  85. data/scout_commands/doc +37 -0
  86. data/scout_commands/find +1 -0
  87. data/scout_commands/offsite +30 -0
  88. data/scout_commands/update +29 -0
  89. data/scout_commands/workflow/info +15 -3
  90. data/scout_commands/workflow/install +102 -0
  91. data/scout_commands/workflow/task +57 -9
  92. data/test/scout/offsite/test_ssh.rb +15 -0
  93. data/test/scout/offsite/test_step.rb +33 -0
  94. data/test/scout/offsite/test_sync.rb +36 -0
  95. data/test/scout/offsite/test_task.rb +0 -0
  96. data/test/scout/open/test_stream.rb +60 -58
  97. data/test/scout/path/test_find.rb +10 -1
  98. data/test/scout/resource/test_path.rb +6 -0
  99. data/test/scout/resource/test_produce.rb +15 -0
  100. data/test/scout/test_meta_extension.rb +25 -0
  101. data/test/scout/test_named_array.rb +24 -0
  102. data/test/scout/test_persist.rb +9 -2
  103. data/test/scout/test_tsv.rb +229 -2
  104. data/test/scout/test_work_queue.rb +65 -41
  105. data/test/scout/tsv/persist/test_tokyocabinet.rb +29 -1
  106. data/test/scout/tsv/test_attach.rb +227 -0
  107. data/test/scout/tsv/test_change_id.rb +98 -0
  108. data/test/scout/tsv/test_dumper.rb +1 -1
  109. data/test/scout/tsv/test_index.rb +49 -3
  110. data/test/scout/tsv/test_open.rb +160 -2
  111. data/test/scout/tsv/test_parser.rb +33 -2
  112. data/test/scout/tsv/test_persist.rb +2 -0
  113. data/test/scout/tsv/test_stream.rb +200 -0
  114. data/test/scout/tsv/test_transformer.rb +120 -0
  115. data/test/scout/tsv/test_traverse.rb +88 -3
  116. data/test/scout/tsv/test_util.rb +1 -0
  117. data/test/scout/tsv/util/test_reorder.rb +94 -0
  118. data/test/scout/tsv/util/test_select.rb +25 -11
  119. data/test/scout/tsv/util/test_unzip.rb +112 -0
  120. data/test/scout/work_queue/test_socket.rb +0 -1
  121. data/test/scout/workflow/deployment/test_orchestrator.rb +272 -0
  122. data/test/scout/workflow/step/test_dependencies.rb +68 -0
  123. data/test/scout/workflow/step/test_info.rb +18 -0
  124. data/test/scout/workflow/step/test_status.rb +30 -0
  125. data/test/scout/workflow/task/test_dependencies.rb +355 -0
  126. data/test/scout/workflow/task/test_inputs.rb +67 -14
  127. data/test/scout/workflow/test_definition.rb +18 -0
  128. data/test/scout/workflow/test_documentation.rb +24 -0
  129. data/test/scout/workflow/test_step.rb +112 -3
  130. data/test/scout/workflow/test_task.rb +0 -151
  131. data/test/scout/workflow/test_usage.rb +33 -6
  132. data/test/test_scout.rb +9 -0
  133. metadata +100 -8
  134. data/scout_commands/workflow/task_old +0 -706
@@ -0,0 +1,98 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ require 'scout/tsv'
5
+ class TestChangeID < Test::Unit::TestCase
6
+ def test_simple_reorder
7
+ content1 =<<-EOF
8
+ #: :sep=" "
9
+ #ID ValueA ValueB
10
+ row1 A1|A11 B1|B11
11
+ row2 A2|A22 B2|B22
12
+ EOF
13
+
14
+ tsv = TSV.open StringIO.new(content1)
15
+
16
+ res = tsv.change_key "ValueA", keep: true
17
+ assert_equal ["row1"], res["A1"]["ID"]
18
+ assert_equal ["row1"], res["A11"]["ID"]
19
+ assert_equal ["row2"], res["A2"]["ID"]
20
+
21
+ res = tsv.change_key "ValueA", keep: false, one2one: true
22
+ assert_equal ["B1"], res["A1"]["ValueB"]
23
+ assert_equal ["B11"], res["A11"]["ValueB"]
24
+ end
25
+
26
+ def test_simple_reorder_file
27
+ content1 =<<-EOF
28
+ #: :sep=" "
29
+ #ID ValueA ValueB
30
+ row1 A1|A11 B1|B11
31
+ row2 A2|A22 B2|B22
32
+ EOF
33
+
34
+ TmpFile.with_file(content1) do |file1|
35
+ res = TSV.change_key file1, "ValueA", keep: true
36
+ assert_equal ["row1"], res["A1"]["ID"]
37
+ assert_equal ["row1"], res["A11"]["ID"]
38
+ assert_equal ["row2"], res["A2"]["ID"]
39
+ assert_equal ["B1","B11"], res["A1"]["ValueB"]
40
+
41
+ res = TSV.change_key file1, "ValueA", one2one: true, keep: true
42
+ assert_equal ["row1"], res["A1"]["ID"]
43
+ assert_equal ["row1"], res["A11"]["ID"]
44
+ assert_equal ["row2"], res["A2"]["ID"]
45
+ assert_equal ["B1"], res["A1"]["ValueB"]
46
+ end
47
+ end
48
+
49
+ def test_change_key_identifiers
50
+ content1 =<<-EOF
51
+ #: :sep=" "
52
+ #ID ValueA ValueB
53
+ row1 A1|A11 B1|B11
54
+ row2 A2|A22 B2|B22
55
+ EOF
56
+
57
+ identifiers_content =<<-EOF
58
+ #: :sep=" "
59
+ #ID ValueC ValueD
60
+ row1 C1|C11 D1|D11
61
+ row2 C2|C22 D2|D22
62
+ EOF
63
+
64
+
65
+ tsv = TSV.open StringIO.new(content1)
66
+ identifiers = TSV.open StringIO.new(identifiers_content)
67
+
68
+ res = tsv.change_key "ValueC", identifiers: identifiers, keep: true
69
+ assert_equal ["row1"], res["C1"]["ID"]
70
+ assert_equal ["row1"], res["C11"]["ID"]
71
+ assert_equal ["row2"], res["C2"]["ID"]
72
+ end
73
+
74
+ def test_change_id_identifiers
75
+ content1 =<<-EOF
76
+ #: :sep=" "
77
+ #ID ValueA ValueB
78
+ row1 A1|A11 B1|B11
79
+ row2 A2|A22 B2|B22
80
+ EOF
81
+
82
+ identifiers_content =<<-EOF
83
+ #: :sep=" "
84
+ #ID ValueC ValueD
85
+ row1 C1|C11 D1|D11
86
+ row2 C2|C22 D2|D22
87
+ EOF
88
+
89
+
90
+ tsv = TSV.open StringIO.new(content1)
91
+ identifiers = TSV.open StringIO.new(identifiers_content)
92
+
93
+ res = tsv.change_id "ValueA", "ValueC", identifiers: identifiers
94
+ assert_equal ["C1","C11"], res["row1"]["ValueC"]
95
+ assert_equal ["C2","C22"], res["row2"]["ValueC"]
96
+ end
97
+ end
98
+
@@ -37,7 +37,7 @@ a\t1|11\t2|22
37
37
  end
38
38
 
39
39
  assert_raise ScoutException do
40
- dumper.stream.read
40
+ TSV.open(dumper.stream, bar: true)
41
41
  end
42
42
  end
43
43
  end
@@ -43,24 +43,49 @@ row2 a b id3
43
43
  end
44
44
  end
45
45
 
46
+ def test_index_from_flat
47
+ content =<<-'EOF'
48
+ #: :sep=" "#:type=:flat
49
+ #Id ValueA
50
+ row1 a aa aaa
51
+ row2 b bb bbb
52
+ EOF
53
+
54
+ TmpFile.with_file(content) do |filename|
55
+ index = TSV.index(filename, :target => "Id")
56
+ assert_equal "row1", index["aa"]
57
+ end
58
+ end
59
+
46
60
  def test_from_tsv
47
61
  content =<<-'EOF'
48
62
  #: :sep=/\s+/#:type=:double#:merge=:concat
49
63
  #Id ValueA ValueB OtherID
50
64
  row1 a|aa|aaa b Id1|Id2
51
- row2 A B Id3|a
65
+ row2 A|b B Id3|a
52
66
  row2 a b id3
53
67
  EOF
54
68
 
55
69
  TmpFile.with_file(content) do |filename|
56
70
  tsv = TSV.open(filename)
71
+ index = TSV.index(tsv, :target => "ValueB")
72
+ assert_equal 'b', index["a"]
73
+ assert_equal 'B', index["B"]
74
+ assert_equal 'b', index["b"]
75
+
76
+ index = tsv.index(:target => "ValueB")
77
+ assert_equal 'b', index["a"]
78
+ assert_equal 'B', index["B"]
79
+ assert_equal 'b', index["b"]
80
+
81
+
57
82
  index = TSV.index(tsv, :target => "ValueB", :fields => "OtherID")
58
83
  assert_equal 'B', index["a"]
59
84
  assert_nil index["B"]
60
85
 
61
86
  index = tsv.index(:target => "ValueB", :fields => "OtherID")
62
87
  assert_equal 'B', index["a"]
63
- assert_nil index["B"]
88
+ assert_nil index["B"]
64
89
  end
65
90
  end
66
91
 
@@ -74,7 +99,7 @@ row2 A B Id3|a
74
99
  row2 a b id3
75
100
  EOF
76
101
  tsv = TmpFile.with_file(content) do |filename|
77
- index = TSV.index(filename, :target => "ValueB", :persist => true)
102
+ index = TSV.index(filename, :target => "ValueB", :persist => true, bar: true)
78
103
  assert_equal 'b', index["row1"]
79
104
  assert_equal 'b', index["a"]
80
105
  assert_equal 'b', index["aaa"]
@@ -107,6 +132,27 @@ g: ____
107
132
  end
108
133
  end
109
134
 
135
+ def test_pos_index
136
+ data =<<-EOF
137
+ # 012345678901234567890
138
+ #ID:Range
139
+ a: ______
140
+ b: ______
141
+ c: _______
142
+ d: ____
143
+ e: ______
144
+ f: ___
145
+ g: ____
146
+ EOF
147
+ TmpFile.with_file(data) do |datafile|
148
+ tsv = load_segment_data(datafile)
149
+ f = tsv.pos_index("Start", :persist => true)
150
+
151
+ assert_equal %w(), f[0].sort
152
+ assert_equal %w(a c d e), f[(2..4)].sort
153
+ end
154
+ end
155
+
110
156
  def test_range_index_persistent
111
157
  data =<<-EOF
112
158
  # 012345678901234567890
@@ -1,9 +1,167 @@
1
1
  require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
2
  require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
3
 
4
+ require 'scout/tsv'
4
5
  class TestOpenTraverse < Test::Unit::TestCase
5
- def test_true
6
- assert true
6
+ def test_array
7
+ num_lines = 100
8
+ lines = num_lines.times.collect{|i| "line-#{i}" }
9
+
10
+ r = TSV.traverse lines, :into => [] do |l|
11
+ l + "-" + Process.pid.to_s
12
+ end
13
+
14
+ assert_equal num_lines, r.length
15
+ end
16
+
17
+ def test_array_cpus
18
+ num_lines = 1000
19
+ lines = num_lines.times.collect{|i| "line-#{i}" }
20
+
21
+ r = TSV.traverse lines, :into => [], :cpus => 2 do |l|
22
+ l + "-" + Process.pid.to_s
23
+ end
24
+
25
+ assert_equal num_lines, r.length
26
+ assert_equal 2, r.collect{|l| l.split("-").last}.uniq.length
27
+ end
28
+
29
+ def test_tsv_cpus
30
+ num_lines = 10000
31
+ lines = num_lines.times.collect{|i| "line-#{i}" }
32
+
33
+ tsv = TSV.setup({}, key_field: "Line", :fields => %w(Prefix Number), :type => :list)
34
+ lines.each do |line|
35
+ tsv[line] = ["LINE", line.split("-").last]
36
+ end
37
+
38
+ r = TSV.traverse tsv, :into => [], :cpus => 2, :bar => {desc: "Process", severity: 0} do |l,v|
39
+ pre, num = v
40
+ pre + "-" + num.to_s + "-" + Process.pid.to_s
41
+ end
42
+
43
+ assert_equal num_lines, r.length
44
+ assert_equal 2, r.collect{|l| l.split("-").last}.uniq.length
45
+ assert_equal "LINE", r.collect{|l| l.split("-").first}.first
46
+ end
47
+
48
+ def test_into_stream
49
+ num_lines = 100
50
+ lines = num_lines.times.collect{|i| "line-#{i}" }
51
+
52
+ r = TSV.traverse lines, :into => :stream do |l|
53
+ l + "-" + Process.pid.to_s
54
+ end
55
+
56
+ assert_equal num_lines, r.read.split("\n").length
57
+ end
58
+
59
+ def test_into_stream_error
60
+ num_lines = 100
61
+ lines = num_lines.times.collect{|i| "line-#{i}" }
62
+
63
+ assert_raise ScoutException do
64
+ Log.with_severity 7 do
65
+ i = 0
66
+ r = TSV.traverse lines, :into => :stream, cpus: 3 do |l|
67
+ raise ScoutException if i > 10
68
+ i += 1
69
+ l + "-" + Process.pid.to_s
70
+ end
71
+
72
+ r.read
73
+ end
74
+ end
75
+ end
76
+
77
+ def test_into_dumper_error
78
+ num_lines = 100
79
+ lines = num_lines.times.collect{|i| "line-#{i}" }
80
+
81
+ assert_raise ScoutException do
82
+ i = 0
83
+ Log.with_severity 7 do
84
+ dumper = TSV::Dumper.new :key_field => "Key", :fields => ["Value"], :type => :single
85
+ dumper.init
86
+ dumper = TSV.traverse lines, :into => dumper, :cpus => 3 do |l|
87
+ raise ScoutException if i > 10
88
+ i += 1
89
+ value = l + "-" + Process.pid.to_s
90
+
91
+ [i.to_s, value]
92
+ end
93
+ ppp dumper.stream.read
94
+ end
95
+ end
96
+ end
97
+
98
+ def test_traverse_line
99
+ text=<<-EOF
100
+ #: :sep=" "
101
+ #Row LabelA LabelB LabelC
102
+ row1 A B C
103
+ row1 a b c
104
+ row2 AA BB CC
105
+ row2 aa bb cc
106
+ EOF
107
+
108
+ TmpFile.with_file(text) do |file|
109
+ lines = Open.traverse file, :type => :line, :into => [] do |line|
110
+ line
111
+ end
112
+ assert_include lines, "row2 AA BB CC"
113
+ end
114
+ end
115
+
116
+ def test_collapse_stream
117
+ text=<<-EOF
118
+ #: :sep=" "
119
+ #Row LabelA LabelB LabelC
120
+ row1 A B C
121
+ row1 a b c
122
+ row2 AA BB CC
123
+ row2 aa bb cc
124
+ EOF
125
+
126
+ s = StringIO.new text
127
+ collapsed = TSV.collapse_stream(s)
128
+ tsv = TSV.open collapsed
129
+ assert_equal ["A", "a"], tsv["row1"][0]
130
+ assert_equal ["BB", "bb"], tsv["row2"][1]
131
+ end
132
+
133
+ def test_cpus_error_dumper
134
+ num_lines = 100
135
+ lines = num_lines.times.collect{|i| "line-#{i}" }
136
+
137
+ dumper = TSV::Dumper.new :key_field => "Key", :fields => ["Field"], type: :single
138
+ dumper.init
139
+ assert_raise ScoutException do
140
+ Log.with_severity 0 do
141
+ i = 0
142
+ TSV.traverse lines, :into => dumper, cpus: 3 do |l|
143
+ raise ScoutException if i > 10
144
+ i += 1
145
+ [Process.pid.to_s, l + "-" + Process.pid.to_s]
146
+ end
147
+
148
+ end
149
+ ppp dumper.stream.read
150
+ end
151
+ end
152
+
153
+ def test_step_travese_cpus
154
+
155
+ size = 1000
156
+ step = Step.new tmpdir.step[__method__] do
157
+ lines = size.times.collect{|i| "line-#{i}" }
158
+ Open.traverse lines, :type => :array, :into => :stream, :cpus => 3 do |line|
159
+ line.reverse
160
+ end
161
+ end
162
+ step.type = :array
163
+
164
+ assert_equal size, step.run.length
7
165
  end
8
166
  end
9
167
 
@@ -119,6 +119,20 @@ k a|A b|B
119
119
  assert_equal [%w(b B), %w(k)], tsv['k']
120
120
  end
121
121
 
122
+ def test_parse_flat
123
+ content =<<-EOF
124
+ #: :sep=" "#:type=:flat
125
+ #Key ValueA
126
+ row1 a aa aaa
127
+ row2 b bb bbb
128
+ EOF
129
+
130
+ tsv = TSV.open(content)
131
+ assert_equal %w(a aa aaa), tsv["row1"]
132
+ tsv = TSV.open(content, :fields => ["ValueA"])
133
+ assert_equal %w(a aa aaa), tsv["row1"]
134
+ end
135
+
122
136
  def test_parse_key
123
137
  content =<<-EOF
124
138
  #: :sep=" "#:type=:double
@@ -172,6 +186,25 @@ k a|A b|B
172
186
  assert_equal [["k", [%w(b B)]]], values
173
187
  end
174
188
 
189
+ def test_parser_traverse_all
190
+ content =<<-EOF
191
+ Key ValueA ValueB
192
+ k a|A b|B
193
+ EOF
194
+ content = StringIO.new content
195
+
196
+ parser = TSV::Parser.new content, sep: " ", header_hash: ''
197
+
198
+ assert_equal "Key", parser.key_field
199
+
200
+ values = []
201
+ parser.traverse key_field: "ValueA", fields: :all, type: :double do |k,v|
202
+ values << v
203
+ end
204
+
205
+ assert_include values.flatten, 'a'
206
+ end
207
+
175
208
 
176
209
  def test_parse_persist_serializer
177
210
  content =<<-EOF
@@ -192,7 +225,5 @@ k 1 2
192
225
  TSV.parse content, sep: " ", header_hash: '', data: data, cast: :to_i, type: :list, serializer: :float_array
193
226
  assert_equal [1.0, 2.0], data["k"]
194
227
  end
195
-
196
228
  end
197
-
198
229
  end
@@ -29,6 +29,8 @@ row2 a a id3
29
29
  end
30
30
  end
31
31
 
32
+ assert_include tsv.keys, 'row1'
33
+ assert_include tsv.keys, 'row2'
32
34
 
33
35
  assert_nothing_raised do
34
36
  tsv = Persist.persist("TEST Persist TSV", :tsv) do
@@ -0,0 +1,200 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ require 'scout/tsv'
5
+ class TestTSVStream < Test::Unit::TestCase
6
+ def test_paste_stream
7
+ text1=<<-EOF
8
+ #: :sep=" "
9
+ #Row LabelA LabelB LabelC
10
+ row1 A B C
11
+ row2 AA BB CC
12
+ row3 AAA BBB CCC
13
+ EOF
14
+
15
+ text2=<<-EOF
16
+ #: :sep=" "
17
+ #Row Labela Labelb
18
+ row1 a b
19
+ row2 aa bb
20
+ row3 aaa bbb
21
+ EOF
22
+
23
+ text3=<<-EOF
24
+ #: :sep=" "
25
+ #Row LabelC
26
+ row1 c
27
+ row2 cc
28
+ row3 ccc
29
+ EOF
30
+
31
+ s1 = StringIO.new text1
32
+ s2 = StringIO.new text2
33
+ s3 = StringIO.new text3
34
+ tsv = TSV.open TSV.paste_streams([s1,s2,s3], :sep => " ", :type => :list)
35
+ assert_equal ["A", "B", "C", "a", "b", "c"], tsv["row1"]
36
+ assert_equal ["AA", "BB", "CC", "aa", "bb", "cc"], tsv["row2"]
37
+ assert_equal ["AAA", "BBB", "CCC", "aaa", "bbb", "ccc"], tsv["row3"]
38
+ end
39
+
40
+ def test_paste_stream_sort
41
+ text1=<<-EOF
42
+ #: :sep=" "
43
+ #Row LabelA LabelB LabelC
44
+ row2 AA BB CC
45
+ row1 A B C
46
+ row3 AAA BBB CCC
47
+ EOF
48
+
49
+ text2=<<-EOF
50
+ #: :sep=" "
51
+ #Row Labela Labelb
52
+ row1 a b
53
+ row3 aaa bbb
54
+ row2 aa bb
55
+ EOF
56
+
57
+ text3=<<-EOF
58
+ #: :sep=" "
59
+ #Row Labelc
60
+ row3 ccc
61
+ row1 c
62
+ row2 cc
63
+ EOF
64
+
65
+ s1 = StringIO.new text1
66
+ s2 = StringIO.new text2
67
+ s3 = StringIO.new text3
68
+ tsv = TSV.open TSV.paste_streams([s1,s2,s3], :sep => " ", :type => :list, :sort => true)
69
+ assert_equal "Row", tsv.key_field
70
+ assert_equal %w(LabelA LabelB LabelC Labela Labelb Labelc), tsv.fields
71
+ assert_equal ["A", "B", "C", "a", "b", "c"], tsv["row1"]
72
+ assert_equal ["AA", "BB", "CC", "aa", "bb", "cc"], tsv["row2"]
73
+ assert_equal ["AAA", "BBB", "CCC", "aaa", "bbb", "ccc"], tsv["row3"]
74
+ end
75
+
76
+ def test_paste_stream_missing_2
77
+ text1=<<-EOF
78
+ #: :sep=" "
79
+ #Row LabelA LabelB LabelC
80
+ row2 AA BB CC
81
+ row1 A B C
82
+ EOF
83
+
84
+ text2=<<-EOF
85
+ #: :sep=" "
86
+ #Row Labela Labelb
87
+ row2 aa bb
88
+ EOF
89
+
90
+ text3=<<-EOF
91
+ #: :sep=" "
92
+ #Row Labelc
93
+ row3 ccc
94
+ row2 cc
95
+ EOF
96
+
97
+ s1 = StringIO.new text1
98
+ s2 = StringIO.new text2
99
+ s3 = StringIO.new text3
100
+ tsv = TSV.open TSV.paste_streams([s1,s2,s3], :sep => " ", :type => :list, :sort => true)
101
+ assert_equal "Row", tsv.key_field
102
+ assert_equal %w(LabelA LabelB LabelC Labela Labelb Labelc), tsv.fields
103
+ assert_equal ["A", "B", "C", "", "", ""], tsv["row1"]
104
+ assert_equal ["AA", "BB", "CC", "aa", "bb", "cc"], tsv["row2"]
105
+ assert_equal ["", "", "", "", "", "ccc"], tsv["row3"]
106
+ end
107
+
108
+ def test_paste_stream_missing
109
+ text1=<<-EOF
110
+ #: :sep=" "
111
+ #Row LabelA LabelB LabelC
112
+ row2 AA BB CC
113
+ row1 A B C
114
+ EOF
115
+
116
+ text2=<<-EOF
117
+ #: :sep=" "
118
+ #Row Labela Labelb
119
+ row2 aa bb
120
+ EOF
121
+
122
+ text3=<<-EOF
123
+ #: :sep=" "
124
+ #Row Labelc
125
+ row3 ccc
126
+ row2 cc
127
+ EOF
128
+
129
+ s1 = StringIO.new text1
130
+ s2 = StringIO.new text2
131
+ s3 = StringIO.new text3
132
+ tsv = TSV.open TSV.paste_streams([s1,s2,s3], :sep => " ", :type => :list, :sort => true)
133
+ assert_equal "Row", tsv.key_field
134
+ assert_equal %w(LabelA LabelB LabelC Labela Labelb Labelc), tsv.fields
135
+ assert_equal ["A", "B", "C", "", "", ""], tsv["row1"]
136
+ assert_equal ["AA", "BB", "CC", "aa", "bb", "cc"], tsv["row2"]
137
+ assert_equal ["", "", "", "", "", "ccc"], tsv["row3"]
138
+ end
139
+
140
+ def test_paste_stream_missing_3
141
+ text1=<<-EOF
142
+ #: :sep=" "
143
+ #Row LabelA LabelB LabelC
144
+ row2 AA BB CC
145
+ row1 A B C
146
+ EOF
147
+
148
+ text2=<<-EOF
149
+ #: :sep=" "
150
+ #Row Labelc
151
+ EOF
152
+
153
+ s1 = StringIO.new text1
154
+ s2 = StringIO.new text2
155
+ tsv = TSV.open TSV.paste_streams([s1,s2], :sep => " ", :type => :list, :sort => true)
156
+ assert_equal "Row", tsv.key_field
157
+ assert_equal %w(LabelA LabelB LabelC Labelc), tsv.fields
158
+ assert_equal ["A", "B", "C", ""], tsv["row1"]
159
+ assert_equal ["AA", "BB", "CC", ""], tsv["row2"]
160
+ end
161
+
162
+ def test_paste_stream_same_field
163
+ text1=<<-EOF
164
+ #: :sep=" "
165
+ #Row LabelA
166
+ row1 A
167
+ row2 AA
168
+ EOF
169
+
170
+ text2=<<-EOF
171
+ #: :sep=" "
172
+ #Row LabelA
173
+ row2 AAA
174
+ EOF
175
+
176
+ s1 = StringIO.new text1
177
+ s2 = StringIO.new text2
178
+ tsv = TSV.open TSV.paste_streams([s1,s2], :sep => " ", :type => :double, :sort => false, :same_fields => true)
179
+ assert_equal "Row", tsv.key_field
180
+ assert_equal ["AA", "AAA"], tsv["row2"][0]
181
+ end
182
+
183
+ def test_paste_stream_nohead
184
+ text1=<<-EOF
185
+ row1\tA
186
+ row2\tAA
187
+ EOF
188
+
189
+ text2=<<-EOF
190
+ row2\tAAA
191
+ EOF
192
+
193
+ s1 = StringIO.new text1
194
+ s2 = StringIO.new text2
195
+ tsv = TSV.open TSV.paste_streams([s1,s2], :type => :double, :sort => false, :same_fields => true)
196
+ assert_equal ["AA", "AAA"], tsv["row2"][0]
197
+ end
198
+
199
+ end
200
+