treevisitor 0.1.4
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/LICENSE.txt +20 -0
- data/README.rdoc +42 -0
- data/Rakefile +9 -0
- data/VERSION.yml +5 -0
- data/bin/tree.rb +9 -0
- data/examples/find_files.rb +17 -0
- data/examples/print_files.rb +15 -0
- data/lib/tree_visitor.rb +2 -0
- data/lib/treevisitor.rb +31 -0
- data/lib/treevisitor/abs_node.rb +146 -0
- data/lib/treevisitor/cli/cli_tree.rb +98 -0
- data/lib/treevisitor/dir_processor.rb +46 -0
- data/lib/treevisitor/dir_tree_walker.rb +164 -0
- data/lib/treevisitor/leaf_node.rb +33 -0
- data/lib/treevisitor/tree_node.rb +247 -0
- data/lib/treevisitor/tree_node_visitor.rb +29 -0
- data/lib/treevisitor/visitors/block_tree_node_visitor.rb +21 -0
- data/lib/treevisitor/visitors/build_dir_tree_visitor.rb +53 -0
- data/lib/treevisitor/visitors/callback_tree_node_visitor.rb +43 -0
- data/lib/treevisitor/visitors/callback_tree_node_visitor2.rb +61 -0
- data/lib/treevisitor/visitors/clone_tree_node_visitor.rb +39 -0
- data/lib/treevisitor/visitors/depth_tree_node_visitor.rb +27 -0
- data/lib/treevisitor/visitors/flat_print_tree_node_visitors.rb +20 -0
- data/lib/treevisitor/visitors/print_dir_tree_visitor.rb +21 -0
- data/lib/treevisitor/visitors/print_tree_node_visitor.rb +40 -0
- data/lib/treevisitor_cli.rb +7 -0
- data/spec/fixtures/test_dir/.dir_with_dot/dummy.txt +0 -0
- data/spec/fixtures/test_dir/dir.1/dir.1.2/file.1.2.1 +0 -0
- data/spec/fixtures/test_dir/dir.1/file.1.1 +0 -0
- data/spec/fixtures/test_dir/dir.2/file.2.1 +0 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/treevisitor/cli/cli_tree_spec.rb +58 -0
- data/spec/treevisitor/dir_processor_spec.rb +15 -0
- data/spec/treevisitor/dir_tree_walker_spec.rb +33 -0
- data/spec/treevisitor/tree_node_dsl_spec.rb +153 -0
- data/spec/treevisitor/tree_node_spec.rb +153 -0
- data/spec/treevisitor/tree_node_visitor_spec.rb +70 -0
- data/tasks/jeweler.rake +55 -0
- data/tasks/rspec.rake +34 -0
- data/tasks/rubyforge.rake +28 -0
- data/tasks/yard.rake +36 -0
- metadata +192 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper")
|
3
|
+
|
4
|
+
describe DirProcessor do
|
5
|
+
|
6
|
+
it do
|
7
|
+
files = []
|
8
|
+
dp = DirProcessor.new { |f| files << f }
|
9
|
+
dp.process(TEST_DIR)
|
10
|
+
files.length.should == 3
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper")
|
3
|
+
|
4
|
+
describe DirTreeWalker do
|
5
|
+
|
6
|
+
it "should accumulate file names" do
|
7
|
+
dir_tree_walker = DirTreeWalker.new( TEST_DIR )
|
8
|
+
dir_tree_walker.ignore_dir( ".svn" )
|
9
|
+
|
10
|
+
accumulator = []
|
11
|
+
visitor = BlockTreeNodeVisitor.new { |pathname| accumulator << File.basename( pathname ) }
|
12
|
+
dir_tree_walker.run( visitor )
|
13
|
+
accumulator.length.should == 9
|
14
|
+
accumulator.sort.should == %w{ test_dir dir.1 dir.1.2 file.1.2.1 file.1.1 dir.2 file.2.1 .dir_with_dot dummy.txt}.sort
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should ignore files" do
|
18
|
+
dtp = DirTreeWalker.new( "." )
|
19
|
+
|
20
|
+
dtp.ignore(/^\./)
|
21
|
+
dtp.ignore_file?( ".thumbnails" ).should be_true
|
22
|
+
dtp.ignore_dir?( ".thumbnails" ).should be_true
|
23
|
+
|
24
|
+
dtp.ignore_dir("thumbnails")
|
25
|
+
dtp.ignore_dir?( ".thumbnails" ).should be_true
|
26
|
+
dtp.ignore_dir?( "thumbnails" ).should be_true
|
27
|
+
dtp.ignore_dir?( "pippo" ).should be_false
|
28
|
+
|
29
|
+
dtp.ignore_file("xvpics")
|
30
|
+
dtp.ignore_file?( "xvpics" ).should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper")
|
3
|
+
|
4
|
+
describe "TreeNodeDsl" do
|
5
|
+
|
6
|
+
class DTreeNode < TreeNode
|
7
|
+
def to_s
|
8
|
+
"dt: #{content}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class DLeafNode < LeafNode
|
13
|
+
def to_s
|
14
|
+
"dl: #{content}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ArgsTreeNode < TreeNode
|
19
|
+
|
20
|
+
attr_reader :description
|
21
|
+
|
22
|
+
def initialize(name, description, parent)
|
23
|
+
super(name, parent)
|
24
|
+
@description = description
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"a: #{description}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ArgsLeafNode < LeafNode
|
33
|
+
|
34
|
+
attr_reader :description
|
35
|
+
|
36
|
+
def initialize(name, description, parent)
|
37
|
+
super(name, parent)
|
38
|
+
@description = description
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
"a: #{description}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
it "test_dsl" do
|
49
|
+
tree = TreeNode.create do
|
50
|
+
node "root" do
|
51
|
+
leaf "l1"
|
52
|
+
leaf "l2"
|
53
|
+
node "sub" do
|
54
|
+
leaf "l3"
|
55
|
+
end
|
56
|
+
node "woleaves"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# puts tree.to_str
|
61
|
+
out =<<EOS
|
62
|
+
root
|
63
|
+
|-- l1
|
64
|
+
|-- l2
|
65
|
+
|-- sub
|
66
|
+
| `-- l3
|
67
|
+
`-- woleaves
|
68
|
+
EOS
|
69
|
+
tree.to_str.should == out
|
70
|
+
end
|
71
|
+
|
72
|
+
it "test_dsl_block_with_arg" do
|
73
|
+
tree = TreeNode.create do
|
74
|
+
node "root" do |node|
|
75
|
+
node.prefix_path=("pre/")
|
76
|
+
leaf "l1"
|
77
|
+
leaf "l2"
|
78
|
+
node "sub" do
|
79
|
+
leaf "l3" do |leaf|
|
80
|
+
end
|
81
|
+
end
|
82
|
+
node "woleaves"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# puts tree.to_str
|
87
|
+
out =<<EOS
|
88
|
+
root
|
89
|
+
|-- l1
|
90
|
+
|-- l2
|
91
|
+
|-- sub
|
92
|
+
| `-- l3
|
93
|
+
`-- woleaves
|
94
|
+
EOS
|
95
|
+
tree.to_str.should == out
|
96
|
+
tree.find("l3").path_with_prefix.should == "pre/root/sub/l3"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "test_derivated" do
|
100
|
+
tree = TreeNode.create(DTreeNode, DLeafNode) do
|
101
|
+
node "root" do
|
102
|
+
leaf "l1"
|
103
|
+
leaf "l2"
|
104
|
+
node "sub" do
|
105
|
+
leaf "l3"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# puts tree.to_str
|
111
|
+
out =<<EOS
|
112
|
+
dt: root
|
113
|
+
|-- dl: l1
|
114
|
+
|-- dl: l2
|
115
|
+
`-- dt: sub
|
116
|
+
`-- dl: l3
|
117
|
+
EOS
|
118
|
+
tree.to_str.should == out
|
119
|
+
|
120
|
+
tree = DTreeNode.create(DLeafNode) do
|
121
|
+
node "root" do
|
122
|
+
leaf "l1"
|
123
|
+
leaf "l2"
|
124
|
+
node "sub" do
|
125
|
+
leaf "l3"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
tree.to_str.should == out
|
130
|
+
end
|
131
|
+
|
132
|
+
it "test_derivated_args" do
|
133
|
+
tree = TreeNode.create(ArgsTreeNode, ArgsLeafNode) do
|
134
|
+
node "root", "droot" do
|
135
|
+
leaf "l1", "dl1"
|
136
|
+
leaf "l2", "dl2"
|
137
|
+
node "sub", "dsub" do
|
138
|
+
leaf "l3", "dl3"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# puts tree.to_str
|
144
|
+
out =<<EOS
|
145
|
+
a: droot
|
146
|
+
|-- a: dl1
|
147
|
+
|-- a: dl2
|
148
|
+
`-- a: dsub
|
149
|
+
`-- a: dl3
|
150
|
+
EOS
|
151
|
+
tree.to_str.should == out
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper")
|
3
|
+
|
4
|
+
describe TreeNode do
|
5
|
+
|
6
|
+
it "should initialize correctly" do
|
7
|
+
ta = TreeNode.new("a")
|
8
|
+
ta.should be_root
|
9
|
+
|
10
|
+
ln1 = LeafNode.new("1", ta)
|
11
|
+
ln1.parent.should == ta
|
12
|
+
ln1.should_not be_root
|
13
|
+
|
14
|
+
ln2 = LeafNode.new("2", ta)
|
15
|
+
tb = TreeNode.new("b", ta)
|
16
|
+
ln3 = LeafNode.new("3", tb)
|
17
|
+
ln3.parent.should == tb
|
18
|
+
|
19
|
+
# test depth
|
20
|
+
tb.depth.should == 2
|
21
|
+
ln3.depth.should == 3
|
22
|
+
|
23
|
+
# test nr_nodes
|
24
|
+
tb.nr_nodes.should == 1
|
25
|
+
ta.nr_nodes.should == 4
|
26
|
+
|
27
|
+
# puts ta.to_str
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should add child and leaf" do
|
31
|
+
ta = TreeNode.new("a")
|
32
|
+
ta.should be_root
|
33
|
+
|
34
|
+
ln1 = LeafNode.new("1")
|
35
|
+
ta.add_leaf(ln1)
|
36
|
+
ln1.parent.should == ta
|
37
|
+
|
38
|
+
ln2 = LeafNode.new("2", ta)
|
39
|
+
ta.add_leaf(ln2)
|
40
|
+
|
41
|
+
tb = TreeNode.new("b", ta)
|
42
|
+
ln3 = LeafNode.new("3", tb)
|
43
|
+
tb.add_leaf(ln3)
|
44
|
+
ln3.parent.should == tb
|
45
|
+
|
46
|
+
ta.add_child(tb)
|
47
|
+
# puts ta.to_str
|
48
|
+
end
|
49
|
+
|
50
|
+
it "next and prev" do
|
51
|
+
ta = TreeNode.new("a")
|
52
|
+
ta.prev.should be_nil
|
53
|
+
ta.next.should be_nil
|
54
|
+
|
55
|
+
ln1 = LeafNode.new("1", ta)
|
56
|
+
ln1.prev.should be_nil
|
57
|
+
ln1.next.should be_nil
|
58
|
+
|
59
|
+
ln2 = LeafNode.new("2", ta)
|
60
|
+
ln2.prev.should == ln1
|
61
|
+
ln2.next.should be_nil
|
62
|
+
|
63
|
+
ln3 = LeafNode.new("3", ta)
|
64
|
+
ln2.next.should == ln3
|
65
|
+
|
66
|
+
tb = TreeNode.new("b", ta)
|
67
|
+
tb.next.should be_nil
|
68
|
+
tb.prev.should be_nil
|
69
|
+
|
70
|
+
tc = TreeNode.new("c", ta)
|
71
|
+
tc.prev.should == tb
|
72
|
+
tc.next.should be_nil
|
73
|
+
end
|
74
|
+
|
75
|
+
context "navigate tree" do
|
76
|
+
|
77
|
+
before do
|
78
|
+
@tree = TreeNode.new("a")
|
79
|
+
ln1 = LeafNode.new("1", @tree)
|
80
|
+
ln2 = LeafNode.new("2", @tree)
|
81
|
+
@sub_tree = TreeNode.new("b", @tree)
|
82
|
+
@ln3 = LeafNode.new("3", @sub_tree)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "nr_nodes and nr_leaves and nr_children" do
|
86
|
+
@tree.nr_nodes.should == 4
|
87
|
+
@tree.nr_leaves.should == 3
|
88
|
+
@tree.nr_children.should == 1
|
89
|
+
|
90
|
+
@sub_tree.nr_nodes.should == 1
|
91
|
+
@sub_tree.nr_leaves.should == 1
|
92
|
+
@sub_tree.nr_children.should == 0
|
93
|
+
end
|
94
|
+
|
95
|
+
it "prefix_path" do
|
96
|
+
@tree.path.should == "a"
|
97
|
+
@sub_tree.path.should == "a/b"
|
98
|
+
@tree.path_with_prefix.should == "a"
|
99
|
+
@sub_tree.path_with_prefix.should == "a/b"
|
100
|
+
|
101
|
+
@tree.prefix_path= "<root>/"
|
102
|
+
|
103
|
+
@tree.prefix_path.should == "<root>/"
|
104
|
+
@tree.path.should == "a"
|
105
|
+
@sub_tree.path.should == "a/b"
|
106
|
+
@tree.path_with_prefix.should == "<root>/a"
|
107
|
+
@sub_tree.path_with_prefix.should == "<root>/a/b"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "invalidate" do
|
111
|
+
@tree.prefix_path="root/"
|
112
|
+
@sub_tree.path.should == "a/b"
|
113
|
+
@sub_tree.path_with_prefix.should == "root/a/b"
|
114
|
+
@sub_tree.depth.should == 2
|
115
|
+
|
116
|
+
r = TreeNode.new("r")
|
117
|
+
r.add_child(@tree)
|
118
|
+
@sub_tree.path.should == "r/a/b"
|
119
|
+
@sub_tree.path_with_prefix.should == "r/a/b"
|
120
|
+
|
121
|
+
r.prefix_path="new_root/"
|
122
|
+
@sub_tree.path.should == "r/a/b"
|
123
|
+
@sub_tree.path_with_prefix.should == "new_root/r/a/b"
|
124
|
+
@sub_tree.depth.should == 3
|
125
|
+
end
|
126
|
+
|
127
|
+
it "find without block" do
|
128
|
+
@tree.find("a").should === @tree
|
129
|
+
@tree.find("b").should === @sub_tree
|
130
|
+
@tree.find("3").should === @ln3
|
131
|
+
@tree.find("not existent").should be_nil
|
132
|
+
end
|
133
|
+
|
134
|
+
it "find with block" do
|
135
|
+
@tree.find {|e| e == "a"}.should === @tree
|
136
|
+
@tree.find {|e| e == "b"}.should === @sub_tree
|
137
|
+
@tree.find {|e| e == "3"}.should === @ln3
|
138
|
+
@tree.find {|e| e == "not existent"}.should be_nil
|
139
|
+
end
|
140
|
+
|
141
|
+
it "to_str" do
|
142
|
+
out = <<EOS
|
143
|
+
a
|
144
|
+
|-- 1
|
145
|
+
|-- 2
|
146
|
+
`-- b
|
147
|
+
`-- 3
|
148
|
+
EOS
|
149
|
+
@tree.to_str.should == out
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper")
|
3
|
+
|
4
|
+
require 'treevisitor/visitors/block_tree_node_visitor'
|
5
|
+
require 'treevisitor/visitors/callback_tree_node_visitor'
|
6
|
+
require 'treevisitor/visitors/callback_tree_node_visitor2'
|
7
|
+
require 'treevisitor/visitors/clone_tree_node_visitor'
|
8
|
+
require 'treevisitor/visitors/depth_tree_node_visitor'
|
9
|
+
|
10
|
+
describe "TreeNodeVisitors" do
|
11
|
+
|
12
|
+
before do
|
13
|
+
ta = TreeNode.new( "a", nil )
|
14
|
+
LeafNode.new("1", ta )
|
15
|
+
LeafNode.new("2", ta )
|
16
|
+
|
17
|
+
tb = TreeNode.new( "b", ta )
|
18
|
+
LeafNode.new( "3", tb )
|
19
|
+
|
20
|
+
@tree = ta
|
21
|
+
end
|
22
|
+
|
23
|
+
it BlockTreeNodeVisitor do
|
24
|
+
accumulator = []
|
25
|
+
visitor = BlockTreeNodeVisitor.new { |node| accumulator << node.content}
|
26
|
+
@tree.accept( visitor )
|
27
|
+
accumulator.length.should == 5
|
28
|
+
accumulator.should == %w{ a 1 2 b 3 }
|
29
|
+
end
|
30
|
+
|
31
|
+
it DepthTreeNodeVisitor do
|
32
|
+
visitor = DepthTreeNodeVisitor.new
|
33
|
+
@tree.accept( visitor )
|
34
|
+
visitor.depth.should == 0
|
35
|
+
|
36
|
+
visitor = CloneTreeNodeVisitor.new
|
37
|
+
@tree.accept( visitor )
|
38
|
+
visitor.cloned_root.nr_nodes.should == @tree.nr_nodes
|
39
|
+
end
|
40
|
+
|
41
|
+
it CallbackTreeNodeVisitor do
|
42
|
+
accumulator = []
|
43
|
+
visitor = CallbackTreeNodeVisitor.new
|
44
|
+
visitor.on_enter_tree_node{ |tree_node| accumulator << tree_node.content }
|
45
|
+
visitor.on_visit_leaf_node{ |leaf_node| accumulator << leaf_node.content }
|
46
|
+
@tree.accept( visitor )
|
47
|
+
accumulator.length.should == 5
|
48
|
+
accumulator.should == %w{ a 1 2 b 3 }
|
49
|
+
end
|
50
|
+
|
51
|
+
it CallbackTreeNodeVisitor2 do
|
52
|
+
visitor = CallbackTreeNodeVisitor2.new
|
53
|
+
visitor.on_enter_tree_node{ |tree_node, new_parent_node|
|
54
|
+
TreeNode.new("n" + tree_node.content, new_parent_node)
|
55
|
+
}
|
56
|
+
visitor.on_visit_leaf_node{ |leaf_node, new_parent_node|
|
57
|
+
LeafNode.new( "n" + leaf_node.content, new_parent_node )
|
58
|
+
}
|
59
|
+
@tree.accept( visitor )
|
60
|
+
new_root = visitor.root
|
61
|
+
new_root.content.should == "n" + @tree.content
|
62
|
+
|
63
|
+
accumulator = []
|
64
|
+
visitor = BlockTreeNodeVisitor.new { |node| accumulator << node.content}
|
65
|
+
new_root.accept( visitor )
|
66
|
+
accumulator.length.should == 5
|
67
|
+
accumulator.should == %w{ na n1 n2 nb n3 }
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/tasks/jeweler.rake
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# jeweler
|
4
|
+
#
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
10
|
+
gem.name = "treevisitor"
|
11
|
+
gem.summary = "Implementation of visitor design pattern"
|
12
|
+
gem.description = <<-EOF
|
13
|
+
Implementation of visitor design pattern. It contains a 'tree.rb'
|
14
|
+
command line clone of the tree unix tool.
|
15
|
+
EOF
|
16
|
+
|
17
|
+
gem.authors = ["Tokiro"]
|
18
|
+
gem.email = "tokiro.oyama@gmail.com"
|
19
|
+
gem.homepage = "http://github.com/tokiro/treevisitor"
|
20
|
+
|
21
|
+
#
|
22
|
+
# dependecies
|
23
|
+
#
|
24
|
+
gem.add_development_dependency "rspec"
|
25
|
+
|
26
|
+
#
|
27
|
+
# bin
|
28
|
+
#
|
29
|
+
gem.executables = %w{ tree.rb }
|
30
|
+
|
31
|
+
#
|
32
|
+
# files
|
33
|
+
#
|
34
|
+
gem.files = %w{LICENSE README.rdoc Rakefile VERSION.yml dircat.gemspec}
|
35
|
+
gem.files.concat Dir['lib/**/*.rb']
|
36
|
+
gem.files.concat Dir['tasks/**/*.rake']
|
37
|
+
gem.files.concat Dir['examples/*.rb']
|
38
|
+
|
39
|
+
|
40
|
+
#
|
41
|
+
# test files
|
42
|
+
#
|
43
|
+
gem.test_files = Dir['spec/**/*.rb']
|
44
|
+
gem.test_files.concat Dir['spec/fixtures/**/*']
|
45
|
+
gem.test_files.concat Dir['spec/fixtures/**/.dir_with_dot/*']
|
46
|
+
|
47
|
+
#
|
48
|
+
# rubyforge
|
49
|
+
#
|
50
|
+
# gem.rubyforge_project = 'treevisitor'
|
51
|
+
end
|
52
|
+
Jeweler::GemcutterTasks.new
|
53
|
+
rescue LoadError
|
54
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
55
|
+
end
|