tb 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/README +62 -50
  2. data/bin/tb +22 -18
  3. data/lib/tb.rb +35 -19
  4. data/lib/tb/basic.rb +85 -86
  5. data/lib/tb/catreader.rb +33 -116
  6. data/lib/tb/cmd_cat.rb +31 -27
  7. data/lib/tb/cmd_consecutive.rb +45 -35
  8. data/lib/tb/cmd_crop.rb +86 -52
  9. data/lib/tb/cmd_cross.rb +113 -71
  10. data/lib/tb/cmd_cut.rb +49 -44
  11. data/lib/tb/cmd_git_log.rb +193 -0
  12. data/lib/tb/cmd_grep.rb +43 -32
  13. data/lib/tb/cmd_group.rb +63 -39
  14. data/lib/tb/cmd_gsub.rb +53 -43
  15. data/lib/tb/cmd_help.rb +51 -24
  16. data/lib/tb/cmd_join.rb +32 -35
  17. data/lib/tb/cmd_ls.rb +233 -205
  18. data/lib/tb/cmd_mheader.rb +47 -37
  19. data/lib/tb/cmd_nest.rb +94 -0
  20. data/lib/tb/cmd_newfield.rb +29 -33
  21. data/lib/tb/cmd_rename.rb +40 -32
  22. data/lib/tb/cmd_shape.rb +31 -24
  23. data/lib/tb/cmd_sort.rb +46 -25
  24. data/lib/tb/cmd_svn_log.rb +47 -28
  25. data/lib/tb/cmd_tar_tvf.rb +447 -0
  26. data/lib/tb/cmd_to_csv.rb +60 -0
  27. data/lib/tb/cmd_to_json.rb +60 -0
  28. data/lib/tb/cmd_to_pnm.rb +48 -0
  29. data/lib/tb/cmd_to_pp.rb +71 -0
  30. data/lib/tb/cmd_to_tsv.rb +48 -0
  31. data/lib/tb/cmd_to_yaml.rb +52 -0
  32. data/lib/tb/cmd_unnest.rb +118 -0
  33. data/lib/tb/cmdmain.rb +24 -20
  34. data/lib/tb/cmdtop.rb +33 -25
  35. data/lib/tb/cmdutil.rb +26 -66
  36. data/lib/tb/csv.rb +46 -34
  37. data/lib/tb/enum.rb +294 -0
  38. data/lib/tb/enumerable.rb +198 -7
  39. data/lib/tb/enumerator.rb +73 -0
  40. data/lib/tb/fieldset.rb +27 -19
  41. data/lib/tb/fileenumerator.rb +365 -0
  42. data/lib/tb/json.rb +50 -0
  43. data/lib/tb/pager.rb +6 -6
  44. data/lib/tb/pairs.rb +227 -0
  45. data/lib/tb/pnm.rb +23 -22
  46. data/lib/tb/reader.rb +52 -49
  47. data/lib/tb/record.rb +48 -19
  48. data/lib/tb/revcmp.rb +38 -0
  49. data/lib/tb/ropen.rb +74 -57
  50. data/lib/tb/search.rb +25 -21
  51. data/lib/tb/tsv.rb +31 -34
  52. data/sample/excel2csv +24 -20
  53. data/sample/poi-xls2csv.rb +24 -20
  54. data/sample/poi-xls2csv.sh +22 -18
  55. data/sample/tbplot +185 -127
  56. data/test-all-cov.rb +3 -3
  57. data/test-all.rb +1 -1
  58. data/test/test_basic.rb +26 -10
  59. data/test/test_catreader.rb +7 -6
  60. data/test/test_cmd_cat.rb +32 -0
  61. data/test/test_cmd_consecutive.rb +10 -0
  62. data/test/test_cmd_crop.rb +4 -4
  63. data/test/test_cmd_cross.rb +16 -4
  64. data/test/test_cmd_git_log.rb +46 -0
  65. data/test/test_cmd_help.rb +17 -12
  66. data/test/test_cmd_join.rb +21 -1
  67. data/test/test_cmd_ls.rb +3 -4
  68. data/test/test_cmd_mheader.rb +17 -11
  69. data/test/test_cmd_nest.rb +49 -0
  70. data/test/test_cmd_sort.rb +15 -0
  71. data/test/test_cmd_tar_tvf.rb +281 -0
  72. data/test/{test_cmd_csv.rb → test_cmd_to_csv.rb} +35 -21
  73. data/test/{test_cmd_json.rb → test_cmd_to_json.rb} +31 -3
  74. data/test/{test_cmd_pnm.rb → test_cmd_to_pnm.rb} +2 -2
  75. data/test/{test_cmd_pp.rb → test_cmd_to_pp.rb} +4 -4
  76. data/test/{test_cmd_tsv.rb → test_cmd_to_tsv.rb} +4 -4
  77. data/test/{test_cmd_yaml.rb → test_cmd_to_yaml.rb} +3 -3
  78. data/test/test_cmd_unnest.rb +89 -0
  79. data/test/test_cmdtty.rb +19 -13
  80. data/test/test_enumerable.rb +83 -1
  81. data/test/test_fileenumerator.rb +265 -0
  82. data/test/test_json.rb +15 -0
  83. data/test/test_pager.rb +3 -4
  84. data/test/test_pairs.rb +122 -0
  85. data/test/test_pnm.rb +24 -24
  86. data/test/test_reader.rb +35 -13
  87. data/test/test_revcmp.rb +10 -0
  88. data/test/test_tbenum.rb +173 -0
  89. metadata +51 -23
  90. data/lib/tb/cmd_csv.rb +0 -42
  91. data/lib/tb/cmd_json.rb +0 -60
  92. data/lib/tb/cmd_pnm.rb +0 -43
  93. data/lib/tb/cmd_pp.rb +0 -70
  94. data/lib/tb/cmd_tsv.rb +0 -43
  95. data/lib/tb/cmd_yaml.rb +0 -47
