tb 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,43 @@
1
+ require 'test/unit'
2
+ require 'tb/cmdtop'
3
+ require 'tmpdir'
4
+
5
+ class TestTbCmdUtil < 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_def_vhelp
19
+ verbose_help = Tb::Cmd.instance_variable_get(:@verbose_help)
20
+ verbose_help['foo'] = 'bar'
21
+ begin
22
+ assert_raise(ArgumentError) { Tb::Cmd.def_vhelp('foo', 'baz') }
23
+ ensure
24
+ verbose_help.delete 'foo'
25
+ end
26
+ end
27
+
28
+ def test_smart_cmp_value
29
+ assert_equal(0, smart_cmp_value(0) <=> smart_cmp_value(0))
30
+ assert_equal(1, smart_cmp_value(10) <=> smart_cmp_value(0))
31
+ assert_equal(-1, smart_cmp_value(-10) <=> smart_cmp_value(0))
32
+ assert_equal(0, smart_cmp_value("a") <=> smart_cmp_value("a"))
33
+ assert_equal(1, smart_cmp_value("z") <=> smart_cmp_value("a"))
34
+ assert_equal(-1, smart_cmp_value("a") <=> smart_cmp_value("b"))
35
+ assert_equal(1, smart_cmp_value("08") <=> smart_cmp_value("7"))
36
+ assert_raise(ArgumentError) { smart_cmp_value(Object.new) }
37
+ end
38
+
39
+ def test_conv_to_numeric
40
+ assert_raise(ArgumentError) { conv_to_numeric("foo") }
41
+ end
42
+
43
+ end
@@ -65,6 +65,16 @@ class TestTbCSV < Test::Unit::TestCase
65
65
  End
66
66
  end
67
67
 
68
+ def test_generate_with_block
69
+ t = Tb.new %w[a b], [1, 2], [3, 4]
70
+ out = t.generate_csv('', ['a', 'b']) {|recids| recids.reverse }
71
+ assert_equal(<<-'End'.gsub(/^\s+/, ''), out)
72
+ a,b
73
+ 3,4
74
+ 1,2
75
+ End
76
+ end
77
+
68
78
  def test_generate_empty
69
79
  t = Tb.new %w[a b c], [1, nil, 2], [3, '', 4]
70
80
  out = t.generate_csv('', ['a', 'b', 'c'])
