tb 0.1 → 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.
Files changed (81) hide show
  1. data/README +156 -5
  2. data/bin/tb +2 -1110
  3. data/lib/tb.rb +4 -2
  4. data/lib/tb/catreader.rb +131 -0
  5. data/lib/tb/cmd_cat.rb +65 -0
  6. data/lib/tb/cmd_consecutive.rb +79 -0
  7. data/lib/tb/cmd_crop.rb +105 -0
  8. data/lib/tb/cmd_cross.rb +119 -0
  9. data/lib/tb/cmd_csv.rb +42 -0
  10. data/lib/tb/cmd_cut.rb +77 -0
  11. data/lib/tb/cmd_grep.rb +76 -0
  12. data/lib/tb/cmd_group.rb +82 -0
  13. data/lib/tb/cmd_gsub.rb +77 -0
  14. data/lib/tb/cmd_help.rb +98 -0
  15. data/lib/tb/cmd_join.rb +81 -0
  16. data/lib/tb/cmd_json.rb +60 -0
  17. data/lib/tb/cmd_ls.rb +273 -0
  18. data/lib/tb/cmd_mheader.rb +77 -0
  19. data/lib/tb/cmd_newfield.rb +59 -0
  20. data/lib/tb/cmd_pnm.rb +43 -0
  21. data/lib/tb/cmd_pp.rb +70 -0
  22. data/lib/tb/cmd_rename.rb +58 -0
  23. data/lib/tb/cmd_shape.rb +67 -0
  24. data/lib/tb/cmd_sort.rb +58 -0
  25. data/lib/tb/cmd_svn_log.rb +158 -0
  26. data/lib/tb/cmd_tsv.rb +43 -0
  27. data/lib/tb/cmd_yaml.rb +47 -0
  28. data/lib/tb/cmdmain.rb +45 -0
  29. data/lib/tb/cmdtop.rb +58 -0
  30. data/lib/tb/cmdutil.rb +327 -0
  31. data/lib/tb/csv.rb +30 -6
  32. data/lib/tb/fieldset.rb +39 -41
  33. data/lib/tb/pager.rb +132 -0
  34. data/lib/tb/pnm.rb +357 -0
  35. data/lib/tb/reader.rb +18 -128
  36. data/lib/tb/record.rb +3 -3
  37. data/lib/tb/ropen.rb +70 -0
  38. data/lib/tb/{pathfinder.rb → search.rb} +69 -34
  39. data/lib/tb/tsv.rb +29 -1
  40. data/sample/colors.ppm +0 -0
  41. data/sample/gradation.pgm +0 -0
  42. data/sample/langs.csv +46 -0
  43. data/sample/tbplot +293 -0
  44. data/test-all-cov.rb +65 -0
  45. data/test-all.rb +5 -0
  46. data/test/test_basic.rb +99 -2
  47. data/test/test_catreader.rb +27 -0
  48. data/test/test_cmd_cat.rb +118 -0
  49. data/test/test_cmd_consecutive.rb +90 -0
  50. data/test/test_cmd_crop.rb +101 -0
  51. data/test/test_cmd_cross.rb +113 -0
  52. data/test/test_cmd_csv.rb +129 -0
  53. data/test/test_cmd_cut.rb +100 -0
  54. data/test/test_cmd_grep.rb +89 -0
  55. data/test/test_cmd_group.rb +181 -0
  56. data/test/test_cmd_gsub.rb +103 -0
  57. data/test/test_cmd_help.rb +190 -0
  58. data/test/test_cmd_join.rb +197 -0
  59. data/test/test_cmd_json.rb +75 -0
  60. data/test/test_cmd_ls.rb +203 -0
  61. data/test/test_cmd_mheader.rb +86 -0
  62. data/test/test_cmd_newfield.rb +63 -0
  63. data/test/test_cmd_pnm.rb +35 -0
  64. data/test/test_cmd_pp.rb +62 -0
  65. data/test/test_cmd_rename.rb +91 -0
  66. data/test/test_cmd_shape.rb +50 -0
  67. data/test/test_cmd_sort.rb +105 -0
  68. data/test/test_cmd_tsv.rb +67 -0
  69. data/test/test_cmd_yaml.rb +55 -0
  70. data/test/test_cmdtty.rb +154 -0
  71. data/test/test_cmdutil.rb +43 -0
  72. data/test/test_csv.rb +10 -0
  73. data/test/test_fieldset.rb +42 -0
  74. data/test/test_pager.rb +142 -0
  75. data/test/test_pnm.rb +374 -0
  76. data/test/test_reader.rb +147 -0
  77. data/test/test_record.rb +49 -0
  78. data/test/test_search.rb +575 -0
  79. data/test/test_tsv.rb +7 -0
  80. metadata +108 -5
  81. data/lib/tb/qtsv.rb +0 -93