@@ -6,7 +6,7 @@ begin
6
6
  rescue LoadError
7
7
  end
8
8
 
9
- class TestTbCmdJSON < Test::Unit::TestCase
9
+ class TestTbCmdToJSON < Test::Unit::TestCase
10
10
  def setup
11
11
  Tb::Cmd.reset_option
12
12
  @curdir = Dir.pwd
@@ -25,7 +25,35 @@ class TestTbCmdJSON < Test::Unit::TestCase
25
25
  0,1,2
26
26
  4,5,6
27
27
  End
28
- Tb::Cmd.main_json(['-o', o="o.json", i])
28
+ Tb::Cmd.main_to_json(['-o', o="o.json", i])
29
+ assert_equal(<<-"End".gsub(/\s/, ''), File.read(o).gsub(/\s/, ''))
30
+ [{
31
+ "a": "0",
32
+ "b": "1",
33
+ "c": "2"
34
+ },
35
+ {
36
+ "a": "4",
37
+ "b": "5",
38
+ "c": "6"
39
+ }]
40
+ End
41
+ end
42
+
43
+ def test_json_to_json
44
+ File.open(i="i.json", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
45
+ [{
46
+ "a": "0",
47
+ "b": "1",
48
+ "c": "2"
49
+ },
50
+ {
51
+ "a": "4",
52
+ "b": "5",
53
+ "c": "6"
54
+ }]
55
+ End
56
+ Tb::Cmd.main_to_json(['-o', o="o.json", i])
29
57
  assert_equal(<<-"End".gsub(/\s/, ''), File.read(o).gsub(/\s/, ''))
30
58
  [{
31
59
  "a": "0",
@@ -51,7 +79,7 @@ class TestTbCmdJSON < Test::Unit::TestCase
51
79
  5,6
52
80
  7,8
53
81
  End
54
- Tb::Cmd.main_json(['-o', o="o.csv", i1, i2])
82
+ Tb::Cmd.main_to_json(['-o', o="o.csv", i1, i2])
55
83
  assert_equal(<<-"End".gsub(/\s/, ''), File.read(o).gsub(/\s/, ''))
56
84
  [{
57
85
  "a": "1",
@@ -2,7 +2,7 @@ require 'test/unit'
2
2
  require 'tb/cmdtop'
3
3
  require 'tmpdir'
4
4
 
5
- class TestTbCmdPNM < Test::Unit::TestCase
5
+ class TestTbCmdToPNM < Test::Unit::TestCase
6
6
  def setup
7
7
  Tb::Cmd.reset_option
8
8
  @curdir = Dir.pwd
@@ -23,7 +23,7 @@ class TestTbCmdPNM < Test::Unit::TestCase
23
23
  11
24
24
  01
25
25
  End
26
- Tb::Cmd.main_pnm(['-o', o="o.ppm", i])
26
+ Tb::Cmd.main_to_pnm(['-o', o="o.ppm", i])
27
27
  assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
28
28
  P1
29
29
  2 3
@@ -2,7 +2,7 @@ require 'test/unit'
2
2
  require 'tb/cmdtop'
3
3
  require 'tmpdir'
4
4
 
5
- class TestTbCmdPP < Test::Unit::TestCase
5
+ class TestTbCmdToPP < Test::Unit::TestCase
6
6
  def setup
7
7
  Tb::Cmd.reset_option
8
8
  @curdir = Dir.pwd
@@ -21,7 +21,7 @@ class TestTbCmdPP < Test::Unit::TestCase
21
21
  0,1,2
22
22
  4,5,6
23
23
  End
24
- Tb::Cmd.main_pp(['-o', o="o.pp", i])
24
+ Tb::Cmd.main_to_pp(['-o', o="o.pp", i])
25
25
  assert_equal(<<-"End".gsub(/\s/, ''), File.read(o).gsub(/\s/, ''))
26
26
  { "a" => "0", "b" => "1", "c" => "2" }
27
27
  { "a" => "4", "b" => "5", "c" => "6" }
@@ -33,7 +33,7 @@ class TestTbCmdPP < Test::Unit::TestCase
33
33
  a,b
34
34
  0,1,2,3
35
35
  End
36
- Tb::Cmd.main_pp(['-o', o="o.pp", i])
36
+ Tb::Cmd.main_to_pp(['-o', o="o.pp", i])
37
37
  assert_equal(<<-"End".gsub(/\s/, ''), File.read(o).gsub(/\s/, ''))
38
38
  { "a" => "0", "b" => "1", "1" => "2", "2" => "3" }
39
39
  End
@@ -50,7 +50,7 @@ class TestTbCmdPP < Test::Unit::TestCase
50
50
  5,6
51
51
  7,8
52
52
  End
53
- Tb::Cmd.main_pp(['-o', o="o.csv", i1, i2])
53
+ Tb::Cmd.main_to_pp(['-o', o="o.csv", i1, i2])
54
54
  assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
55
55
  {"a"=>"1", "b"=>"2"}
56
56
  {"a"=>"3", "b"=>"4"}
@@ -2,7 +2,7 @@ require 'test/unit'
2
2
  require 'tb/cmdtop'
3
3
  require 'tmpdir'
4
4
 
5
- class TestTbCmdTSV < Test::Unit::TestCase
5
+ class TestTbCmdToTSV < Test::Unit::TestCase
6
6
  def setup
7
7
  Tb::Cmd.reset_option
8
8
  @curdir = Dir.pwd
@@ -21,7 +21,7 @@ class TestTbCmdTSV < Test::Unit::TestCase
21
21
  0,1,2
22
22
  4,5,6
23
23
  End
24
- Tb::Cmd.main_tsv(['-o', o="o.tsv", i])
24
+ Tb::Cmd.main_to_tsv(['-o', o="o.tsv", i])
25
25
  assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
26
26
  a\tb\tc
27
27
  0\t1\t2
@@ -35,7 +35,7 @@ class TestTbCmdTSV < Test::Unit::TestCase
35
35
  0,1,2
36
36
  4,5,6
37
37
  End
38
- Tb::Cmd.main_tsv(['-o', o="o.tsv", '-N', i])
38
+ Tb::Cmd.main_to_tsv(['-o', o="o.tsv", '-N', i])
39
39
  assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
40
40
  a\tb\tc
41
41
  0\t1\t2
@@ -54,7 +54,7 @@ class TestTbCmdTSV < Test::Unit::TestCase
54
54
  5,6
55
55
  7,8
56
56
  End
57
- Tb::Cmd.main_tsv(['-o', o="o.csv", i1, i2])
57
+ Tb::Cmd.main_to_tsv(['-o', o="o.csv", i1, i2])
58
58
  assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
59
59
  a\tb
60
60
  1\t2
@@ -2,7 +2,7 @@ require 'test/unit'
2
2
  require 'tb/cmdtop'
3
3
  require 'tmpdir'
4
4
 
5
- class TestTbCmdYAML < Test::Unit::TestCase
5
+ class TestTbCmdToYAML < Test::Unit::TestCase
6
6
  def setup
7
7
  Tb::Cmd.reset_option
8
8
  @curdir = Dir.pwd
@@ -21,7 +21,7 @@ class TestTbCmdYAML < Test::Unit::TestCase
21
21
  0,1,2
22
22
  4,5,6
23
23
  End
24
- Tb::Cmd.main_yaml(['-o', o="o.yaml", i])
24
+ Tb::Cmd.main_to_yaml(['-o', o="o.yaml", i])
25
25
  assert_equal(
26
26
  [
27
27
  {'a' => '0', 'b' => '1', 'c' => '2'},
@@ -41,7 +41,7 @@ class TestTbCmdYAML < Test::Unit::TestCase
41
41
  5,6
42
42
  7,8
43
43
  End
44
- Tb::Cmd.main_yaml(['-o', o="o.csv", i1, i2])
44
+ Tb::Cmd.main_to_yaml(['-o', o="o.csv", i1, i2])
45
45
  assert_equal(
46
46
  [
47
47
  {'a' => '1', 'b' => '2'},
@@ -0,0 +1,89 @@
1
+ require 'test/unit'
2
+ require 'tb/cmdtop'
3
+ require 'tmpdir'
4
+
5
+ class TestTbCmdUnnest < 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
+ foo,"b1,b2
22
+ 1,2
23
+ 3,4
24
+ ",baz
25
+ qux,"b1,b2
26
+ 5,6
27
+ ",quuux
28
+ End
29
+ Tb::Cmd.main_unnest(['-o', o="o.csv", 'b', i])
30
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
31
+ a,b1,b2,c
32
+ foo,1,2,baz
33
+ foo,3,4,baz
34
+ qux,5,6,quuux
35
+ End
36
+ end
37
+
38
+ def test_opt_outer1
39
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
40
+ a,b,c
41
+ foo,"b1,b2
42
+ 1,2
43
+ ",baz
44
+ f,"b1,b2
45
+ ",g
46
+ qux,,quuux
47
+ End
48
+ Tb::Cmd.main_unnest(['-o', o="o.csv", '--outer', 'b', i])
49
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
50
+ a,b1,b2,c
51
+ foo,1,2,baz
52
+ f,,,g
53
+ qux,,,quuux
54
+ End
55
+ end
56
+
57
+ def test_opt_no_outer
58
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
59
+ a,b,c
60
+ foo,"b1,b2
61
+ 1,2
62
+ ",baz
63
+ f,"b1,b2
64
+ ",g
65
+ qux,,quuux
66
+ End
67
+ Tb::Cmd.main_unnest(['-o', o="o.csv", 'b', i])
68
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
69
+ a,b1,b2,c
70
+ foo,1,2,baz
71
+ End
72
+ end
73
+
74
+ def test_no_target_field
75
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
76
+ a,b,c
77
+ foo,"b1,b2
78
+ 1,2
79
+ 3,4
80
+ ",baz
81
+ qux,"b1,b2
82
+ 5,6
83
+ ",quuux
84
+ End
85
+ exc = assert_raise(SystemExit) { Tb::Cmd.main_unnest(['-o', "o.csv", 'bb', i]) }
86
+ assert(!exc.success?)
87
+ end
88
+
89
+ end
data/test/test_cmdtty.rb CHANGED
@@ -30,19 +30,19 @@ class TestTbCmdTTY < Test::Unit::TestCase
30
30
  end
31
31
  end
32
32
 
33
- def with_stdout(io)
34
- save = STDOUT.dup
35
- STDOUT.reopen(io)
33
+ def with_real_stdout(io)
34
+ save = $stdout.dup
35
+ $stdout.reopen(io)
36
36
  begin
37
37
  yield
38
38
  ensure
39
- STDOUT.reopen(save)
39
+ $stdout.reopen(save)
40
40
  save.close
41
41
  end
42
42
  end
43
43
 
44
44
  def reader_thread(io)
45
- Thread.new {
45
+ th = Thread.new {
46
46
  r = ''
47
47
  loop {
48
48
  begin
@@ -53,9 +53,12 @@ class TestTbCmdTTY < Test::Unit::TestCase
53
53
  }
54
54
  r
55
55
  }
56
+ sleep 0.1 if /freebsd/ =~ RUBY_PLATFORM # FreeBSD 8.2-RELEASE-p3 (amd64) hang ???
57
+ th
56
58
  end
57
59
 
58
60
  def test_ttyout_multiscreen
61
+ return unless IO.instance_methods.include?(:raw!)
59
62
  File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
60
63
  a,b,c
61
64
  0,1,2
@@ -66,8 +69,8 @@ class TestTbCmdTTY < Test::Unit::TestCase
66
69
  s.raw!
67
70
  s.winsize = [2, 80]
68
71
  th = reader_thread(m)
69
- with_stdout(s) {
70
- Tb::Cmd.main_csv([i])
72
+ with_real_stdout(s) {
73
+ Tb::Cmd.main_to_csv([i])
71
74
  }
72
75
  s.close
73
76
  result = th.value
@@ -81,6 +84,7 @@ class TestTbCmdTTY < Test::Unit::TestCase
81
84
  end
82
85
 
83
86
  def test_ttyout_singlescreen
87
+ return unless IO.instance_methods.include?(:raw!)
84
88
  File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
85
89
  a,b,c
86
90
  0,1,2
@@ -91,8 +95,8 @@ class TestTbCmdTTY < Test::Unit::TestCase
91
95
  s.raw!
92
96
  s.winsize = [24, 80]
93
97
  th = reader_thread(m)
94
- with_stdout(s) {
95
- Tb::Cmd.main_csv([i])
98
+ with_real_stdout(s) {
99
+ Tb::Cmd.main_to_csv([i])
96
100
  }
97
101
  s.close
98
102
  result = th.value
@@ -106,6 +110,7 @@ class TestTbCmdTTY < Test::Unit::TestCase
106
110
  end
107
111
 
108
112
  def test_ttyout_tab
113
+ return unless IO.instance_methods.include?(:raw!)
109
114
  File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
110
115
  a,b,c
111
116
  0,\t,2
@@ -115,8 +120,8 @@ class TestTbCmdTTY < Test::Unit::TestCase
115
120
  s.raw!
116
121
  s.winsize = [3, 10]
117
122
  th = reader_thread(m)
118
- with_stdout(s) {
119
- Tb::Cmd.main_csv([i])
123
+ with_real_stdout(s) {
124
+ Tb::Cmd.main_to_csv([i])
120
125
  }
121
126
  s.close
122
127
  result = th.value
@@ -129,6 +134,7 @@ class TestTbCmdTTY < Test::Unit::TestCase
129
134
  end
130
135
 
131
136
  def test_ttyout_nottysize
137
+ return unless IO.instance_methods.include?(:raw!)
132
138
  File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
133
139
  a,b,c
134
140
  0,1,2
@@ -138,8 +144,8 @@ class TestTbCmdTTY < Test::Unit::TestCase
138
144
  s.raw!
139
145
  s.winsize = [0, 0]
140
146
  th = reader_thread(m)
141
- with_stdout(s) {
142
- Tb::Cmd.main_csv([i])
147
+ with_real_stdout(s) {
148
+ Tb::Cmd.main_to_csv([i])
143
149
  }
144
150
  s.close
145
151
  result = th.value
@@ -1,4 +1,4 @@
1
- require 'tb/enumerable'
1
+ require 'tb'
2
2
  require 'test/unit'
3
3
 
4
4
  class TestTbEnumerable < Test::Unit::TestCase
@@ -119,4 +119,86 @@ class TestTbEnumerable < Test::Unit::TestCase
119
119
  assert_equal({"sweet"=>{"yellow"=>1, "green"=>1}, "tart"=>{"yellow"=>1}},
120
120
  a.tb_category_count(:taste, :color))
121
121
  end
122
+
123
+ def test_extsort_by_empty
124
+ assert_equal([], [].extsort_by {|x| x }.to_a)
125
+ end
126
+
127
+ def test_extsort_by_exhaustive
128
+ maxlen = 3
129
+ #maxlen = 7
130
+ midsize = Marshal.dump([0,0]).size + 1
131
+ [0, midsize, nil].each {|memsize|
132
+ (maxlen+1).times {|len|
133
+ (len**len).times {|i|
134
+ ary = []
135
+ len.times {|j|
136
+ ary << (i % len)
137
+ i /= len
138
+ }
139
+ uary = ary.sort.uniq
140
+ next if uary[0] != 0 || uary[-1] != uary.length - 1
141
+ ary1 = ary.map.with_index.to_a
142
+ #p [memsize, ary1]
143
+ ary2 = ary1.extsort_by(:memsize => memsize) {|v, k| v }.to_a
144
+ assert_equal(ary1.sort, ary2,
145
+ "#{ary.inspect}.extsort_by(:memsize=>#{memsize}) {|v, k| v }.to_a")
146
+ }
147
+ }
148
+ }
149
+ end
150
+
151
+ def test_extsort_by_random
152
+ midsize = Marshal.dump([0,0]).size + 1
153
+ [0, midsize, nil].each {|memsize|
154
+ 10.times {|i|
155
+ len = rand(100)
156
+ ary = []
157
+ len.times { ary << rand(1000) }
158
+ ary1 = ary.sort
159
+ ary2 = ary.extsort_by(:memsize => memsize) {|x| x }.to_a
160
+ assert_equal(ary1, ary2)
161
+ }
162
+ }
163
+ end
164
+
165
+ def test_extsort_by_block_random
166
+ 3.times {|i|
167
+ len = rand(100)
168
+ ary = []
169
+ len.times { ary << rand(1000) }
170
+ ary1 = ary.sort.reverse
171
+ ary2 = ary.extsort_by {|x| -x }.to_a
172
+ assert_equal(ary1, ary2)
173
+ }
174
+ end
175
+
176
+ def test_each_group_element
177
+ result = []
178
+ (0..9).to_a.each_group_element(
179
+ lambda {|a, b| a / 3 != b / 3 },
180
+ lambda {|v| result << [:before, v] },
181
+ lambda {|v| result << [:body, v] },
182
+ lambda {|v| result << [:after, v] })
183
+ assert_equal(
184
+ [[:before, 0],
185
+ [:body, 0],
186
+ [:body, 1],
187
+ [:body, 2],
188
+ [:after, 2],
189
+ [:before, 3],
190
+ [:body, 3],
191
+ [:body, 4],
192
+ [:body, 5],
193
+ [:after, 5],
194
+ [:before, 6],
195
+ [:body, 6],
196
+ [:body, 7],
197
+ [:body, 8],
198
+ [:after, 8],
199
+ [:before, 9],
200
+ [:body, 9],
201
+ [:after, 9]],
202
+ result)
203
+ end
122
204
  end