@@ -0,0 +1,42 @@
1
+ require 'test/unit'
2
+
3
+ class TestTbFieldSet < Test::Unit::TestCase
4
+ def test_new
5
+ assert_equal([], Tb::FieldSet.new.header)
6
+ assert_equal(['a'], Tb::FieldSet.new('a').header)
7
+ assert_equal(['a', 'b'], Tb::FieldSet.new('a', 'b').header)
8
+ end
9
+
10
+ def test_index_from_field
11
+ assert_equal(0, Tb::FieldSet.new('a').index_from_field('a'))
12
+ assert_equal(0, Tb::FieldSet.new('a', 'b').index_from_field('a'))
13
+ assert_equal(1, Tb::FieldSet.new('a', 'b').index_from_field('b'))
14
+ assert_raise(ArgumentError) { Tb::FieldSet.new('a', 'b').index_from_field('c') }
15
+ end
16
+
17
+ def test_field_from_index_ex
18
+ fs = Tb::FieldSet.new('a', 'b')
19
+ assert_equal('a', fs.field_from_index_ex(0))
20
+ assert_equal('b', fs.field_from_index_ex(1))
21
+ assert_equal('1', fs.field_from_index_ex(2))
22
+ assert_equal('2', fs.field_from_index_ex(3))
23
+ end
24
+
25
+ def test_field_from_index
26
+ fs = Tb::FieldSet.new('a', 'b')
27
+ assert_equal('a', fs.field_from_index(0))
28
+ assert_equal('b', fs.field_from_index(1))
29
+ assert_raise(ArgumentError) { fs.field_from_index(2) }
30
+ end
31
+
32
+ def test_length
33
+ fs = Tb::FieldSet.new('a', 'b')
34
+ assert_equal(2, fs.length)
35
+ end
36
+
37
+ def test_numsuffix
38
+ fs = Tb::FieldSet.new('a', 'a(2)', 'a')
39
+ assert_equal(['a', 'a(2)', 'a(3)'], fs.header)
40
+ end
41
+
42
+ end
@@ -0,0 +1,142 @@
1
+ require 'test/unit'
2
+ require 'tb/cmdtop'
3
+ require 'tmpdir'
4
+
5
+ class TestTbPager < 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 with_env(k, v)
19
+ save = ENV[k]
20
+ begin
21
+ ENV[k] = v
22
+ yield
23
+ ensure
24
+ ENV[k] = save
25
+ end
26
+ end
27
+
28
+ def with_stdout(io)
29
+ save = STDOUT.dup
30
+ STDOUT.reopen(io)
31
+ begin
32
+ yield
33
+ ensure
34
+ STDOUT.reopen(save)
35
+ save.close
36
+ end
37
+ end
38
+
39
+ def reader_thread(io)
40
+ Thread.new {
41
+ r = ''
42
+ loop {
43
+ begin
44
+ r << io.readpartial(4096)
45
+ rescue EOFError, Errno::EIO
46
+ break
47
+ end
48
+ }
49
+ r
50
+ }
51
+ end
52
+
53
+ def test_notty
54
+ open("tst", 'w') {|f|
55
+ with_stdout(f) {
56
+ Tb::Pager.open {|pager|
57
+ pager.print "a"
58
+ }
59
+ }
60
+ }
61
+ assert_equal("a", File.read("tst"))
62
+ end
63
+
64
+ def test_printf
65
+ open("tst", 'w') {|f|
66
+ with_stdout(f) {
67
+ Tb::Pager.open {|pager|
68
+ pager.printf "%x", 255
69
+ }
70
+ }
71
+ }
72
+ assert_equal("ff", File.read("tst"))
73
+ end
74
+
75
+ def test_putc_int
76
+ open("tst", 'w') {|f|
77
+ with_stdout(f) {
78
+ Tb::Pager.open {|pager|
79
+ pager.putc 33
80
+ }
81
+ }
82
+ }
83
+ assert_equal("!", File.read("tst"))
84
+ end
85
+
86
+ def test_putc_str
87
+ open("tst", 'w') {|f|
88
+ with_stdout(f) {
89
+ Tb::Pager.open {|pager|
90
+ pager.putc "a"
91
+ }
92
+ }
93
+ }
94
+ assert_equal("a", File.read("tst"))
95
+ end
96
+
97
+ def test_puts_noarg
98
+ open("tst", 'w') {|f|
99
+ with_stdout(f) {
100
+ Tb::Pager.open {|pager|
101
+ pager.puts
102
+ }
103
+ }
104
+ }
105
+ assert_equal("\n", File.read("tst"))
106
+ end
107
+
108
+ def test_puts
109
+ open("tst", 'w') {|f|
110
+ with_stdout(f) {
111
+ Tb::Pager.open {|pager|
112
+ pager.puts "foo"
113
+ }
114
+ }
115
+ }
116
+ assert_equal("foo\n", File.read("tst"))
117
+ end
118
+
119
+ def test_write_nonblock
120
+ open("tst", 'w') {|f|
121
+ with_stdout(f) {
122
+ Tb::Pager.open {|pager|
123
+ pager.write_nonblock "foo"
124
+ }
125
+ }
126
+ }
127
+ assert_equal("foo", File.read("tst"))
128
+ end
129
+
130
+ def test_flush
131
+ open("tst", 'w') {|f|
132
+ with_stdout(f) {
133
+ Tb::Pager.open {|pager|
134
+ pager.write "foo"
135
+ pager.flush
136
+ }
137
+ }
138
+ }
139
+ assert_equal("foo", File.read("tst"))
140
+ end
141
+
142
+ end
@@ -0,0 +1,374 @@
1
+ require 'tb'
2
+ require 'tmpdir'
3
+ require 'test/unit'
4
+
5
+ class TestTbPNM < Test::Unit::TestCase
6
+ def test_parse_pbm_ascii
7
+ pbm = "P1\n2 3\n101101\n"
8
+ t = Tb.parse_pnm(pbm)
9
+ assert_equal(
10
+ [
11
+ {"type"=>"meta", "component"=>"pnm_type", "value"=>"P1"},
12
+ {"type"=>"meta", "component"=>"width", "value"=>2},
13
+ {"type"=>"meta", "component"=>"height", "value"=>3},
14
+ {"type"=>"meta", "component"=>"max", "value"=>1},
15
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"V", "value"=>0.0},
16
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"V", "value"=>1.0},
17
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"V", "value"=>0.0},
18
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"V", "value"=>0.0},
19
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"V", "value"=>1.0},
20
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"V", "value"=>0.0}
21
+ ], t.map {|rec| rec.to_h })
22
+ assert_equal("P1\n2 3\n10\n11\n01\n", t.generate_pnm)
23
+ end
24
+
25
+ def test_parse_pbm_binary
26
+ pbm = "P4\n2 3\n\x80\xc0\x40"
27
+ t = Tb.parse_pnm(pbm)
28
+ assert_equal(
29
+ [
30
+ {"type"=>"meta", "component"=>"pnm_type", "value"=>"P4"},
31
+ {"type"=>"meta", "component"=>"width", "value"=>2},
32
+ {"type"=>"meta", "component"=>"height", "value"=>3},
33
+ {"type"=>"meta", "component"=>"max", "value"=>1},
34
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"V", "value"=>0.0},
35
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"V", "value"=>1.0},
36
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"V", "value"=>0.0},
37
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"V", "value"=>0.0},
38
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"V", "value"=>1.0},
39
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"V", "value"=>0.0}
40
+ ], t.map {|rec| rec.to_h })
41
+ assert_equal(pbm, t.generate_pnm)
42
+ end
43
+
44
+ def test_parse_pgm_ascii
45
+ pgm = "P2\n2 3\n255\n0 1\n100 101\n254 255\n"
46
+ t = Tb.parse_pnm(pgm)
47
+ assert_equal(
48
+ [
49
+ {"type"=>"meta", "component"=>"pnm_type", "value"=>"P2"},
50
+ {"type"=>"meta", "component"=>"width", "value"=>2},
51
+ {"type"=>"meta", "component"=>"height", "value"=>3},
52
+ {"type"=>"meta", "component"=>"max", "value"=>255},
53
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"V", "value"=>0.0},
54
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"V", "value"=>1.0/255},
55
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"V", "value"=>100.0/255},
56
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"V", "value"=>101.0/255},
57
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"V", "value"=>254.0/255},
58
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"V", "value"=>255.0/255}
59
+ ], t.map {|rec| rec.to_h })
60
+ assert_equal(pgm, t.generate_pnm)
61
+ end
62
+
63
+ def test_parse_pgm_binary
64
+ pgm = "P5\n2 3\n255\n\x00\x01\x64\x65\xfe\xff"
65
+ t = Tb.parse_pnm(pgm)
66
+ assert_equal(
67
+ [
68
+ {"type"=>"meta", "component"=>"pnm_type", "value"=>"P5"},
69
+ {"type"=>"meta", "component"=>"width", "value"=>2},
70
+ {"type"=>"meta", "component"=>"height", "value"=>3},
71
+ {"type"=>"meta", "component"=>"max", "value"=>255},
72
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"V", "value"=>0.0},
73
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"V", "value"=>1.0/255},
74
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"V", "value"=>100.0/255},
75
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"V", "value"=>101.0/255},
76
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"V", "value"=>254.0/255},
77
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"V", "value"=>255.0/255}
78
+ ], t.map {|rec| rec.to_h })
79
+ assert_equal(pgm, t.generate_pnm)
80
+ end
81
+
82
+ def test_parse_ppm_ascii
83
+ ppm = "P3\n2 3\n255\n0 1 2 3 4 5\n100 101 102 103 104 105\n250 251 252 253 254 255\n"
84
+ t = Tb.parse_pnm(ppm)
85
+ assert_equal(
86
+ [
87
+ {"type"=>"meta", "component"=>"pnm_type", "value"=>"P3"},
88
+ {"type"=>"meta", "component"=>"width", "value"=>2},
89
+ {"type"=>"meta", "component"=>"height", "value"=>3},
90
+ {"type"=>"meta", "component"=>"max", "value"=>255},
91
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"R", "value"=>0.0},
92
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"G", "value"=>1.0/255},
93
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"B", "value"=>2.0/255},
94
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"R", "value"=>3.0/255},
95
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"G", "value"=>4.0/255},
96
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"B", "value"=>5.0/255},
97
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"R", "value"=>100.0/255},
98
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"G", "value"=>101.0/255},
99
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"B", "value"=>102.0/255},
100
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"R", "value"=>103.0/255},
101
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"G", "value"=>104.0/255},
102
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"B", "value"=>105.0/255},
103
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"R", "value"=>250.0/255},
104
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"G", "value"=>251.0/255},
105
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"B", "value"=>252.0/255},
106
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"R", "value"=>253.0/255},
107
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"G", "value"=>254.0/255},
108
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"B", "value"=>255.0/255}
109
+ ], t.map {|rec| rec.to_h })
110
+ assert_equal(ppm, t.generate_pnm)
111
+ end
112
+
113
+ def test_parse_ppm_binary
114
+ ppm = "P6\n2 3\n255\n\x00\x01\x02\x03\x04\x05\x64\x65\x66\x67\x68\x69\xfa\xfb\xfc\xfd\xfe\xff"
115
+ t = Tb.parse_pnm(ppm)
116
+ assert_equal(
117
+ [
118
+ {"type"=>"meta", "component"=>"pnm_type", "value"=>"P6"},
119
+ {"type"=>"meta", "component"=>"width", "value"=>2},
120
+ {"type"=>"meta", "component"=>"height", "value"=>3},
121
+ {"type"=>"meta", "component"=>"max", "value"=>255},
122
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"R", "value"=>0.0},
123
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"G", "value"=>1.0/255},
124
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"B", "value"=>2.0/255},
125
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"R", "value"=>3.0/255},
126
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"G", "value"=>4.0/255},
127
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"B", "value"=>5.0/255},
128
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"R", "value"=>100.0/255},
129
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"G", "value"=>101.0/255},
130
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"B", "value"=>102.0/255},
131
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"R", "value"=>103.0/255},
132
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"G", "value"=>104.0/255},
133
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"B", "value"=>105.0/255},
134
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"R", "value"=>250.0/255},
135
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"G", "value"=>251.0/255},
136
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"B", "value"=>252.0/255},
137
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"R", "value"=>253.0/255},
138
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"G", "value"=>254.0/255},
139
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"B", "value"=>255.0/255}
140
+ ], t.map {|rec| rec.to_h })
141
+ assert_equal(ppm, t.generate_pnm)
142
+ end
143
+
144
+ def test_parse_ppm_binary2
145
+ ppm = "P6\n2 3\n65535\n\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff"
146
+ t = Tb.parse_pnm(ppm)
147
+ assert_equal(
148
+ [
149
+ {"type"=>"meta", "component"=>"pnm_type", "value"=>"P6"},
150
+ {"type"=>"meta", "component"=>"width", "value"=>2},
151
+ {"type"=>"meta", "component"=>"height", "value"=>3},
152
+ {"type"=>"meta", "component"=>"max", "value"=>65535},
153
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"R", "value"=>0.0},
154
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"G", "value"=>1.0/65535},
155
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"B", "value"=>2.0/65535},
156
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"R", "value"=>3.0/65535},
157
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"G", "value"=>4.0/65535},
158
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"B", "value"=>5.0/65535},
159
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"R", "value"=>100.0/65535},
160
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"G", "value"=>101.0/65535},
161
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"B", "value"=>102.0/65535},
162
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"R", "value"=>103.0/65535},
163
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"G", "value"=>104.0/65535},
164
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"B", "value"=>105.0/65535},
165
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"R", "value"=>250.0/65535},
166
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"G", "value"=>251.0/65535},
167
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"B", "value"=>252.0/65535},
168
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"R", "value"=>253.0/65535},
169
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"G", "value"=>254.0/65535},
170
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"B", "value"=>255.0/65535}
171
+ ], t.map {|rec| rec.to_h })
172
+ assert_equal(ppm, t.generate_pnm)
173
+ end
174
+
175
+ def test_parse_pbm_comment
176
+ pbm = "P1\n\#foo\n2 3\n101101\n"
177
+ t = Tb.parse_pnm(pbm)
178
+ assert_equal(
179
+ [
180
+ {"type"=>"meta", "component"=>"pnm_type", "value"=>"P1"},
181
+ {"type"=>"meta", "component"=>"width", "value"=>2},
182
+ {"type"=>"meta", "component"=>"height", "value"=>3},
183
+ {"type"=>"meta", "component"=>"max", "value"=>1},
184
+ {"type"=>"meta", "component"=>"comment", "value"=>"foo"},
185
+ {"type"=>"pixel", "x"=>0, "y"=>0, "component"=>"V", "value"=>0.0},
186
+ {"type"=>"pixel", "x"=>1, "y"=>0, "component"=>"V", "value"=>1.0},
187
+ {"type"=>"pixel", "x"=>0, "y"=>1, "component"=>"V", "value"=>0.0},
188
+ {"type"=>"pixel", "x"=>1, "y"=>1, "component"=>"V", "value"=>0.0},
189
+ {"type"=>"pixel", "x"=>0, "y"=>2, "component"=>"V", "value"=>1.0},
190
+ {"type"=>"pixel", "x"=>1, "y"=>2, "component"=>"V", "value"=>0.0}
191
+ ], t.map {|rec| rec.to_h })
192
+ assert_equal("P1\n\#foo\n2 3\n10\n11\n01\n", t.generate_pnm)
193
+ end
194
+
195
+ def test_parse_pbm_ascii_wide
196
+ pbm = "P1\n71 3\n" + "0" * (71 * 3)
197
+ t = Tb.parse_pnm(pbm)
198
+ assert_equal("P1\n71 3\n" + ("0"*70+"\n0\n")*3, t.generate_pnm)
199
+ end
200
+
201
+ def test_parse_pgm_ascii_wide
202
+ pgm = "P2\n40 3\n255\n" + "0 " * (40*3)
203
+ t = Tb.parse_pnm(pgm)
204
+ assert_equal("P2\n40 3\n255\n" + ("0 "*34 + "0\n" + "0 "*4 + "0\n")*3, t.generate_pnm)
205
+ end
206
+
207
+ def test_parse_invalid
208
+ invalid = "foo"
209
+ assert_raise(ArgumentError) { Tb.parse_pnm(invalid) }
210
+ end
211
+
212
+ def test_parse_too_short
213
+ too_short = "P1\n2 3\n10110\n"
214
+ assert_raise(ArgumentError) { Tb.parse_pnm(too_short) }
215
+ end
216
+
217
+ def test_generate_invalid_fields
218
+ t = Tb.new %w[foo], [1]
219
+ assert_raise(ArgumentError) { t.generate_pnm }
220
+ end
221
+
222
+ def test_generate_inconsistent_color_component
223
+ t = Tb.new %w[x y component value], [nil, nil, 'V', 1.0], [nil, nil, 'R', 1.0]
224
+ assert_raise(ArgumentError) { t.generate_pnm }
225
+ end
226
+
227
+ def test_generate_complement
228
+ t = Tb.new %w[x y component value]
229
+ [
230
+ {"x"=>0, "y"=>0, "component"=>"V", "value"=>0.0},
231
+ {"x"=>1, "y"=>0, "component"=>"V", "value"=>1.0},
232
+ {"x"=>0, "y"=>1, "component"=>"V", "value"=>0.0},
233
+ {"x"=>1, "y"=>1, "component"=>"V", "value"=>0.0},
234
+ {"x"=>0, "y"=>2, "component"=>"V", "value"=>1.0},
235
+ {"x"=>1, "y"=>2, "component"=>"V", "value"=>0.0}
236
+ ].each {|h| t.insert h }
237
+ assert_equal("P4\n2 3\n\x80\xc0\x40", t.generate_pnm)
238
+ end
239
+
240
+ def test_generate_complement2
241
+ t = Tb.new %w[x y component value]
242
+ [
243
+ {"x"=>0, "y"=>0, "component"=>"V", "value"=>1.0/65535},
244
+ {"x"=>1, "y"=>0, "component"=>"V", "value"=>1.0},
245
+ {"x"=>0, "y"=>1, "component"=>"V", "value"=>0.0},
246
+ {"x"=>1, "y"=>1, "component"=>"V", "value"=>0.0},
247
+ {"x"=>0, "y"=>2, "component"=>"V", "value"=>1.0},
248
+ {"x"=>1, "y"=>2, "component"=>"V", "value"=>0.0}
249
+ ].each {|h| t.insert h }
250
+ assert_equal("P5\n2 3\n65535\n\x00\x01\xff\xff\x00\x00\x00\x00\xff\xff\x00\x00", t.generate_pnm)
251
+ end
252
+
253
+ def test_generate_complement1
254
+ t = Tb.new %w[x y component value]
255
+ [
256
+ {"x"=>0, "y"=>0, "component"=>"V", "value"=>1.0/255},
257
+ {"x"=>1, "y"=>0, "component"=>"V", "value"=>1.0},
258
+ {"x"=>0, "y"=>1, "component"=>"V", "value"=>0.0},
259
+ {"x"=>1, "y"=>1, "component"=>"V", "value"=>0.0},
260
+ {"x"=>0, "y"=>2, "component"=>"V", "value"=>1.0},
261
+ {"x"=>1, "y"=>2, "component"=>"V", "value"=>0.0}
262
+ ].each {|h| t.insert h }
263
+ assert_equal("P5\n2 3\n255\n\x01\xff\x00\x00\xff\x00", t.generate_pnm)
264
+ end
265
+
266
+ def test_generate_complement_ppm
267
+ t = Tb.new %w[x y component value]
268
+ [
269
+ {"x"=>0, "y"=>0, "component"=>"R", "value"=>0.0},
270
+ {"x"=>0, "y"=>0, "component"=>"G", "value"=>1.0},
271
+ {"x"=>0, "y"=>0, "component"=>"B", "value"=>1.0},
272
+ ].each {|h| t.insert h }
273
+ assert_equal("P6\n1 1\n255\n\x00\xff\xff", t.generate_pnm)
274
+ end
275
+
276
+ def test_generate_overrange
277
+ t = Tb.new %w[x y component value]
278
+ [
279
+ {"x"=>0, "y"=>0, "component"=>"V", "value"=>-0.5},
280
+ {"x"=>0, "y"=>1, "component"=>"V", "value"=>1.5},
281
+ ].each {|h| t.insert h }
282
+ assert_equal("P5\n1 2\n255\n\x00\xff", t.generate_pnm)
283
+ end
284
+
285
+ def test_invalid_pnm_type
286
+ t = Tb.new %w[x y component value], [nil, nil, 'pnm_type', "foo"]
287
+ assert_raise(ArgumentError) { t.generate_pnm }
288
+ end
289
+
290
+ def test_invalid_comment
291
+ t = Tb.new %w[x y component value], [nil, nil, 'comment', "\n"]
292
+ assert_raise(ArgumentError) { t.generate_pnm }
293
+ end
294
+
295
+ def test_load_pnm
296
+ Dir.mktmpdir {|d|
297
+ File.open(fn="#{d}/foo.pbm", "w") {|f| f << "P4\n1 1\n\0" }
298
+ t = Tb.load_pnm(fn)
299
+ assert_equal({"type"=>"meta", "component"=>"pnm_type", "value"=>"P4"}, t.get_record(0).to_h)
300
+ }
301
+ end
302
+
303
+ def test_pnmreader_to_a
304
+ pbm = "P1\n2 3\n101101\n"
305
+ r = Tb::PNMReader.new(pbm)
306
+ assert_equal(
307
+ [["type", "x", "y", "component", "value"],
308
+ ["meta", nil, nil, "pnm_type", "P1"],
309
+ ["meta", nil, nil, "width", 2],
310
+ ["meta", nil, nil, "height", 3],
311
+ ["meta", nil, nil, "max", 1],
312
+ ["pixel", 0, 0, "V", 0.0],
313
+ ["pixel", 1, 0, "V", 1.0],
314
+ ["pixel", 0, 1, "V", 0.0],
315
+ ["pixel", 1, 1, "V", 0.0],
316
+ ["pixel", 0, 2, "V", 1.0],
317
+ ["pixel", 1, 2, "V", 0.0]],
318
+ r.to_a)
319
+ end
320
+
321
+ def test_reader_open
322
+ Dir.mktmpdir {|d|
323
+ Dir.chdir(d) {
324
+ File.open("ba.pbm", "w") {|f| f << "P1\n1 1\n0" }
325
+ File.open("ba", "w") {|f| f << "P1\n1 1\n0" }
326
+ File.open("ga.pgm", "w") {|f| f << "P2\n1 1\n255\n0" }
327
+ File.open("ga", "w") {|f| f << "P2\n1 1\n255\n0" }
328
+ File.open("pa.ppm", "w") {|f| f << "P3\n1 1\n255\n0 0 0" }
329
+ File.open("pa", "w") {|f| f << "P3\n1 1\n255\n0 0 0" }
330
+ File.open("bb.pbm", "w") {|f| f << "P4\n1 1\n\0" }
331
+ File.open("bb", "w") {|f| f << "P4\n1 1\n\0" }
332
+ File.open("gb.pgm", "w") {|f| f << "P5\n1 1\n255\n\0" }
333
+ File.open("gb", "w") {|f| f << "P5\n1 1\n255\n\0" }
334
+ File.open("pb.ppm", "w") {|f| f << "P6\n1 1\n255\n\0\0\0" }
335
+ File.open("pb", "w") {|f| f << "P6\n1 1\n255\n\0\0\0" }
336
+
337
+ File.open("ba.pnm", "w") {|f| f << "P1\n1 1\n0" }
338
+ File.open("ga.pnm", "w") {|f| f << "P2\n1 1\n255\n0" }
339
+ File.open("pa.pnm", "w") {|f| f << "P3\n1 1\n255\n0 0 0" }
340
+ File.open("bb.pnm", "w") {|f| f << "P4\n1 1\n\0" }
341
+ File.open("gb.pnm", "w") {|f| f << "P5\n1 1\n255\n\0" }
342
+ File.open("pb.pnm", "w") {|f| f << "P6\n1 1\n255\n\0\0\0" }
343
+
344
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("ba.pbm") {|r| r.header })
345
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pnm:ba") {|r| r.header })
346
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("ga.pgm") {|r| r.header })
347
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pnm:ga") {|r| r.header })
348
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pa.ppm") {|r| r.header })
349
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pnm:pa") {|r| r.header })
350
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("bb.pbm") {|r| r.header })
351
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pnm:bb") {|r| r.header })
352
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("gb.pgm") {|r| r.header })
353
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pnm:gb") {|r| r.header })
354
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pb.ppm") {|r| r.header })
355
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pnm:pb") {|r| r.header })
356
+
357
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pbm:ba") {|r| r.header })
358
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pgm:ga") {|r| r.header })
359
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("ppm:pa") {|r| r.header })
360
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pbm:bb") {|r| r.header })
361
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pgm:gb") {|r| r.header })
362
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("ppm:pb") {|r| r.header })
363
+
364
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("ba.pnm") {|r| r.header })
365
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("ga.pnm") {|r| r.header })
366
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pa.pnm") {|r| r.header })
367
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("bb.pnm") {|r| r.header })
368
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("gb.pnm") {|r| r.header })
369
+ assert_equal(["type", "x", "y", "component", "value"], Tb::Reader.open("pb.pnm") {|r| r.header })
370
+ }
371
+ }
372
+ end
373
+
374
+ end