gf-tree_visitor 0.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.
- data/LICENSE +20 -0
- data/README.rdoc +28 -0
- data/bin/dirtree.rb +13 -0
- data/lib/tree_visitor/abs_node.rb +116 -0
- data/lib/tree_visitor/build_dir_tree_visitor.rb +58 -0
- data/lib/tree_visitor/cli/cli_dir_tree.rb +84 -0
- data/lib/tree_visitor/dir_processor.rb +40 -0
- data/lib/tree_visitor/dir_tree_walker.rb +99 -0
- data/lib/tree_visitor/leaf_node.rb +27 -0
- data/lib/tree_visitor/tree_node.rb +134 -0
- data/lib/tree_visitor/tree_node_visitor.rb +251 -0
- data/lib/tree_visitor/utility/md5.rb +17 -0
- data/lib/tree_visitor/utility/numeric.rb +17 -0
- data/lib/tree_visitor/visitor/print_node_visitor2.rb +35 -0
- data/lib/tree_visitor.rb +3 -0
- data/test/tree_visitor/tc_dir_processor.rb +16 -0
- data/test/tree_visitor/tc_dir_tree_walker.rb +37 -0
- data/test/tree_visitor/tc_tree_node.rb +135 -0
- data/test/tree_visitor/tc_tree_node_visitor.rb +70 -0
- data/test/tree_visitor/utility/tc_md5.rb +20 -0
- data/test/tree_visitor/utility/tc_numeric.rb +21 -0
- data/test/ts_tree_visitor.rb +16 -0
- metadata +73 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 gf
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
= ralbum_commmon
|
2
|
+
|
3
|
+
* FIX (url)
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
FIX (describe your package)
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* FIX (list of features or problems)
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
FIX (code sample of usage)
|
16
|
+
|
17
|
+
== REQUIREMENTS:
|
18
|
+
|
19
|
+
* utilizza la libreria abstract di kwartz
|
20
|
+
* gui: dipende da fxruby e/o wxruby
|
21
|
+
|
22
|
+
== INSTALL:
|
23
|
+
|
24
|
+
* FIX (sudo gem install, anything else)
|
25
|
+
|
26
|
+
== Copyright
|
27
|
+
|
28
|
+
Copyright (c) 2009 gf. See LICENSE for details.
|
data/bin/dirtree.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Piccolo wrapper per richiamare il programma
|
4
|
+
# clidirtree
|
5
|
+
#
|
6
|
+
|
7
|
+
$COMMON_HOME = File.expand_path( File.join( File.dirname( __FILE__), ".." ) )
|
8
|
+
$:.unshift( File.join($COMMON_HOME, "lib" ) )
|
9
|
+
|
10
|
+
require "tree_visitor/cli/cli_dir_tree"
|
11
|
+
|
12
|
+
CliDirTree.run
|
13
|
+
exit
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# rubygems
|
2
|
+
require "rubygems"
|
3
|
+
require "abstract"
|
4
|
+
|
5
|
+
#
|
6
|
+
# Nodo Astratto
|
7
|
+
# Gerarchia delle classi
|
8
|
+
#
|
9
|
+
# AbsNode ha un nome, un parent
|
10
|
+
# | definisce un path
|
11
|
+
# |
|
12
|
+
# |- LeafNode
|
13
|
+
# |
|
14
|
+
# |- TreeNode
|
15
|
+
#
|
16
|
+
#
|
17
|
+
class AbsNode
|
18
|
+
|
19
|
+
attr_reader :parent
|
20
|
+
attr_reader :name
|
21
|
+
|
22
|
+
# solo TreeNode puo' scrivere vedi funzione add_leaf
|
23
|
+
attr_accessor :prev
|
24
|
+
attr_accessor :next
|
25
|
+
|
26
|
+
|
27
|
+
def initialize( name )
|
28
|
+
@parent = nil
|
29
|
+
@name = name
|
30
|
+
@prefix_path = nil
|
31
|
+
invalidate
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# invalidate cached info
|
36
|
+
#
|
37
|
+
def invalidate
|
38
|
+
@path = nil
|
39
|
+
@path_from_root = nil
|
40
|
+
@depth = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def prefix_path
|
44
|
+
if not @parent.nil?
|
45
|
+
raise "Not root!!"
|
46
|
+
end
|
47
|
+
@prefix_path
|
48
|
+
end
|
49
|
+
|
50
|
+
def prefix_path=( prefix )
|
51
|
+
if not @parent.nil?
|
52
|
+
raise "Not root!!"
|
53
|
+
end
|
54
|
+
if prefix != @prefix_path
|
55
|
+
@prefix_path = prefix
|
56
|
+
invalidate
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def root
|
61
|
+
if root?
|
62
|
+
self
|
63
|
+
else
|
64
|
+
parent.root
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def path
|
69
|
+
return @path unless @path.nil?
|
70
|
+
if @parent.nil?
|
71
|
+
if @prefix_path
|
72
|
+
@path = @prefix_path + @name
|
73
|
+
else
|
74
|
+
@path = @name
|
75
|
+
end
|
76
|
+
else
|
77
|
+
@path = File.join( @parent.path, @name )
|
78
|
+
end
|
79
|
+
@path
|
80
|
+
end
|
81
|
+
|
82
|
+
def path_from_root
|
83
|
+
return @path_from_root unless @path_from_root.nil?
|
84
|
+
if @parent.nil?
|
85
|
+
if @prefix_path
|
86
|
+
@path_from_root = @prefix_path
|
87
|
+
else
|
88
|
+
@path_from_root = ""
|
89
|
+
end
|
90
|
+
else
|
91
|
+
@path_from_root = File.join( @parent.path_from_root, @name )
|
92
|
+
end
|
93
|
+
@path_from_root
|
94
|
+
end
|
95
|
+
|
96
|
+
def depth
|
97
|
+
return @depth unless @depth.nil?
|
98
|
+
if @parent.nil?
|
99
|
+
@depth = 1
|
100
|
+
else
|
101
|
+
@depth = @parent.depth + 1
|
102
|
+
end
|
103
|
+
@depth
|
104
|
+
end
|
105
|
+
|
106
|
+
def accept( visitor )
|
107
|
+
not_implemented
|
108
|
+
end
|
109
|
+
|
110
|
+
protected
|
111
|
+
|
112
|
+
def parent=( parent )
|
113
|
+
@parent = parent
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# common
|
2
|
+
require 'tree_visitor/tree_node'
|
3
|
+
require 'tree_visitor/dir_tree_walker'
|
4
|
+
require 'tree_visitor/tree_node_visitor'
|
5
|
+
|
6
|
+
#
|
7
|
+
# costruisce una albero TreeNode a partire dalla struttura
|
8
|
+
# della directory, simile a clona
|
9
|
+
# Clona un TreeNode
|
10
|
+
#
|
11
|
+
class BuildDirTreeVisitor < TreeNodeVisitor
|
12
|
+
|
13
|
+
attr_reader :root
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
super
|
17
|
+
@root = nil
|
18
|
+
@stack = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def enter_treeNode( pathname )
|
22
|
+
if @stack.empty?
|
23
|
+
treeNode = TreeNode.new( File.basename( pathname ) )
|
24
|
+
@root = treeNode
|
25
|
+
else
|
26
|
+
treeNode = TreeNode.new( File.basename( pathname ), @stack.last )
|
27
|
+
end
|
28
|
+
@stack.push( treeNode )
|
29
|
+
end
|
30
|
+
|
31
|
+
def exit_treeNode( pathname )
|
32
|
+
@stack.pop
|
33
|
+
end
|
34
|
+
|
35
|
+
def visit_leafNode( pathname )
|
36
|
+
leafNode = LeafNode.new( File.basename(pathname), @stack.last )
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Utilizzo della classa astratta DirTreeProcessor
|
43
|
+
# per stampare i nodi di un TreeNode
|
44
|
+
#
|
45
|
+
class PrintDirTreeVisitor < TreeNodeVisitor
|
46
|
+
|
47
|
+
def enter_treeNode( pathname )
|
48
|
+
puts pathname
|
49
|
+
end
|
50
|
+
|
51
|
+
def exit_treeNode( treeNode )
|
52
|
+
end
|
53
|
+
|
54
|
+
def visit_leafNode( pathname )
|
55
|
+
puts pathname
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# stdlib
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
# common
|
5
|
+
require 'tree_visitor/dir_tree_walker'
|
6
|
+
require 'tree_visitor/build_dir_tree_visitor'
|
7
|
+
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
class CliDirTree
|
12
|
+
|
13
|
+
def self.run
|
14
|
+
self.new.parse_args( ARGV )
|
15
|
+
end
|
16
|
+
|
17
|
+
def parse_args( argv )
|
18
|
+
|
19
|
+
options = { :verbose => true, :force => false, :algo => 'build' }
|
20
|
+
|
21
|
+
opts = OptionParser.new
|
22
|
+
opts.banner = "Usage: example.rb [options]"
|
23
|
+
|
24
|
+
opts.separator ""
|
25
|
+
opts.separator "programma per testare la classe DirProcessor"
|
26
|
+
opts.separator "Inserire il nome della directory da cui costuire il tree"
|
27
|
+
|
28
|
+
opts.separator ""
|
29
|
+
opts.separator "opzioni: "
|
30
|
+
|
31
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
32
|
+
options[:verbose] = v
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on("-q", "--quiet", "quiet mode as --no-verbose") do |v|
|
36
|
+
options[:verbose] = false
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.on("-h", "--help", "Show this message") do
|
40
|
+
puts opts
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
algos = %w[build visit]
|
46
|
+
algo_aliases = { "b" => "build", "v" => "visit" }
|
47
|
+
|
48
|
+
algo_list = (algo_aliases.keys + algos).join(',')
|
49
|
+
opts.on("-a", "--algo ALGO", algos, algo_aliases, "Select algo"," (#{algo_list})") do |algo|
|
50
|
+
options[:algo] = algo
|
51
|
+
end
|
52
|
+
|
53
|
+
rest = opts.parse(argv)
|
54
|
+
|
55
|
+
# p options
|
56
|
+
# p ARGV
|
57
|
+
|
58
|
+
if rest.length < 1
|
59
|
+
puts opts
|
60
|
+
return 1
|
61
|
+
end
|
62
|
+
|
63
|
+
dirname = rest[0]
|
64
|
+
dirname = File.expand_path( dirname )
|
65
|
+
|
66
|
+
puts "reading : #{dirname}"
|
67
|
+
|
68
|
+
dtw = DirTreeWalker.new( dirname )
|
69
|
+
dtw.add_ignore_dir( ".svn" )
|
70
|
+
dtw.add_ignore_dir( "catalog_data" )
|
71
|
+
|
72
|
+
case options[:algo]
|
73
|
+
when 'build'
|
74
|
+
visitor = BuildDirTreeVisitor.new
|
75
|
+
dtw.run( visitor )
|
76
|
+
puts visitor.root.to_str
|
77
|
+
when 'visit'
|
78
|
+
visitor = PrintDirTreeVisitor.new
|
79
|
+
dtw.run( visitor )
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
class DirProcessor
|
4
|
+
|
5
|
+
def initialize( dirname, &action )
|
6
|
+
@dirname = dirname
|
7
|
+
@processors = {}
|
8
|
+
@default_processor = action
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_processor( re, &action )
|
12
|
+
@processors[ re ] = action
|
13
|
+
end
|
14
|
+
|
15
|
+
def run()
|
16
|
+
old_dirname = Dir.pwd
|
17
|
+
Dir.chdir( @dirname )
|
18
|
+
Dir["**/*"].each { |f|
|
19
|
+
pn = Pathname.new( f ).expand_path
|
20
|
+
# puts "#{self.class.name}#loadfromdir #{f}"
|
21
|
+
next if pn.directory?
|
22
|
+
process_file( pn )
|
23
|
+
}
|
24
|
+
Dir.chdir( old_dirname )
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def process_file( pn )
|
31
|
+
# puts "file: #{f}"
|
32
|
+
pair = @processors.find { |re,action| re =~ pn.to_s }
|
33
|
+
unless pair.nil?
|
34
|
+
pair[1].call( pn )
|
35
|
+
else
|
36
|
+
@default_processor.call( pn ) if @default_processor
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
class DirTreeWalker
|
2
|
+
|
3
|
+
def initialize( dirname )
|
4
|
+
@dirname = dirname
|
5
|
+
unless File.directory?( dirname )
|
6
|
+
raise "#{dirname} is not a directory!"
|
7
|
+
end
|
8
|
+
|
9
|
+
@visitor = nil
|
10
|
+
@ignore_dir_patterns = []
|
11
|
+
@inspect_file_patterns = []
|
12
|
+
@ignore_file_patterns = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_ignore_dir( pattern )
|
16
|
+
@ignore_dir_patterns << pattern
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_ignore_file( pattern )
|
20
|
+
@ignore_file_patterns << pattern
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# quali file bisogna prendere in considerazione
|
25
|
+
# inspect opposto di ignore :-)
|
26
|
+
#
|
27
|
+
def add_inspect_file( pattern )
|
28
|
+
@inspect_file_patterns << pattern
|
29
|
+
end
|
30
|
+
|
31
|
+
def ignore_dir?( dirname )
|
32
|
+
basename = File.basename( dirname )
|
33
|
+
@ignore_dir_patterns.find{ |pattern|
|
34
|
+
basename == pattern
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def ignore_file?( filename )
|
39
|
+
basename = File.basename( filename )
|
40
|
+
@ignore_file_patterns.find{ |pattern|
|
41
|
+
if pattern.kind_of? Regexp
|
42
|
+
pattern =~ basename
|
43
|
+
else
|
44
|
+
pattern == basename
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def inspect_file?( filename )
|
50
|
+
return true if @inspect_file_patterns.empty?
|
51
|
+
basename = File.basename( filename )
|
52
|
+
@inspect_file_patterns.find{ |pattern|
|
53
|
+
if pattern.kind_of? Regexp
|
54
|
+
pattern =~ basename
|
55
|
+
else
|
56
|
+
pattern == basename
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def run( treeNodeVisitor )
|
62
|
+
@visitor = treeNodeVisitor
|
63
|
+
process_directory( File.expand_path( @dirname ) )
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
#
|
69
|
+
# recurse on other directories
|
70
|
+
#
|
71
|
+
# def process_directory( parentNode, dirname )
|
72
|
+
def process_directory( dirname )
|
73
|
+
return if ignore_dir?( dirname )
|
74
|
+
|
75
|
+
@visitor.enter_treeNode( dirname )
|
76
|
+
|
77
|
+
Dir.entries( dirname ).each { |basename|
|
78
|
+
next if basename == "." or basename == ".."
|
79
|
+
pathname = File.join( dirname, basename )
|
80
|
+
|
81
|
+
if File.directory?( pathname )
|
82
|
+
|
83
|
+
# directory
|
84
|
+
if ! ignore_dir?( basename )
|
85
|
+
process_directory( pathname )
|
86
|
+
end
|
87
|
+
|
88
|
+
else
|
89
|
+
|
90
|
+
# file
|
91
|
+
if inspect_file?( basename ) && ! ignore_file?( basename )
|
92
|
+
@visitor.visit_leafNode( pathname )
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
}
|
97
|
+
@visitor.exit_treeNode( dirname )
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# common
|
2
|
+
require "tree_visitor/abs_node"
|
3
|
+
|
4
|
+
#
|
5
|
+
# Deriva da AbsNode
|
6
|
+
#
|
7
|
+
# definisce un metodo to_str
|
8
|
+
#
|
9
|
+
#
|
10
|
+
class LeafNode < AbsNode
|
11
|
+
|
12
|
+
def initialize( name, parent = nil )
|
13
|
+
super( name )
|
14
|
+
if parent
|
15
|
+
parent.add_leaf( self )
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def accept( visitor )
|
20
|
+
visitor.visit_leafNode( self )
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_str
|
24
|
+
name.to_str
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# common
|
2
|
+
require 'tree_visitor/leaf_node'
|
3
|
+
|
4
|
+
#
|
5
|
+
# Un treeNode e' come un AbsNode
|
6
|
+
# in piu' ha la possibilita' di contenere
|
7
|
+
# altri treeNode e LeafNode
|
8
|
+
#
|
9
|
+
# TreeNode @childs -1---n-> TreeNode
|
10
|
+
# @leaves -1---n-> LeafNode
|
11
|
+
#
|
12
|
+
class TreeNode < AbsNode
|
13
|
+
|
14
|
+
attr_reader :leaves
|
15
|
+
attr_reader :childs
|
16
|
+
|
17
|
+
def initialize( name, parent = nil )
|
18
|
+
@leaves = []
|
19
|
+
@childs = []
|
20
|
+
super( name )
|
21
|
+
if parent
|
22
|
+
parent.add_child( self )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def root?
|
27
|
+
@parent.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# invalidate cached info
|
32
|
+
#
|
33
|
+
def invalidate
|
34
|
+
super
|
35
|
+
@childs.each{ |c| c.invalidate }
|
36
|
+
@leaves.each{ |l| l.invalidate }
|
37
|
+
end
|
38
|
+
|
39
|
+
def nr_nodes
|
40
|
+
nr = @leaves.length + @childs.length
|
41
|
+
@childs.inject( nr ) { |nr,c| nr + c.nr_nodes }
|
42
|
+
end
|
43
|
+
|
44
|
+
def nr_leaves
|
45
|
+
@leaves.length + @childs.inject(0) { |sum, child| sum + child.nr_leaves }
|
46
|
+
end
|
47
|
+
|
48
|
+
def nr_childs
|
49
|
+
@childs.length + @childs.inject(0) { |sum, child| sum + child.nr_childs }
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_leaf( leaf )
|
53
|
+
return if leaf.parent == self
|
54
|
+
if not leaf.parent.nil?
|
55
|
+
leaf.remove_from_parent()
|
56
|
+
end
|
57
|
+
leaf.parent = self
|
58
|
+
if @leaves.length > 0
|
59
|
+
@leaves.last.next = leaf
|
60
|
+
leaf.prev = @leaves.last
|
61
|
+
leaf.next = nil
|
62
|
+
end
|
63
|
+
leaf.invalidate
|
64
|
+
@leaves << leaf
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_child( treeNode )
|
68
|
+
return if treeNode.parent == self
|
69
|
+
if not treeNode.parent.nil?
|
70
|
+
treeNode.remove_from_parent()
|
71
|
+
end
|
72
|
+
treeNode.invalidate
|
73
|
+
treeNode.parent = self
|
74
|
+
@childs << treeNode
|
75
|
+
end
|
76
|
+
|
77
|
+
def find( name )
|
78
|
+
if self.name == name
|
79
|
+
return self
|
80
|
+
end
|
81
|
+
|
82
|
+
leaf = @leaves.find { |l| l.name == name }
|
83
|
+
if leaf
|
84
|
+
return leaf
|
85
|
+
end
|
86
|
+
|
87
|
+
@childs.each {|c|
|
88
|
+
node = c.find(name)
|
89
|
+
return node if node
|
90
|
+
}
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def accept( visitor )
|
95
|
+
visitor.enter_treeNode( self )
|
96
|
+
@leaves.each{ |l|
|
97
|
+
l.accept( visitor )
|
98
|
+
}
|
99
|
+
@childs.each { |tn|
|
100
|
+
tn.accept( visitor )
|
101
|
+
}
|
102
|
+
visitor.exit_treeNode( self )
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_str( depth = 0 )
|
106
|
+
str = ""
|
107
|
+
(0...depth).step {
|
108
|
+
str << " |-"
|
109
|
+
}
|
110
|
+
|
111
|
+
str << @name
|
112
|
+
str << "\n"
|
113
|
+
|
114
|
+
if ! @leaves.empty?
|
115
|
+
@leaves.each{ |l|
|
116
|
+
(0...depth-1).step {
|
117
|
+
str << " |-"
|
118
|
+
}
|
119
|
+
if @childs.empty?
|
120
|
+
str << " | "
|
121
|
+
else
|
122
|
+
str << " | | "
|
123
|
+
end
|
124
|
+
str << l.to_str
|
125
|
+
str << "\n"
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
@childs.each { |tn|
|
130
|
+
str << tn.to_str( depth + 1 )
|
131
|
+
}
|
132
|
+
str
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
# rubygems
|
2
|
+
require 'rubygems'
|
3
|
+
require 'abstract'
|
4
|
+
|
5
|
+
#
|
6
|
+
# Classe astratta per visitare un TreeNode
|
7
|
+
#
|
8
|
+
class TreeNodeVisitor
|
9
|
+
|
10
|
+
def enter_treeNode( treeNode )
|
11
|
+
not_implemented
|
12
|
+
end
|
13
|
+
|
14
|
+
def exit_treeNode( treeNode )
|
15
|
+
not_implemented
|
16
|
+
end
|
17
|
+
|
18
|
+
def visit_leafNode( leafNode )
|
19
|
+
not_implemented
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Utilizzo della classa astratta DirTreeProcessor
|
26
|
+
# per chimare un blocco su tutti i TreeNode
|
27
|
+
#
|
28
|
+
class BlockTreeNodeVisitor
|
29
|
+
|
30
|
+
def initialize( &action )
|
31
|
+
@block = action
|
32
|
+
end
|
33
|
+
|
34
|
+
def enter_treeNode( treeNode )
|
35
|
+
@block.call( treeNode )
|
36
|
+
end
|
37
|
+
|
38
|
+
def exit_treeNode( treeNode )
|
39
|
+
end
|
40
|
+
|
41
|
+
def visit_leafNode( leafNode )
|
42
|
+
@block.call( leafNode )
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Utilizzo della classa astratta DirTreeProcessor
|
49
|
+
# per stampare i nodi di un TreeNode
|
50
|
+
#
|
51
|
+
class FlatPrintTreeNodeVisitor < TreeNodeVisitor
|
52
|
+
|
53
|
+
def enter_treeNode( treeNode )
|
54
|
+
puts treeNode.name
|
55
|
+
end
|
56
|
+
|
57
|
+
def exit_treeNode( treeNode )
|
58
|
+
end
|
59
|
+
|
60
|
+
def visit_leafNode( leafNode )
|
61
|
+
puts leafNode.name
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
class PrintTreeNodeVisitor < TreeNodeVisitor
|
68
|
+
|
69
|
+
def initialize( *args )
|
70
|
+
super( *args )
|
71
|
+
@depth = 0
|
72
|
+
end
|
73
|
+
|
74
|
+
def visit_leafNode( leafNode )
|
75
|
+
str = ""
|
76
|
+
(0...@depth-1).step {
|
77
|
+
str << " |-"
|
78
|
+
}
|
79
|
+
str << " | "
|
80
|
+
puts str + leafNode.name.to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
def enter_treeNode( treeNode )
|
84
|
+
|
85
|
+
str = ""
|
86
|
+
(0...@depth).step {
|
87
|
+
str << " |-"
|
88
|
+
}
|
89
|
+
|
90
|
+
if @depth == 0
|
91
|
+
puts str + treeNode.name.to_s
|
92
|
+
else
|
93
|
+
puts str + treeNode.name.to_s
|
94
|
+
end
|
95
|
+
@depth += 1
|
96
|
+
end
|
97
|
+
|
98
|
+
def exit_treeNode( treeNode )
|
99
|
+
@depth -= 1
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
#
|
105
|
+
#
|
106
|
+
#
|
107
|
+
class DepthTreeNodeVisitor < TreeNodeVisitor
|
108
|
+
|
109
|
+
attr_reader :depth
|
110
|
+
|
111
|
+
def initialize
|
112
|
+
super
|
113
|
+
@depth = 0
|
114
|
+
end
|
115
|
+
|
116
|
+
def enter_treeNode( treeNode )
|
117
|
+
@depth += 1
|
118
|
+
end
|
119
|
+
|
120
|
+
def exit_treeNode( treeNode )
|
121
|
+
@depth -= 1
|
122
|
+
end
|
123
|
+
|
124
|
+
def visit_leafNode( leafNode )
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# Esempio
|
131
|
+
# Clona un TreeNode
|
132
|
+
#
|
133
|
+
class CloneTreeNodeVisitor < TreeNodeVisitor
|
134
|
+
|
135
|
+
attr_reader :clonedRoot
|
136
|
+
|
137
|
+
def initialize
|
138
|
+
super
|
139
|
+
@clonedRoot = nil
|
140
|
+
@stack = []
|
141
|
+
end
|
142
|
+
|
143
|
+
def enter_treeNode( treeNode )
|
144
|
+
if @stack.empty?
|
145
|
+
clonedTreeNode = TreeNode.new( treeNode.name )
|
146
|
+
@clonedRoot = clonedTreeNode
|
147
|
+
else
|
148
|
+
clonedTreeNode = TreeNode.new( treeNode.name, @stack.last )
|
149
|
+
end
|
150
|
+
@stack.push( clonedTreeNode )
|
151
|
+
end
|
152
|
+
|
153
|
+
def exit_treeNode( treeNode )
|
154
|
+
@stack.pop
|
155
|
+
end
|
156
|
+
|
157
|
+
def visit_leafNode( leafNode )
|
158
|
+
clonedLeafNode = LeafNode.new( leafNode.name, @stack.last )
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# CallbackTreeNodeVisitor
|
165
|
+
#
|
166
|
+
class CallbackTreeNodeVisitor < TreeNodeVisitor
|
167
|
+
|
168
|
+
def initialize( root = nil )
|
169
|
+
super()
|
170
|
+
@stack = []
|
171
|
+
@root = root
|
172
|
+
@stack.push( root ) if root
|
173
|
+
@action_enterTreeNode = nil
|
174
|
+
@action_visitLeafNode = nil
|
175
|
+
end
|
176
|
+
|
177
|
+
def onEnterTreeNode( &action )
|
178
|
+
@action_enterTreeNode = action
|
179
|
+
end
|
180
|
+
|
181
|
+
def onVisitLeafNode( &action )
|
182
|
+
@action_visitLeafNode = action
|
183
|
+
end
|
184
|
+
|
185
|
+
def enter_treeNode( treeNode )
|
186
|
+
parentNode = if @stack.empty?
|
187
|
+
nil
|
188
|
+
else
|
189
|
+
@stack.last
|
190
|
+
end
|
191
|
+
@root = treeNode if @stack.empty?
|
192
|
+
@stack.push( treeNode )
|
193
|
+
@action_enterTreeNode.call( treeNode ) if @action_enterTreeNode
|
194
|
+
end
|
195
|
+
|
196
|
+
def exit_treeNode( treeNode )
|
197
|
+
@stack.pop
|
198
|
+
end
|
199
|
+
|
200
|
+
def visit_leafNode( leafNode )
|
201
|
+
parentNode = @stack.last
|
202
|
+
@action_visitLeafNode.call( leafNode ) if @action_visitLeafNode
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
#
|
209
|
+
# CallbackTreeNodeVisitor
|
210
|
+
#
|
211
|
+
class CallbackTreeNodeVisitor2 < TreeNodeVisitor
|
212
|
+
|
213
|
+
attr_reader :root
|
214
|
+
|
215
|
+
def initialize( root = nil )
|
216
|
+
super()
|
217
|
+
@stack = []
|
218
|
+
@root = root
|
219
|
+
@stack.push( root ) if root
|
220
|
+
end
|
221
|
+
|
222
|
+
def onEnterTreeNode( &action )
|
223
|
+
@action_enterTreeNode = action
|
224
|
+
end
|
225
|
+
|
226
|
+
def onVisitLeafNode( &action )
|
227
|
+
@action_visitLeafNode = action
|
228
|
+
end
|
229
|
+
|
230
|
+
def enter_treeNode( treeNode )
|
231
|
+
newParentNode = if @stack.empty?
|
232
|
+
nil
|
233
|
+
else
|
234
|
+
@stack.last
|
235
|
+
end
|
236
|
+
newTreeNode = @action_enterTreeNode.call( treeNode, newParentNode )
|
237
|
+
@root = newTreeNode if @stack.empty?
|
238
|
+
@stack.push( newTreeNode )
|
239
|
+
end
|
240
|
+
|
241
|
+
def exit_treeNode( treeNode )
|
242
|
+
@stack.pop
|
243
|
+
end
|
244
|
+
|
245
|
+
def visit_leafNode( leafNode )
|
246
|
+
newParentNode = @stack.last
|
247
|
+
@action_visitLeafNode.call( leafNode, newParentNode )
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# stdlib
|
2
|
+
require 'md5'
|
3
|
+
|
4
|
+
#
|
5
|
+
# calcola md5 di file grandi, copiata da usenet
|
6
|
+
#
|
7
|
+
class MD5
|
8
|
+
def self.file(file)
|
9
|
+
File.open(file, "rb") do |f|
|
10
|
+
res = self.new
|
11
|
+
while (data = f.read(4096))
|
12
|
+
res << data
|
13
|
+
end
|
14
|
+
res
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Numeric
|
2
|
+
#
|
3
|
+
# ritorna una stringa con le migliaia serparate da <separator>
|
4
|
+
# es.: 100000 -> 1.000.000
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# copiata da http://wiki.rubygarden.org/Ruby/page/show/FixNumFormat
|
8
|
+
#
|
9
|
+
def with_separator( separator = ',', length = 3 )
|
10
|
+
splitter = Regexp.compile "(\\d{#{length}})"
|
11
|
+
before, after = self.to_s.split('.')
|
12
|
+
before = before.reverse.gsub splitter, '\1' + separator
|
13
|
+
str = "#{ before.chomp( separator ).reverse }"
|
14
|
+
str += ".#{ after }" if after
|
15
|
+
return str
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class PrintTreeNodeVisitor2 < TreeNodeVisitor
|
2
|
+
|
3
|
+
def initialize( *args )
|
4
|
+
super( *args )
|
5
|
+
@depth = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def visit_leafNode( leafNode )
|
9
|
+
str = ""
|
10
|
+
(0...@depth-1).step {
|
11
|
+
str << " |-"
|
12
|
+
}
|
13
|
+
str << " | "
|
14
|
+
puts str + leafNode.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def enter_treeNode( treeNode )
|
18
|
+
|
19
|
+
str = ""
|
20
|
+
(0...@depth).step {
|
21
|
+
str << " |-"
|
22
|
+
}
|
23
|
+
|
24
|
+
if @depth == 0
|
25
|
+
puts str + treeNode.to_s
|
26
|
+
else
|
27
|
+
puts str + treeNode.to_s
|
28
|
+
end
|
29
|
+
@depth += 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def exit_treeNode( treeNode )
|
33
|
+
@depth -= 1
|
34
|
+
end
|
35
|
+
end
|
data/lib/tree_visitor.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
$COMMON_HOME = File.expand_path( File.join( File.dirname( __FILE__), "..", ".." ) )
|
4
|
+
$:.unshift( File.join($COMMON_HOME, "lib" ) )
|
5
|
+
$:.unshift( File.join($COMMON_HOME, "test" ) )
|
6
|
+
|
7
|
+
$TEST_DATA = File.join( $COMMON_HOME, "test", "tree_visitor", "test_data" )
|
8
|
+
|
9
|
+
require 'tree_visitor/dir_processor'
|
10
|
+
|
11
|
+
class TCDirProcessor < Test::Unit::TestCase
|
12
|
+
def test_simple
|
13
|
+
dp = DirProcessor.new($TEST_DATA) { |f| puts f }
|
14
|
+
dp.run
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# stdlib
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
# common
|
5
|
+
$COMMON_HOME = File.expand_path( File.join( File.dirname( __FILE__), "..", ".." ) )
|
6
|
+
$:.unshift( File.join($COMMON_HOME, "lib" ) )
|
7
|
+
$:.unshift( File.join($COMMON_HOME, "test" ) )
|
8
|
+
$TEST_DATA = File.join( $COMMON_HOME, "test", "tree_visitor", "test_data" )
|
9
|
+
|
10
|
+
require 'tree_visitor/dir_tree_walker.rb'
|
11
|
+
require 'tree_visitor/tree_node_visitor.rb'
|
12
|
+
|
13
|
+
class TCDirTreeWalker < Test::Unit::TestCase
|
14
|
+
|
15
|
+
def test_simple
|
16
|
+
dir_tree_walker = DirTreeWalker.new( $TEST_DATA )
|
17
|
+
dir_tree_walker.add_ignore_dir( ".svn" )
|
18
|
+
|
19
|
+
accumulator = []
|
20
|
+
visitor = BlockTreeNodeVisitor.new { |pathname| accumulator << File.basename( pathname ) }
|
21
|
+
dir_tree_walker.run( visitor )
|
22
|
+
assert_equal( 7, accumulator.length )
|
23
|
+
assert_equal( %w{ test_data dir.1 dir.1.2 file.1.2.1 file.1.1 dir.2 file.2.1 }, accumulator )
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_ignore_dir
|
27
|
+
dtp = DirTreeWalker.new( "." )
|
28
|
+
|
29
|
+
dtp.add_ignore_dir(".xvpics")
|
30
|
+
dtp.add_ignore_dir(".thumbnails")
|
31
|
+
dtp.add_ignore_dir("catalog_data")
|
32
|
+
|
33
|
+
assert( dtp.ignore_dir?( ".thumbnails" ) )
|
34
|
+
assert( ! dtp.ignore_dir?( "pippo" ) )
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# stdlib
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
# common
|
5
|
+
$COMMON_HOME = File.expand_path( File.join( File.dirname( __FILE__), "..", ".." ) )
|
6
|
+
$:.unshift( File.join($COMMON_HOME, "lib" ) )
|
7
|
+
$:.unshift( File.join($COMMON_HOME, "test" ) )
|
8
|
+
|
9
|
+
require 'tree_visitor/tree_node.rb'
|
10
|
+
|
11
|
+
class TCTreeNode < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def test_simple_build
|
14
|
+
ta = TreeNode.new( "a" )
|
15
|
+
assert( ta.root? )
|
16
|
+
ln1 = LeafNode.new("1", ta)
|
17
|
+
assert_equal( ta, ln1.parent )
|
18
|
+
ln2 = LeafNode.new("2", ta)
|
19
|
+
tb = TreeNode.new( "b", ta )
|
20
|
+
ln3 = LeafNode.new( "3", tb )
|
21
|
+
assert_equal( tb, ln3.parent )
|
22
|
+
|
23
|
+
# test depth
|
24
|
+
assert_equal( 2, tb.depth )
|
25
|
+
assert_equal( 3, ln3.depth )
|
26
|
+
|
27
|
+
# test nr_nodes
|
28
|
+
assert_equal( 1, tb.nr_nodes )
|
29
|
+
assert_equal( 4, ta.nr_nodes )
|
30
|
+
|
31
|
+
# puts ta.to_str
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_add_methods
|
35
|
+
ta = TreeNode.new( "a" )
|
36
|
+
assert( ta.root? )
|
37
|
+
|
38
|
+
ln1 = LeafNode.new("1")
|
39
|
+
ta.add_leaf( ln1 )
|
40
|
+
assert_equal( ta, ln1.parent )
|
41
|
+
|
42
|
+
ln2 = LeafNode.new("2", ta)
|
43
|
+
ta.add_leaf( ln2 )
|
44
|
+
|
45
|
+
tb = TreeNode.new( "b", ta )
|
46
|
+
ln3 = LeafNode.new( "3", tb )
|
47
|
+
tb.add_leaf( ln3 )
|
48
|
+
assert_equal( tb, ln3.parent )
|
49
|
+
|
50
|
+
ta.add_child( tb )
|
51
|
+
# puts ta.to_str
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_next_prev
|
55
|
+
ta = TreeNode.new( "a" )
|
56
|
+
|
57
|
+
ln1 = LeafNode.new("1", ta)
|
58
|
+
assert_nil( ln1.next )
|
59
|
+
assert_nil( ln1.prev )
|
60
|
+
|
61
|
+
ln2 = LeafNode.new("2", ta)
|
62
|
+
assert_equal( ln1, ln2.prev )
|
63
|
+
assert_nil( ln2.next )
|
64
|
+
|
65
|
+
ln3 = LeafNode.new("3", ta)
|
66
|
+
assert_equal( ln3, ln2.next )
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_nr_methods
|
70
|
+
ta = TreeNode.new( "a" )
|
71
|
+
ln1 = LeafNode.new("1", ta)
|
72
|
+
ln2 = LeafNode.new("2", ta)
|
73
|
+
tb = TreeNode.new( "b", ta )
|
74
|
+
ln3 = LeafNode.new( "3", tb )
|
75
|
+
|
76
|
+
assert_equal( 4, ta.nr_nodes )
|
77
|
+
assert_equal( 3, ta.nr_leaves )
|
78
|
+
assert_equal( 1, ta.nr_childs )
|
79
|
+
|
80
|
+
assert_equal( 1, tb.nr_nodes )
|
81
|
+
assert_equal( 1, tb.nr_leaves )
|
82
|
+
assert_equal( 0, tb.nr_childs )
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_prefix_path
|
86
|
+
ta = TreeNode.new( "a" )
|
87
|
+
ln1 = LeafNode.new("1", ta)
|
88
|
+
ln2 = LeafNode.new("2", ta)
|
89
|
+
tb = TreeNode.new( "b", ta )
|
90
|
+
ln3 = LeafNode.new( "3", tb )
|
91
|
+
|
92
|
+
assert_equal( "a", ta.path )
|
93
|
+
assert_equal( "a/b", tb.path )
|
94
|
+
|
95
|
+
ta.prefix_path= "<root>/"
|
96
|
+
|
97
|
+
assert_equal( "<root>/a", ta.path )
|
98
|
+
assert_equal( "<root>/a/b", tb.path )
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_invalidate
|
102
|
+
ta = TreeNode.new( "a" )
|
103
|
+
ln1 = LeafNode.new("1", ta)
|
104
|
+
ln2 = LeafNode.new("2", ta)
|
105
|
+
tb = TreeNode.new( "b", ta )
|
106
|
+
ln3 = LeafNode.new( "3", tb )
|
107
|
+
|
108
|
+
#@path = nil
|
109
|
+
#@path_from_root = nil
|
110
|
+
#@depth = nil
|
111
|
+
|
112
|
+
|
113
|
+
assert_equal( "a/b", tb.path )
|
114
|
+
assert_equal( "/b", tb.path_from_root )
|
115
|
+
assert_equal( 2, tb.depth )
|
116
|
+
|
117
|
+
r = TreeNode.new( "r" )
|
118
|
+
r.add_child( ta )
|
119
|
+
assert_equal( "r/a/b", tb.path )
|
120
|
+
assert_equal( "/a/b", tb.path_from_root )
|
121
|
+
assert_equal( 3, tb.depth )
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_find
|
125
|
+
ta = TreeNode.new( "a" )
|
126
|
+
ln1 = LeafNode.new("1", ta)
|
127
|
+
ln2 = LeafNode.new("2", ta)
|
128
|
+
tb = TreeNode.new( "b", ta )
|
129
|
+
ln3 = LeafNode.new( "3", tb )
|
130
|
+
|
131
|
+
assert_equal(ln3, ta.find( "3"))
|
132
|
+
assert_equal(tb, ta.find( "b"))
|
133
|
+
assert_nil( ta.find("not existent"))
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
$COMMON_HOME = File.expand_path( File.join( File.dirname( __FILE__), "..", ".." ) )
|
4
|
+
$:.unshift( File.join($COMMON_HOME, "lib" ) )
|
5
|
+
$:.unshift( File.join($COMMON_HOME, "test" ) )
|
6
|
+
|
7
|
+
require 'tree_visitor/tree_node.rb'
|
8
|
+
require 'tree_visitor/tree_node_visitor.rb'
|
9
|
+
|
10
|
+
class TCTreeNodeVisitor < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def setup
|
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
|
+
def test_blocktreenodevisitor
|
24
|
+
accumulator = []
|
25
|
+
visitor = BlockTreeNodeVisitor.new { |node| accumulator << node.name}
|
26
|
+
@tree.accept( visitor )
|
27
|
+
assert_equal( 5, accumulator.length )
|
28
|
+
assert_equal( %w{ a 1 2 b 3 }, accumulator )
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_depthtreenodevisitor
|
32
|
+
visitor = DepthTreeNodeVisitor.new
|
33
|
+
@tree.accept( visitor )
|
34
|
+
assert_equal( 0, visitor.depth )
|
35
|
+
|
36
|
+
visitor = CloneTreeNodeVisitor.new
|
37
|
+
@tree.accept( visitor )
|
38
|
+
assert_equal(@tree.nr_nodes, visitor.clonedRoot.nr_nodes )
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_callback_tree_node_visitor
|
42
|
+
accumulator = []
|
43
|
+
visitor = CallbackTreeNodeVisitor.new
|
44
|
+
visitor.onEnterTreeNode{ |treeNode| accumulator << treeNode.name }
|
45
|
+
visitor.onVisitLeafNode{ |leafNode| accumulator << leafNode.name }
|
46
|
+
@tree.accept( visitor )
|
47
|
+
assert_equal( 5, accumulator.length )
|
48
|
+
assert_equal( %w{ a 1 2 b 3 }, accumulator )
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_callback_tree_node_visitor2
|
52
|
+
visitor = CallbackTreeNodeVisitor2.new
|
53
|
+
visitor.onEnterTreeNode{ |treeNode, newParentNode|
|
54
|
+
TreeNode.new("n" + treeNode.name, newParentNode)
|
55
|
+
}
|
56
|
+
visitor.onVisitLeafNode{ |leafNode, newParentNode|
|
57
|
+
LeafNode.new( "n" + leafNode.name, newParentNode )
|
58
|
+
}
|
59
|
+
@tree.accept( visitor )
|
60
|
+
newRoot = visitor.root
|
61
|
+
assert_equal( "n" + @tree.name, newRoot.name)
|
62
|
+
|
63
|
+
accumulator = []
|
64
|
+
visitor = BlockTreeNodeVisitor.new { |node| accumulator << node.name}
|
65
|
+
newRoot.accept( visitor )
|
66
|
+
assert_equal( 5, accumulator.length )
|
67
|
+
assert_equal( %w{ na n1 n2 nb n3 }, accumulator )
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# stdlib
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
# common
|
5
|
+
$COMMON_HOME = File.expand_path( File.join( File.dirname( __FILE__), "..", "..", ".." ) )
|
6
|
+
$:.unshift( File.join($COMMON_HOME, "lib" ) )
|
7
|
+
$:.unshift( File.join($COMMON_HOME, "test" ) )
|
8
|
+
$TEST_FILE = File.join( $COMMON_HOME, "lib", "tree_visitor.rb" )
|
9
|
+
|
10
|
+
|
11
|
+
require 'tree_visitor/utility/md5.rb'
|
12
|
+
|
13
|
+
class TCMD5 < Test::Unit::TestCase
|
14
|
+
|
15
|
+
def test_simple_build
|
16
|
+
file_name = File.join( $TEST_FILE )
|
17
|
+
MD5.file( file_name )
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# stdlib
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
# common
|
5
|
+
$COMMON_HOME = File.expand_path( File.join( File.dirname( __FILE__), "..", "..", ".." ) )
|
6
|
+
$:.unshift( File.join($COMMON_HOME, "lib" ) )
|
7
|
+
$:.unshift( File.join($COMMON_HOME, "test" ) )
|
8
|
+
$TEST_FILE = File.join( $COMMON_HOME, "lib", "tree_visitor.rb" )
|
9
|
+
|
10
|
+
|
11
|
+
require 'tree_visitor/utility/numeric.rb'
|
12
|
+
|
13
|
+
class TCNumeric < Test::Unit::TestCase
|
14
|
+
|
15
|
+
def test_simple
|
16
|
+
assert_equal "10", 10.with_separator
|
17
|
+
assert_equal "10.0", 10.0.with_separator
|
18
|
+
assert_equal "1,000,000", 1000000.with_separator
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# stdlib
|
2
|
+
require "test/unit"
|
3
|
+
|
4
|
+
# common
|
5
|
+
$COMMON_HOME = File.expand_path( File.join( File.dirname( __FILE__), "..") )
|
6
|
+
$:.unshift( File.join($COMMON_HOME, "lib" ) )
|
7
|
+
$:.unshift( File.join($COMMON_HOME, "test" ) )
|
8
|
+
|
9
|
+
require "tree_visitor"
|
10
|
+
|
11
|
+
require "tree_visitor/utility/tc_md5"
|
12
|
+
|
13
|
+
require "tree_visitor/tc_dir_processor"
|
14
|
+
require "tree_visitor/tc_dir_tree_walker"
|
15
|
+
require "tree_visitor/tc_tree_node"
|
16
|
+
require "tree_visitor/tc_tree_node_visitor"
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gf-tree_visitor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- gf
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-22 00:00:00 -07:00
|
13
|
+
default_executable: dirtree.rb
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: giovanni.ferro@gmail.com
|
18
|
+
executables:
|
19
|
+
- dirtree.rb
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- lib/tree_visitor.rb
|
27
|
+
- lib/tree_visitor/abs_node.rb
|
28
|
+
- lib/tree_visitor/build_dir_tree_visitor.rb
|
29
|
+
- lib/tree_visitor/cli/cli_dir_tree.rb
|
30
|
+
- lib/tree_visitor/dir_processor.rb
|
31
|
+
- lib/tree_visitor/dir_tree_walker.rb
|
32
|
+
- lib/tree_visitor/leaf_node.rb
|
33
|
+
- lib/tree_visitor/tree_node.rb
|
34
|
+
- lib/tree_visitor/tree_node_visitor.rb
|
35
|
+
- lib/tree_visitor/utility/md5.rb
|
36
|
+
- lib/tree_visitor/utility/numeric.rb
|
37
|
+
- lib/tree_visitor/visitor/print_node_visitor2.rb
|
38
|
+
- LICENSE
|
39
|
+
- README.rdoc
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/gf/tree_visitor
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.2.0
|
63
|
+
signing_key:
|
64
|
+
specification_version: 2
|
65
|
+
summary: TODO
|
66
|
+
test_files:
|
67
|
+
- test/ts_tree_visitor.rb
|
68
|
+
- test/tree_visitor/tc_dir_processor.rb
|
69
|
+
- test/tree_visitor/tc_dir_tree_walker.rb
|
70
|
+
- test/tree_visitor/tc_tree_node.rb
|
71
|
+
- test/tree_visitor/tc_tree_node_visitor.rb
|
72
|
+
- test/tree_visitor/utility/tc_md5.rb
|
73
|
+
- test/tree_visitor/utility/tc_numeric.rb
|