@@ -2,6 +2,11 @@ $VERBOSE = true
2
2
 
3
3
  $:.unshift "lib"
4
4
 
5
+ r, w = IO.pipe
6
+ w.close
7
+ STDIN.reopen(r)
8
+ r.close
9
+
5
10
  Dir.glob('test/test_*.rb') {|filename|
6
11
  load filename
7
12
  }
@@ -31,6 +31,21 @@ class TestTbBasic < Test::Unit::TestCase
31
31
  t2.to_a.map {|rec| rec.to_h })
32
32
  end
33
33
 
34
+ def test_pretty_print
35
+ t = Tb.new %w[fruit color],
36
+ %w[apple red],
37
+ %w[banana yellow],
38
+ %w[orange orange]
39
+ s = t.pretty_inspect
40
+ assert_match(/fruit/, s)
41
+ assert_match(/color/, s)
42
+ assert_match(/apple/, s)
43
+ assert_match(/red/, s)
44
+ assert_match(/banana/, s)
45
+ assert_match(/yellow/, s)
46
+ assert_match(/orange/, s)
47
+ end
48
+
34
49
  def test_enumerable
35
50
  t = Tb.new
36
51
  assert_kind_of(Enumerable, t)
@@ -52,6 +67,15 @@ class TestTbBasic < Test::Unit::TestCase
52
67
  }
53
68
  end
54
69
 
70
+ def test_define_field_error
71
+ t = Tb.new %w[fruit color],
72
+ %w[apple red],
73
+ %w[banana yellow],
74
+ %w[orange orange]
75
+ assert_raise(ArgumentError) { t.define_field("_foo") }
76
+ assert_raise(ArgumentError) { t.define_field("fruit") }
77
+ end
78
+
55
79
  def test_list_fields
56
80
  t = Tb.new
57
81
  assert_equal([], t.list_fields)
@@ -182,11 +206,12 @@ class TestTbBasic < Test::Unit::TestCase
182
206
 
183
207
  def test_natjoin2
184
208
  t1 = Tb.new %w[a b], %w[1 2], %w[3 4], %w[0 4]
185
- t2 = Tb.new %w[b c], %w[2 3], %w[4 5]
209
+ t2 = Tb.new %w[b c], %w[2 3], %w[4 5], %w[5 8]
186
210
  t3 = t1.natjoin2(t2)
187
211
  assert_equal([{"_recordid"=>0, "a"=>"1", "b"=>"2", "c"=>"3"},
188
212
  {"_recordid"=>1, "a"=>"3", "b"=>"4", "c"=>"5"},
189
- {"_recordid"=>2, "a"=>"0", "b"=>"4", "c"=>"5"}], t3.to_a.map {|r| r.to_h_with_reserved })
213
+ {"_recordid"=>2, "a"=>"0", "b"=>"4", "c"=>"5"}],
214
+ t3.to_a.map {|r| r.to_h_with_reserved })
190
215
  end
191
216
 
192
217
  def test_natjoin2_nocommon
@@ -200,6 +225,18 @@ class TestTbBasic < Test::Unit::TestCase
200
225
  t3.to_a.map {|r| r.to_h })
201
226
  end
202
227
 
228
+ def test_natjoin2_outer
229
+ t1 = Tb.new %w[a b], %w[1 2], %w[3 4], %w[0 4], %w[0 1]
230
+ t2 = Tb.new %w[b c], %w[2 3], %w[4 5], %w[5 8]
231
+ t3 = t1.natjoin2_outer(t2)
232
+ assert_equal([{"_recordid"=>0, "a"=>"1", "b"=>"2", "c"=>"3"},
233
+ {"_recordid"=>1, "a"=>"3", "b"=>"4", "c"=>"5"},
234
+ {"_recordid"=>2, "a"=>"0", "b"=>"4", "c"=>"5"},
235
+ {"_recordid"=>3, "a"=>"0", "b"=>"1"},
236
+ {"_recordid"=>4, "b"=>"5", "c"=>"8"}],
237
+ t3.to_a.map {|r| r.to_h_with_reserved })
238
+ end
239
+
203
240
  def test_fmap!
204
241
  t = Tb.new %w[a b], %w[1 2], %w[3 4]
205
242
  t.fmap!("a") {|record, v| "foo" + v }
