tree.rb 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.gemtest +0 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +160 -0
  4. data/Rakefile +12 -0
  5. data/bin/tree.rb +9 -0
  6. data/examples/directory_walker/directory_without_subdirectory.rb +37 -0
  7. data/examples/directory_walker/find_files.rb +18 -0
  8. data/examples/directory_walker/print_files.rb +12 -0
  9. data/examples/protovis/directory_to_json_visitor.rb +15 -0
  10. data/examples/protovis/index.html +87 -0
  11. data/examples/protovis/protovis-r3.2.js +277 -0
  12. data/examples/protovis/treevisitor.js +33 -0
  13. data/examples/protovis/treevisitor.png +0 -0
  14. data/lib/tree_visitor.rb +2 -0
  15. data/lib/treevisitor/abs_node.rb +144 -0
  16. data/lib/treevisitor/basic_tree_node_visitor.rb +44 -0
  17. data/lib/treevisitor/cli/cli_tree.rb +121 -0
  18. data/lib/treevisitor/directory_walker.rb +300 -0
  19. data/lib/treevisitor/leaf_node.rb +33 -0
  20. data/lib/treevisitor/tree_node.rb +296 -0
  21. data/lib/treevisitor/tree_node_visitor.rb +120 -0
  22. data/lib/treevisitor/util/dir_processor.rb +46 -0
  23. data/lib/treevisitor/version.rb +4 -0
  24. data/lib/treevisitor/visitors/block_tree_node_visitor.rb +21 -0
  25. data/lib/treevisitor/visitors/build_dir_tree_visitor.rb +57 -0
  26. data/lib/treevisitor/visitors/callback_tree_node_visitor2.rb +48 -0
  27. data/lib/treevisitor/visitors/clone_tree_node_visitor.rb +39 -0
  28. data/lib/treevisitor/visitors/depth_tree_node_visitor.rb +27 -0
  29. data/lib/treevisitor/visitors/directory_to_hash_visitor.rb +33 -0
  30. data/lib/treevisitor/visitors/flat_print_tree_node_visitors.rb +20 -0
  31. data/lib/treevisitor/visitors/print_dir_tree_visitor.rb +21 -0
  32. data/lib/treevisitor/visitors/print_tree_node_visitor.rb +40 -0
  33. data/lib/treevisitor.rb +40 -0
  34. data/lib/treevisitor_cli.rb +7 -0
  35. data/spec/fixtures/test_dir_1/.dir_with_dot/dummy.txt +0 -0
  36. data/spec/fixtures/test_dir_1/dir.1/dir.1.2/file.1.2.1 +0 -0
  37. data/spec/fixtures/test_dir_1/dir.1/file.1.1 +0 -0
  38. data/spec/fixtures/test_dir_1/dir.2/file.2.1 +0 -0
  39. data/spec/fixtures/test_dir_2/[Dsube]/sub/.gitkeep +0 -0
  40. data/spec/spec_helper.rb +27 -0
  41. data/spec/treevisitor/cli/cli_tree_spec.rb +69 -0
  42. data/spec/treevisitor/directory_walker_spec.rb +99 -0
  43. data/spec/treevisitor/tree_dsl_spec.rb +57 -0
  44. data/spec/treevisitor/tree_dsl_with_derived_class1_spec.rb +53 -0
  45. data/spec/treevisitor/tree_dsl_with_derived_class_spec.rb +51 -0
  46. data/spec/treevisitor/tree_node_paths_spec.rb +70 -0
  47. data/spec/treevisitor/tree_node_spec.rb +135 -0
  48. data/spec/treevisitor/tree_node_visitor_delegate_spec.rb +35 -0
  49. data/spec/treevisitor/tree_node_visitor_dsl_spec.rb +66 -0
  50. data/spec/treevisitor/util/dir_processor_spec.rb +13 -0
  51. data/spec/treevisitor/visitors/block_tree_node_visitor_spec.rb +25 -0
  52. data/spec/treevisitor/visitors/callback_tree_node_visitor2_spec.rb +38 -0
  53. data/spec/treevisitor/visitors/depth_tree_node_visitor_spec.rb +28 -0
  54. data/spec/treevisitor/visitors/tree_node_visitors_spec.rb +27 -0
  55. data/tasks/rspec.rake +34 -0
  56. data/tasks/yard.rake +36 -0
  57. data/tree.rb.gemspec +70 -0
  58. metadata +231 -0
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Visitor for DirTreeWalker
5
+ # Prints the node at enter
6
+ # TODO: join this con PrintTreeNodeVisitor
7
+ class PrintDirTreeVisitor # < BasicTreeNodeVisitor
8
+
9
+ def enter_node( pathname )
10
+ puts pathname
11
+ end
12
+
13
+ def exit_node( pathname )
14
+ end
15
+
16
+ def visit_leaf( pathname )
17
+ puts pathname
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+ module TreeVisitor
3
+ #
4
+ # Prints TreeNode names indenting according to depth
5
+ #
6
+ class PrintTreeNodeVisitor # < BasicTreeNodeVisitor
7
+
8
+ def initialize
9
+ @depth = 0
10
+ end
11
+
12
+ def enter_node( tree_node )
13
+ str = ""
14
+ (0...@depth).step {
15
+ str << " |-"
16
+ }
17
+
18
+ if @depth == 0
19
+ puts str + tree_node.name.to_s
20
+ else
21
+ puts str + tree_node.name.to_s
22
+ end
23
+ @depth += 1
24
+ end
25
+
26
+ def exit_node( tree_node )
27
+ @depth -= 1
28
+ end
29
+
30
+ def visit_leaf( leaf_node )
31
+ str = ""
32
+ (0...@depth-1).step {
33
+ str << " |-"
34
+ }
35
+ str << " | "
36
+ puts str + leaf_node.name.to_s
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ #
4
+ # std lib
5
+ #
6
+ require 'pathname'
7
+ require 'yaml'
8
+
9
+ #
10
+ # rubygems
11
+ #
12
+ # require 'rubygems' # rubygems must be loaded from binary file (tree.rb) so $LOAD_PATH is not modified
13
+ require 'json'
14
+ require 'ansi/code'
15
+
16
+ #
17
+ # treevisitor
18
+ #
19
+
20
+ require "treevisitor/version"
21
+ require "treevisitor/abs_node"
22
+ require 'treevisitor/leaf_node'
23
+ require 'treevisitor/tree_node'
24
+ require 'treevisitor/basic_tree_node_visitor'
25
+ require 'treevisitor/tree_node_visitor'
26
+
27
+ require 'treevisitor/directory_walker'
28
+
29
+ #
30
+ # visitors
31
+ #
32
+ require 'treevisitor/visitors/block_tree_node_visitor'
33
+ require 'treevisitor/visitors/build_dir_tree_visitor'
34
+ require 'treevisitor/visitors/callback_tree_node_visitor2'
35
+ require 'treevisitor/visitors/clone_tree_node_visitor'
36
+ require 'treevisitor/visitors/depth_tree_node_visitor'
37
+ require 'treevisitor/visitors/print_dir_tree_visitor'
38
+ require 'treevisitor/visitors/directory_to_hash_visitor'
39
+
40
+ require 'treevisitor/util/dir_processor'
@@ -0,0 +1,7 @@
1
+ #
2
+ # cli
3
+ #
4
+
5
+ require 'optparse'
6
+ require 'treevisitor'
7
+ require "treevisitor/cli/cli_tree"
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # std lib
4
+ #
5
+ require "stringio"
6
+
7
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ require 'treevisitor'
9
+ require 'treevisitor_cli'
10
+ include TreeVisitor
11
+
12
+ FIXTURES = File.expand_path( File.join( File.dirname(__FILE__), "fixtures" ) )
13
+
14
+ def with_output_captured
15
+ old_stdout, old_stderr = $stdout, $stderr
16
+ out = StringIO.new
17
+ err = StringIO.new
18
+ $stdout = out
19
+ $stderr = err
20
+ begin
21
+ yield
22
+ ensure
23
+ $stdout = old_stdout
24
+ $stderr = old_stderr
25
+ end
26
+ { :stdout => out.string, :stderr => err.string }
27
+ end
@@ -0,0 +1,69 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
3
+
4
+ describe CliTree do
5
+
6
+ it "help message" do
7
+ out = with_output_captured do
8
+ args = %w{-h}
9
+ CliTree.new.parse_args(args)
10
+ end
11
+ out[:stdout].should match /Usage:/
12
+ end
13
+
14
+ it "version" do
15
+ out = with_output_captured do
16
+ args = %w{--version}
17
+ CliTree.new.parse_args(args)
18
+ end
19
+ version = TreeVisitor::VERSION
20
+ out[:stdout].should match version
21
+ end
22
+
23
+ it "should accepts switch -d (directories only)" do
24
+ out = with_output_captured do
25
+ args = %w{-d}
26
+ args << File.join(FIXTURES, "test_dir_1")
27
+ CliTree.new.parse_args(args)
28
+ end
29
+ # puts out
30
+ out[:stdout].split("\n").length.should == 6
31
+
32
+ out = with_output_captured do
33
+ args = %w{-da}
34
+ args << File.join(FIXTURES, "test_dir_1")
35
+ CliTree.new.parse_args(args)
36
+ end
37
+ # puts out
38
+ out[:stdout].split("\n").length.should == 7
39
+ end
40
+
41
+ it "should accepts switch -a (all files)" do
42
+ out = with_output_captured do
43
+ args = %w{-a}
44
+ args << File.join(FIXTURES, "test_dir_1")
45
+ CliTree.new.parse_args(args)
46
+ end
47
+ # pp out
48
+ out[:stdout].split("\n").length.should == 11
49
+
50
+ out = with_output_captured do
51
+ args = []
52
+ args << File.join(FIXTURES, "test_dir_1")
53
+ CliTree.new.parse_args(args)
54
+ end
55
+ # puts out
56
+ out[:stdout].split("\n").length.should == 9
57
+ end
58
+
59
+ it "should show tree with inaccessible directories" do
60
+ out = with_output_captured do
61
+ args = []
62
+ args << File.join(FIXTURES, "test_dir_3_with_error")
63
+ CliTree.new.parse_args(args)
64
+ end
65
+ puts out
66
+ out[:stderr].should_not be_empty
67
+ out[:stdout].split("\n").length.should == 4
68
+ end
69
+ end
@@ -0,0 +1,99 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe DirTreeWalker do
5
+
6
+ it "should accept option :ignore" do
7
+ walker = DirTreeWalker.new :ignore => /^\./
8
+ walker.ignore_file?(".thumbnails").should be_true
9
+ walker.ignore_dir?(".thumbnails").should be_true
10
+ end
11
+
12
+ it "should accept option :ignore" do
13
+ walker = DirTreeWalker.new :ignore => ".git"
14
+ walker.ignore_file?(".git").should be_true
15
+ walker.ignore_dir?(".git").should be_true
16
+ end
17
+
18
+
19
+ it "should accept option :ignore_dir" do
20
+ dtw = DirTreeWalker.new :ignore_dir => [/^\./, "private_dir" ]
21
+ dtw.should be_ignore_dir ".git"
22
+ dtw.should be_ignore_dir "private_dir"
23
+ end
24
+
25
+ it "should accept option :ignore_file" do
26
+ dtw = DirTreeWalker.new :ignore_file => [/.xml/, /(ignore)|(orig)/ ]
27
+ dtw.should be_ignore_file "pippo.xml"
28
+ end
29
+
30
+ it "should accept option :match" do
31
+ dtw = DirTreeWalker.new :match => /.jpg/
32
+ dtw.should be_match "foo.jpg"
33
+ end
34
+
35
+ it "should ignore files and directory" do
36
+ walker = DirTreeWalker.new(".")
37
+
38
+ walker.ignore(/^\./)
39
+ walker.ignore_file?(".thumbnails").should be_true
40
+ walker.ignore_dir?(".thumbnails").should be_true
41
+
42
+ walker.ignore_dir("thumbnails")
43
+ walker.ignore_dir?(".thumbnails").should be_true
44
+ walker.ignore_dir?("thumbnails").should be_true
45
+ walker.ignore_dir?("pippo").should be_false
46
+
47
+ walker.ignore_file("xvpics")
48
+ walker.ignore_file?("xvpics").should be_true
49
+
50
+ walker.ignore("sub")
51
+ walker.ignore_file?("[Dsube]").should be_false
52
+ walker.ignore_dir?("[Dsube]").should be_false
53
+ end
54
+
55
+ it "should accumulate file names" do
56
+ dir_tree_walker = DirTreeWalker.new(File.join(FIXTURES, "test_dir_1"))
57
+
58
+ accumulator = []
59
+ visitor = BlockTreeNodeVisitor.new { |pathname| accumulator << File.basename(pathname) }
60
+ dir_tree_walker.run(visitor)
61
+ accumulator.length.should == 9
62
+ accumulator.sort.should == %w{ test_dir_1 dir.1 dir.1.2 file.1.2.1 file.1.1 dir.2 file.2.1 .dir_with_dot dummy.txt }.sort
63
+ end
64
+
65
+ it "should accumulate file names 2" do
66
+ dir_tree_walker = DirTreeWalker.new(File.join(FIXTURES, "test_dir_2"))
67
+ dir_tree_walker.ignore("sub")
68
+
69
+ accumulator = []
70
+ visitor = BlockTreeNodeVisitor.new { |pathname| accumulator << File.basename(pathname) }
71
+ dir_tree_walker.run(visitor)
72
+ accumulator.length.should == 2
73
+ accumulator.sort.should == %w{ [Dsube] test_dir_2 }.sort
74
+ end
75
+
76
+ it "should ignore not accessible directory" do
77
+
78
+ dir = File.join(FIXTURES, "test_dir_3_with_error")
79
+
80
+ f1 = File.join(dir, "no_accessible_dir")
81
+ Dir.rmdir(f1) if File.exist?(f1)
82
+ Dir.mkdir(f1, 0000)
83
+
84
+ f2 = File.join(dir, "accessible_dir")
85
+ Dir.rmdir(f2) if File.exist?(f2)
86
+ Dir.mkdir(f2)
87
+
88
+ dir_tree_walker = DirTreeWalker.new(File.join(FIXTURES, "test_dir_3_with_error"))
89
+ accumulator = []
90
+ visitor = BlockTreeNodeVisitor.new { |pathname| accumulator << File.basename(pathname) }
91
+ dir_tree_walker.run(visitor)
92
+ accumulator.length.should == 2
93
+ accumulator.sort.should == %w{accessible_dir test_dir_3_with_error }.sort
94
+
95
+ # Dir.rmdir(f1)
96
+ # Dir.rmdir(f2)
97
+ end
98
+
99
+ end
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe "TreeNodeDsl" do
5
+
6
+ it "should build tree with dsl" do
7
+ tree = TreeNode.create do
8
+ node "root" do
9
+ leaf "l1"
10
+ leaf "l2"
11
+ node "sub" do
12
+ leaf "l3"
13
+ end
14
+ node "wo leaves"
15
+ end
16
+ end
17
+
18
+ # puts tree.to_str
19
+ out =<<EOS
20
+ root
21
+ |-- l1
22
+ |-- l2
23
+ |-- sub
24
+ | `-- l3
25
+ `-- wo leaves
26
+ EOS
27
+ tree.to_str.should == out
28
+ end
29
+
30
+ it "test_dsl_block_with_arg" do
31
+ tree = TreeNode.create do
32
+ node "root" do |node|
33
+ node.prefix_path=("pre/")
34
+ leaf "l1"
35
+ leaf "l2"
36
+ node "sub" do
37
+ leaf "l3" do |leaf|
38
+ end
39
+ end
40
+ node "woleaves"
41
+ end
42
+ end
43
+
44
+ # puts tree.to_str
45
+ out =<<EOS
46
+ root
47
+ |-- l1
48
+ |-- l2
49
+ |-- sub
50
+ | `-- l3
51
+ `-- woleaves
52
+ EOS
53
+ tree.to_str.should == out
54
+ tree.find("l3").path_with_prefix.should == "pre/root/sub/l3"
55
+ end
56
+
57
+ end
@@ -0,0 +1,53 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe "Tree Node Dsl Derived Class with n-arg constructor" do
5
+
6
+ class ArgsTreeNode < TreeNode
7
+ attr_reader :description
8
+
9
+ def initialize(name, description, parent)
10
+ super(name, parent)
11
+ @description = description
12
+ end
13
+
14
+ def to_s
15
+ "a: #{description}"
16
+ end
17
+ end
18
+
19
+ class ArgsLeafNode < LeafNode
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
+ it "test_derivated_args" do
33
+ tree = TreeNode.create(ArgsTreeNode, ArgsLeafNode) do
34
+ node "root", "droot" do
35
+ leaf "l1", "dl1"
36
+ leaf "l2", "dl2"
37
+ node "sub", "dsub" do
38
+ leaf "l3", "dl3"
39
+ end
40
+ end
41
+ end
42
+
43
+ # puts tree.to_str
44
+ out =<<EOS
45
+ a: droot
46
+ |-- a: dl1
47
+ |-- a: dl2
48
+ `-- a: dsub
49
+ `-- a: dl3
50
+ EOS
51
+ tree.to_str.should == out
52
+ end
53
+ end
@@ -0,0 +1,51 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe "Tree Node Dsl Derived Class with no-arg constructor " 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
+ it "dsl with non-arg constructor" do
19
+ tree = TreeNode.create(DTreeNode, DLeafNode) do
20
+ node "root" do
21
+ leaf "l1"
22
+ leaf "l2"
23
+ node "sub" do
24
+ leaf "l3"
25
+ end
26
+ end
27
+ end
28
+
29
+ # puts tree.to_str
30
+ out =<<EOS
31
+ dt: root
32
+ |-- dl: l1
33
+ |-- dl: l2
34
+ `-- dt: sub
35
+ `-- dl: l3
36
+ EOS
37
+ tree.to_str.should == out
38
+
39
+ tree = DTreeNode.create(DLeafNode) do
40
+ node "root" do
41
+ leaf "l1"
42
+ leaf "l2"
43
+ node "sub" do
44
+ leaf "l3"
45
+ end
46
+ end
47
+ end
48
+ tree.to_str.should == out
49
+ end
50
+
51
+ end
@@ -0,0 +1,70 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe TreeNode do
5
+
6
+ context "paths" do
7
+
8
+ before do
9
+ @tree = TreeNode.new("a")
10
+ ln1 = LeafNode.new("1", @tree)
11
+ ln2 = LeafNode.new("2", @tree)
12
+ @sub_tree = TreeNode.new("b", @tree)
13
+ @ln3 = LeafNode.new("3", @sub_tree)
14
+ @ln4 = LeafNode.new("12", @sub_tree)
15
+ end
16
+
17
+ it "correct path" do
18
+ @tree.path.should == "a"
19
+ @sub_tree.path.should == "a/b"
20
+ @tree.path_with_prefix.should == "a"
21
+ @sub_tree.path_with_prefix.should == "a/b"
22
+ end
23
+
24
+ it "assign prefix path with a /" do
25
+ @tree.prefix_path= "<root>/"
26
+
27
+ @tree.prefix_path.should == "<root>/"
28
+ @tree.path.should == "a"
29
+ @sub_tree.path.should == "a/b"
30
+ @tree.path_with_prefix.should == "<root>/a"
31
+ @sub_tree.path_with_prefix.should == "<root>/a/b"
32
+ end
33
+
34
+ it "assign empty prefix path" do
35
+ @tree.prefix_path= ""
36
+
37
+ @tree.prefix_path.should == "/"
38
+ @tree.path.should == "a"
39
+ @sub_tree.path.should == "a/b"
40
+ @tree.path_with_prefix.should == "/a"
41
+ @sub_tree.path_with_prefix.should == "/a/b"
42
+ end
43
+
44
+ it "assign prefix path wo a /" do
45
+ @tree.prefix_path= "<root>"
46
+
47
+ @tree.prefix_path.should == "<root>/"
48
+ @tree.path_with_prefix.should == "<root>/a"
49
+ @sub_tree.path_with_prefix.should == "<root>/a/b"
50
+ end
51
+
52
+ it "invalidate" do
53
+ @tree.prefix_path="root/"
54
+ @sub_tree.path.should == "a/b"
55
+ @sub_tree.path_with_prefix.should == "root/a/b"
56
+ @sub_tree.depth.should == 2
57
+
58
+ r = TreeNode.new("r")
59
+ r.add_child(@tree)
60
+ @sub_tree.path.should == "r/a/b"
61
+ @sub_tree.path_with_prefix.should == "r/a/b"
62
+
63
+ r.prefix_path="new_root/"
64
+ @sub_tree.path.should == "r/a/b"
65
+ @sub_tree.path_with_prefix.should == "new_root/r/a/b"
66
+ @sub_tree.depth.should == 3
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,135 @@
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
+ @ln4 = LeafNode.new("12", @sub_tree)
84
+ end
85
+
86
+ it "nr_nodes and nr_leaves and nr_children" do
87
+ @tree.nr_nodes.should == 5
88
+ @tree.nr_leaves.should == 4
89
+ @tree.nr_children.should == 1
90
+
91
+ @sub_tree.nr_nodes.should == 2
92
+ @sub_tree.nr_leaves.should == 2
93
+ @sub_tree.nr_children.should == 0
94
+ end
95
+
96
+
97
+ context "find" do
98
+
99
+ it "find by string" do
100
+ @tree.find("a").should === @tree
101
+ @tree.find("b").should === @sub_tree
102
+ @tree.find("3").should === @ln3
103
+ @tree.find("not existent").should be_nil
104
+ end
105
+
106
+ it "find by regex" do
107
+ @tree.find(/[a,b]/).should === @tree
108
+ @tree.find(/[b,c]/).should === @sub_tree
109
+ @tree.find(/\d\d/).should === @ln4
110
+ @tree.find(/not existent/).should be_nil
111
+ end
112
+
113
+ it "find with block" do
114
+ @tree.find { |e| e.content == "a" }.should === @tree
115
+ @tree.find { |e| e.content == "b" }.should === @sub_tree
116
+ @tree.find { |e| e.content == "3" }.should === @ln3
117
+ @tree.find { |e| e.content == "not existent" }.should be_nil
118
+ end
119
+
120
+ it "to_str" do
121
+ out = <<EOS
122
+ a
123
+ |-- 1
124
+ |-- 2
125
+ `-- b
126
+ |-- 3
127
+ `-- 12
128
+ EOS
129
+ @tree.to_str.should == out
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+ end