@@ -249,6 +286,21 @@ class TestTbBasic < Test::Unit::TestCase
249
286
  assert(recordid3 != recordid2)
250
287
  end
251
288
 
289
+ def test_allocate_recordid_error
290
+ t = Tb.new
291
+ recordid1 = t.allocate_recordid
292
+ assert_raise(ArgumentError) { t.allocate_recordid(recordid1) }
293
+ end
294
+
295
+ def test_allocate_record
296
+ t = Tb.new
297
+ rec1 = t.allocate_record
298
+ assert_kind_of(Tb::Record, rec1)
299
+ rec2 = t.allocate_record(200)
300
+ assert_kind_of(Tb::Record, rec2)
301
+ assert_equal(200, rec2.record_id)
302
+ end
303
+
252
304
  def test_reorder_fields!
253
305
  t = Tb.new %w[fruit color],
254
306
  %w[apple red],
@@ -287,4 +339,49 @@ class TestTbBasic < Test::Unit::TestCase
287
339
  t2 = t.reorder_records_by {|rec| rec["color"] }
288
340
  assert_equal(t.map {|rec| rec["color"] }.sort, t2.map {|rec| rec["color"] })
289
341
  end
342
+
343
+ def test_insert_values
344
+ t = Tb.new %w[fruit color],
345
+ %w[apple red],
346
+ %w[banana yellow],
347
+ %w[orange orange]
348
+ res = t.insert_values(["fruit", "color"], ["grape", "purple"], ["cherry", "red"])
349
+ assert_equal([3, 4], res)
350
+ assert_equal(["grape", "purple"], t.get_values(3, "fruit", "color"))
351
+ assert_equal(["cherry", "red"], t.get_values(4, "fruit", "color"))
352
+ end
353
+
354
+ def test_insert_values_error
355
+ t = Tb.new %w[fruit color],
356
+ %w[apple red],
357
+ %w[banana yellow],
358
+ %w[orange orange]
359
+ assert_raise(ArgumentError) { t.insert_values(["fruit", "color"], ["grape", "purple", "red"]) }
360
+ end
361
+
362
+ def test_concat
363
+ t1 = Tb.new %w[fruit color],
364
+ %w[apple red]
365
+ t2 = Tb.new %w[fruit color],
366
+ %w[banana yellow],
367
+ %w[orange orange]
368
+ t3 = t1.concat(t2)
369
+ assert_same(t1, t3)
370
+ assert_equal(3, t1.size)
371
+ assert_equal(["banana", "yellow"], t1.get_values(1, "fruit", "color"))
372
+ assert_equal(["orange", "orange"], t1.get_values(2, "fruit", "color"))
373
+ end
374
+
375
+ def test_each_record_values
376
+ t = Tb.new %w[fruit color],
377
+ %w[banana yellow],
378
+ %w[orange orange]
379
+ rs = []
380
+ t.each_record_values('fruit') {|r| rs << r }
381
+ assert_equal([['banana'], ['orange']], rs)
382
+ rs = []
383
+ t.each_record_values('fruit', 'color') {|r| rs << r }
384
+ assert_equal([['banana', 'yellow'], ['orange', 'orange']], rs)
385
+ end
386
+
290
387
  end
@@ -0,0 +1,27 @@
1
+ require 'tb'
2
+ require 'test/unit'
3
+ require 'tmpdir'
4
+
5
+ class TestTbCatReader < Test::Unit::TestCase
6
+ def test_open
7
+ Dir.mktmpdir {|d|
8
+ open(i1="#{d}/i1.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
9
+ a,b
10
+ 1,2
11
+ End
12
+ open(i2="#{d}/i2.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
13
+ b,a
14
+ 3,4
15
+ End
16
+ Tb::CatReader.open([i1, i2]) {|r|
17
+ assert_equal(%w[a b], r.header)
18
+ assert_equal([%w[1 2], %w[4 3]], r.read_all)
19
+ assert_equal(0, r.index_from_field("a"))
20
+ assert_equal("b", r.field_from_index(1))
21
+ assert_equal(2, r.index_from_field_ex("1"))
22
+ assert_equal("2", r.field_from_index_ex(3))
23
+ }
24
+ }
25
+ end
26
+
27
+ end
@@ -0,0 +1,118 @@
1
+ require 'test/unit'
2
+ require 'tb/cmdtop'
3
+ require 'tmpdir'
4
+
5
+ class TestTbCmdCat < Test::Unit::TestCase
6
+ def setup
7
+ Tb::Cmd.reset_option
8
+ @curdir = Dir.pwd
9
+ @tmpdir = Dir.mktmpdir
10
+ Dir.chdir @tmpdir
11
+ end
12
+ def teardown
13
+ Tb::Cmd.reset_option
14
+ Dir.chdir @curdir
15
+ FileUtils.rmtree @tmpdir
16
+ end
17
+
18
+ def test_basic
19
+ File.open(i1="i1.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
20
+ a,b
21
+ 1,2
22
+ 3,4
23
+ End
24
+ File.open(i2="i2.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
25
+ b,c
26
+ 5,6
27
+ 7,8
28
+ End
29
+ Tb::Cmd.main_cat(['-o', o="o.csv", i1, i2])
30
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
31
+ a,b,c
32
+ 1,2
33
+ 3,4
34
+ ,5,6
35
+ ,7,8
36
+ End
37
+ end
38
+
39
+ def test_numeric
40
+ File.open(i1="i1.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
41
+ a,b
42
+ 1,2
43
+ 3,4
44
+ End
45
+ File.open(i2="i2.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
46
+ b,c
47
+ 5,6
48
+ 7,8
49
+ End
50
+ Tb::Cmd.main_cat(['-o', o="o.csv", '-N', i1, i2])
51
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
52
+ a,b
53
+ 1,2
54
+ 3,4
55
+ b,c
56
+ 5,6
57
+ 7,8
58
+ End
59
+ end
60
+
61
+ def test_extend
62
+ File.open(i1="i1.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
63
+ a,b
64
+ 1,2
65
+ 3,4,x
66
+ End
67
+ File.open(i2="i2.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
68
+ b,c
69
+ 5,6
70
+ 7,8,y
71
+ End
72
+ Tb::Cmd.main_cat(['-o', o="o.csv", i1, i2])
73
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
74
+ a,b,c
75
+ 1,2
76
+ 3,4,,x
77
+ ,5,6
78
+ ,7,8,y
79
+ End
80
+ end
81
+
82
+ def test_extend_both
83
+ File.open(i1="i1.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
84
+ a
85
+ 1,x
86
+ End
87
+ File.open(i2="i2.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
88
+ b
89
+ 2,y
90
+ End
91
+ Tb::Cmd.main_cat(['-o', o="o.csv", i1, i2])
92
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
93
+ a,b
94
+ 1,,x
95
+ ,2,y
96
+ End
97
+ end
98
+
99
+ def test_field_order
100
+ File.open(i1="i1.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
101
+ a,b,c
102
+ 1,2,3
103
+ 4,5,6
104
+ End
105
+ File.open(i2="i2.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
106
+ c,b,a
107
+ 7,8,9
108
+ End
109
+ Tb::Cmd.main_cat(['-o', o="o.csv", i1, i2])
110
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
111
+ a,b,c
112
+ 1,2,3
113
+ 4,5,6
114
+ 9,8,7
115
+ End
116
+ end
117
+
118
+ end
@@ -0,0 +1,90 @@
1
+ require 'test/unit'
2
+ require 'tb/cmdtop'
3
+ require 'tmpdir'
4
+
5
+ class TestTbCmdConsecutive < Test::Unit::TestCase
6
+ def setup
7
+ Tb::Cmd.reset_option
8
+ @curdir = Dir.pwd
9
+ @tmpdir = Dir.mktmpdir
10
+ Dir.chdir @tmpdir
11
+ end
12
+ def teardown
13
+ Tb::Cmd.reset_option
14
+ Dir.chdir @curdir
15
+ FileUtils.rmtree @tmpdir
16
+ end
17
+
18
+ def test_basic
19
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
20
+ a,b,c
21
+ 1,2,3
22
+ 4,5,6
23
+ 7,8,9
24
+ End
25
+ Tb::Cmd.main_consecutive(['-o', o="o.csv", i])
26
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
27
+ a_1,a_2,b_1,b_2,c_1,c_2
28
+ 1,4,2,5,3,6
29
+ 4,7,5,8,6,9
30
+ End
31
+ end
32
+
33
+ def test_numeric
34
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
35
+ a,b,c
36
+ 1,2,3
37
+ 4,5,6
38
+ 7,8,9
39
+ End
40
+ Tb::Cmd.main_consecutive(['-o', o="o.csv", '-N', i])
41
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
42
+ a,1,b,2,c,3
43
+ 1,4,2,5,3,6
44
+ 4,7,5,8,6,9
45
+ End
46
+ end
47
+
48
+ def test_extend
49
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
50
+ a,b
51
+ 1,2,3
52
+ 4,5,6
53
+ 7,8,9
54
+ End
55
+ Tb::Cmd.main_consecutive(['-o', o="o.csv", i])
56
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
57
+ a_1,a_2,b_1,b_2
58
+ 1,4,2,5,3,6
59
+ 4,7,5,8,6,9
60
+ End
61
+ end
62
+
63
+ def test_n3
64
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
65
+ a,b,c
66
+ 1,2,3
67
+ 4,5,6
68
+ 7,8,9
69
+ End
70
+ Tb::Cmd.main_consecutive(['-o', o="o.csv", '-n3', i])
71
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
72
+ a_1,a_2,a_3,b_1,b_2,b_3,c_1,c_2,c_3
73
+ 1,4,7,2,5,8,3,6,9
74
+ End
75
+ end
76
+
77
+ def test_n4
78
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
79
+ a,b,c
80
+ 1,2,3
81
+ 4,5,6
82
+ 7,8,9
83
+ End
84
+ Tb::Cmd.main_consecutive(['-o', o="o.csv", '-n4', i])
85
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
86
+ a_1,a_2,a_3,a_4,b_1,b_2,b_3,b_4,c_1,c_2,c_3,c_4
87
+ End
88
+ end
89
+
90
+ end
@@ -0,0 +1,101 @@
1
+ require 'test/unit'
2
+ require 'tb/cmdtop'
3
+ require 'tmpdir'
4
+
5
+ class TestTbCmdCrop < Test::Unit::TestCase
6
+ def setup
7
+ Tb::Cmd.reset_option
8
+ @curdir = Dir.pwd
9
+ @tmpdir = Dir.mktmpdir
10
+ Dir.chdir @tmpdir
11
+ end
12
+ def teardown
13
+ Tb::Cmd.reset_option
14
+ Dir.chdir @curdir
15
+ FileUtils.rmtree @tmpdir
16
+ end
17
+
18
+ def test_basic
19
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
20
+ ,,
21
+ ,a,b,,
22
+ ,0,1,,,
23
+ ,4,,,
24
+ ,,,
25
+
26
+ End
27
+ Tb::Cmd.main_crop(['-o', o="o.csv", i])
28
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
29
+ a,b
30
+ 0,1
31
+ 4
32
+ End
33
+ end
34
+
35
+ def test_a1_range
36
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
37
+ a,b,c,d
38
+ 0,1,2,3
39
+ 4,5,6,7
40
+ 8,9,a,b
41
+ c,d,e,f
42
+ End
43
+ Tb::Cmd.main_crop(['-o', o="o.csv", '-r', 'B1:C2', i])
44
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
45
+ b,c
46
+ 1,2
47
+ End
48
+ end
49
+
50
+ def test_r1c1_range
51
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
52
+ a,b,c,d
53
+ 0,1,2,3
54
+ 4,5,6,7
55
+ 8,9,a,b
56
+ c,d,e,f
57
+ End
58
+ Tb::Cmd.main_crop(['-o', o="o.csv", '-r', 'R2C1:R3C2', i])
59
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
60
+ 0,1
61
+ 4,5
62
+ End
63
+ end
64
+
65
+ def test_twofile
66
+ File.open(i1="i1.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
67
+ a,b
68
+ 1,2
69
+ 3,4
70
+ End
71
+ File.open(i2="i2.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
72
+ b,a
73
+ 5,6
74
+ 7,8
75
+ End
76
+ Tb::Cmd.main_crop(['-o', o="o.csv", '-r', 'B2:B4', i1, i2])
77
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
78
+ 2
79
+ 4
80
+ a
81
+ End
82
+ end
83
+ end
84
+
85
+ class TestTbCmdCropNoTmpDir < Test::Unit::TestCase
86
+ def test_invalid_range
87
+ assert_raise(ArgumentError) { Tb::Cmd.main_crop(['-r', 'foo']) }
88
+ end
89
+
90
+ def test_decode_a1_addressing_col
91
+ assert_equal(1, Tb::Cmd.decode_a1_addressing_col("A"))
92
+ assert_equal(26, Tb::Cmd.decode_a1_addressing_col("Z"))
93
+ ("A".."Z").each_with_index {|ch, i|
94
+ assert_equal(i+1, Tb::Cmd.decode_a1_addressing_col(ch))
95
+ }
96
+ assert_equal(27, Tb::Cmd.decode_a1_addressing_col("AA"))
97
+ assert_equal(256, Tb::Cmd.decode_a1_addressing_col("IV"))
98
+ assert_equal(16384, Tb::Cmd.decode_a1_addressing_col("XFD"))
99
+ end
100
+
101
+ end