rubytree 0.9.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -4
- data/Gemfile.lock +37 -52
- data/README.md +5 -5
- data/Rakefile +19 -19
- data/examples/example_basic.rb +5 -5
- data/lib/rubytree.rb +1 -1
- data/lib/tree.rb +55 -50
- data/lib/tree/binarytree.rb +10 -7
- data/lib/tree/tree_deps.rb +8 -8
- data/lib/tree/utils/camel_case_method_handler.rb +10 -9
- data/lib/tree/utils/hash_converter.rb +6 -4
- data/lib/tree/utils/json_converter.rb +13 -9
- data/lib/tree/utils/metrics_methods.rb +8 -6
- data/lib/tree/utils/path_methods.rb +7 -5
- data/lib/tree/utils/tree_merge_handler.rb +5 -4
- data/lib/tree/utils/utils.rb +3 -0
- data/lib/tree/version.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/tree_spec.rb +17 -17
- data/test/run_test.rb +6 -6
- data/test/test_binarytree.rb +84 -82
- data/test/test_rubytree_require.rb +2 -2
- data/test/test_subclassed_node.rb +13 -12
- data/test/test_thread_and_fiber.rb +3 -3
- data/test/test_tree.rb +479 -484
- metadata +19 -23
- data/TAGS +0 -248
- data/gem_graph.png +0 -0
- data/rubytree.gemspec +0 -90
- data/setup.rb +0 -1585
data/lib/tree/binarytree.rb
CHANGED
@@ -38,7 +38,7 @@
|
|
38
38
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
39
39
|
#
|
40
40
|
|
41
|
-
|
41
|
+
require_relative '../tree'
|
42
42
|
|
43
43
|
module Tree
|
44
44
|
|
@@ -114,7 +114,7 @@ module Tree
|
|
114
114
|
# @raise [ArgumentError] This exception is raised if two children are
|
115
115
|
# already present.
|
116
116
|
def add(child)
|
117
|
-
raise ArgumentError,
|
117
|
+
raise ArgumentError, 'Already has two child nodes' if @children.size == 2
|
118
118
|
|
119
119
|
super(child)
|
120
120
|
end
|
@@ -150,12 +150,12 @@ module Tree
|
|
150
150
|
# @raise [ArgumentError] This exception is raised if a non-hash is passed.
|
151
151
|
# @return [Array] Array of child nodes added
|
152
152
|
def add_from_hash(hashed_subtree)
|
153
|
-
raise ArgumentError,
|
153
|
+
raise ArgumentError, 'Too many children'\
|
154
154
|
if hashed_subtree.size + @children.size > 2
|
155
155
|
super(hashed_subtree)
|
156
156
|
end
|
157
157
|
|
158
|
-
# Performs
|
158
|
+
# Performs in-order traversal (including this node).
|
159
159
|
#
|
160
160
|
# @yieldparam node [Tree::BinaryTreeNode] Each node (in-order).
|
161
161
|
#
|
@@ -164,9 +164,12 @@ module Tree
|
|
164
164
|
#
|
165
165
|
# @since 0.9.0
|
166
166
|
#
|
167
|
+
# @param [Object] block
|
168
|
+
#
|
167
169
|
# @see #each
|
168
170
|
# @see #preordered_each
|
169
171
|
# @see #postordered_each
|
172
|
+
# noinspection RubyUnusedLocalVariable
|
170
173
|
def inordered_each(&block)
|
171
174
|
|
172
175
|
return self.to_enum unless block_given?
|
@@ -179,13 +182,13 @@ module Tree
|
|
179
182
|
node_stack.push(current_node)
|
180
183
|
current_node = current_node.left_child
|
181
184
|
else
|
182
|
-
current_node = node_stack.pop
|
185
|
+
current_node = node_stack.pop
|
183
186
|
yield current_node
|
184
187
|
current_node = current_node.right_child
|
185
188
|
end
|
186
189
|
end
|
187
190
|
|
188
|
-
|
191
|
+
self if block_given?
|
189
192
|
|
190
193
|
end
|
191
194
|
|
@@ -201,7 +204,7 @@ module Tree
|
|
201
204
|
#
|
202
205
|
# @raise [ArgumentError] If the index is out of limits.
|
203
206
|
def set_child_at(child, at_index)
|
204
|
-
raise ArgumentError
|
207
|
+
raise ArgumentError 'A binary tree cannot have more than two children.'\
|
205
208
|
unless (0..1).include? at_index
|
206
209
|
|
207
210
|
@children[at_index] = child
|
data/lib/tree/tree_deps.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# = rubytree_deps.rb - Dependencies for RubyTree
|
4
4
|
#
|
5
|
-
# Centralizes and lists the dependencies
|
5
|
+
# Centralizes and lists the dependencies for the RubyTree gem.
|
6
6
|
#
|
7
7
|
# Author:: Anupam Sengupta (anupamsg@gmail.com)
|
8
8
|
#
|
@@ -40,10 +40,10 @@
|
|
40
40
|
require 'structured_warnings'
|
41
41
|
require 'json'
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
43
|
+
require_relative '../tree/version'
|
44
|
+
require_relative '../tree/utils/metrics_methods'
|
45
|
+
require_relative '../tree/utils/path_methods'
|
46
|
+
require_relative '../tree/utils/camel_case_method_handler'
|
47
|
+
require_relative '../tree/utils/json_converter'
|
48
|
+
require_relative '../tree/utils/tree_merge_handler'
|
49
|
+
require_relative '../tree/utils/hash_converter'
|
@@ -4,9 +4,9 @@
|
|
4
4
|
#
|
5
5
|
# Author:: Anupam Sengupta (anupamsg@gmail.com)
|
6
6
|
#
|
7
|
-
# Time-stamp: <
|
7
|
+
# Time-stamp: <2017-12-21 13:42:15 anupam>
|
8
8
|
#
|
9
|
-
# Copyright (C) 2012, 2013, 2015 Anupam Sengupta <anupamsg@gmail.com>
|
9
|
+
# Copyright (C) 2012, 2013, 2015, 2017 Anupam Sengupta <anupamsg@gmail.com>
|
10
10
|
#
|
11
11
|
# All rights reserved.
|
12
12
|
#
|
@@ -36,6 +36,7 @@
|
|
36
36
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
37
|
#
|
38
38
|
|
39
|
+
require_relative '../../../lib/tree'
|
39
40
|
require 'structured_warnings'
|
40
41
|
|
41
42
|
module Tree::Utils
|
@@ -47,17 +48,17 @@ module Tree::Utils
|
|
47
48
|
# Allow the deprecated CamelCase method names. Display a warning.
|
48
49
|
# :nodoc:
|
49
50
|
def method_missing(meth, *args, &blk)
|
50
|
-
if self.respond_to?(new_method_name = to_snake_case(meth))
|
51
|
-
warn DeprecatedMethodWarning,
|
52
|
-
|
51
|
+
if self.respond_to?((new_method_name = to_snake_case(meth)))
|
52
|
+
warn StructuredWarnings::DeprecatedMethodWarning,
|
53
|
+
'The camelCased methods are deprecated. ' +
|
53
54
|
"Please use #{new_method_name} instead of #{meth}"
|
54
|
-
|
55
|
+
send(new_method_name, *args, &blk)
|
55
56
|
else
|
56
57
|
super
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
|
-
|
61
|
+
protected
|
61
62
|
|
62
63
|
# @!visibility private
|
63
64
|
# Convert a CamelCasedWord to a underscore separated camel_cased_word.
|
@@ -65,11 +66,11 @@ module Tree::Utils
|
|
65
66
|
# @param [String] camel_cased_word The word to be converted to snake_case.
|
66
67
|
# @return [String] the snake_cased_word.
|
67
68
|
def to_snake_case(camel_cased_word)
|
68
|
-
word = camel_cased_word.to_s
|
69
|
+
word = camel_cased_word.to_s
|
69
70
|
word.gsub!(/::/, '/')
|
70
71
|
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
71
72
|
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
72
|
-
word.tr!(
|
73
|
+
word.tr!('-', '_')
|
73
74
|
word.downcase!
|
74
75
|
word
|
75
76
|
end
|
@@ -37,6 +37,8 @@
|
|
37
37
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
38
38
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
39
39
|
|
40
|
+
require_relative '../../../lib/tree/utils/utils'
|
41
|
+
|
40
42
|
module Tree::Utils::HashConverter
|
41
43
|
|
42
44
|
def self.included(base)
|
@@ -92,16 +94,16 @@ module Tree::Utils::HashConverter
|
|
92
94
|
# values that are not hashes or nils.
|
93
95
|
|
94
96
|
def from_hash(hash)
|
95
|
-
raise ArgumentError,
|
97
|
+
raise ArgumentError, 'Argument must be a type of hash'\
|
96
98
|
unless hash.is_a?(Hash)
|
97
99
|
|
98
|
-
raise ArgumentError,
|
100
|
+
raise ArgumentError, 'Hash must have one top-level element'\
|
99
101
|
if hash.size != 1
|
100
102
|
|
101
103
|
root, children = hash.first
|
102
104
|
|
103
105
|
unless [Hash, NilClass].include?(children.class)
|
104
|
-
raise ArgumentError,
|
106
|
+
raise ArgumentError, 'Invalid child. Must be nil or hash.'
|
105
107
|
end
|
106
108
|
|
107
109
|
node = self.new(*root)
|
@@ -138,7 +140,7 @@ module Tree::Utils::HashConverter
|
|
138
140
|
# @return [Array] Array of child nodes added
|
139
141
|
# @see ClassMethods#from_hash
|
140
142
|
def add_from_hash(children)
|
141
|
-
raise ArgumentError,
|
143
|
+
raise ArgumentError, 'Argument must be a type of hash'\
|
142
144
|
unless children.is_a?(Hash)
|
143
145
|
|
144
146
|
child_nodes = []
|
@@ -35,6 +35,7 @@
|
|
35
35
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
36
36
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
37
|
|
38
|
+
require_relative '../utils/utils'
|
38
39
|
require 'json'
|
39
40
|
|
40
41
|
# Provides utility methods to convert a {Tree::TreeNode} to and from
|
@@ -57,21 +58,24 @@ module Tree::Utils::JSONConverter
|
|
57
58
|
# Rails uses JSON in ActiveSupport, and all Rails JSON encoding goes through
|
58
59
|
# +as_json+.
|
59
60
|
#
|
61
|
+
# @param [Object] options
|
62
|
+
#
|
60
63
|
# @see #to_json
|
61
64
|
# @see http://stackoverflow.com/a/6880638/273808
|
65
|
+
# noinspection RubyUnusedLocalVariable
|
62
66
|
def as_json(options = {})
|
63
67
|
|
64
68
|
json_hash = {
|
65
|
-
|
66
|
-
|
67
|
-
|
69
|
+
name: name,
|
70
|
+
content: content,
|
71
|
+
JSON.create_id => self.class.name
|
68
72
|
}
|
69
73
|
|
70
74
|
if has_children?
|
71
|
-
json_hash[
|
75
|
+
json_hash['children'] = children
|
72
76
|
end
|
73
77
|
|
74
|
-
|
78
|
+
json_hash
|
75
79
|
|
76
80
|
end
|
77
81
|
|
@@ -114,13 +118,13 @@ module Tree::Utils::JSONConverter
|
|
114
118
|
# @see http://flori.github.com/json
|
115
119
|
def json_create(json_hash)
|
116
120
|
|
117
|
-
node = new(json_hash[
|
121
|
+
node = new(json_hash['name'], json_hash['content'])
|
118
122
|
|
119
|
-
json_hash[
|
123
|
+
json_hash['children'].each do |child|
|
120
124
|
node << child
|
121
|
-
end if json_hash[
|
125
|
+
end if json_hash['children']
|
122
126
|
|
123
|
-
|
127
|
+
node
|
124
128
|
|
125
129
|
end
|
126
130
|
end
|
@@ -4,9 +4,9 @@
|
|
4
4
|
#
|
5
5
|
# Author:: Anupam Sengupta (anupamsg@gmail.com)
|
6
6
|
#
|
7
|
-
# Time-stamp: <
|
7
|
+
# Time-stamp: <2017-12-21 12:49:25 anupam>
|
8
8
|
#
|
9
|
-
# Copyright (C) 2013, 2015 Anupam Sengupta <anupamsg@gmail.com>
|
9
|
+
# Copyright (C) 2013, 2015, 2017 Anupam Sengupta <anupamsg@gmail.com>
|
10
10
|
#
|
11
11
|
# All rights reserved.
|
12
12
|
#
|
@@ -36,11 +36,13 @@
|
|
36
36
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
37
|
#
|
38
38
|
|
39
|
+
require_relative '../../../lib/tree'
|
39
40
|
require 'structured_warnings'
|
40
41
|
|
41
42
|
module Tree::Utils
|
42
43
|
# Provides utility functions to measure various tree metrics.
|
43
44
|
module TreeMetricsHandler
|
45
|
+
# noinspection RubyUnusedLocalVariable
|
44
46
|
def self.included(base)
|
45
47
|
|
46
48
|
# @!group Metrics and Measures
|
@@ -66,7 +68,7 @@ module Tree::Utils
|
|
66
68
|
# @return [Integer] The total number of nodes in this (sub)tree.
|
67
69
|
# @see #size
|
68
70
|
def length
|
69
|
-
size
|
71
|
+
self.size
|
70
72
|
end
|
71
73
|
|
72
74
|
# @!attribute [r] node_height
|
@@ -127,9 +129,9 @@ module Tree::Utils
|
|
127
129
|
#
|
128
130
|
# @see #node_depth
|
129
131
|
def depth
|
130
|
-
warn DeprecatedMethodWarning,
|
131
|
-
|
132
|
-
|
132
|
+
warn StructuredWarnings::DeprecatedMethodWarning,
|
133
|
+
'This method is deprecated. '\
|
134
|
+
'Please use node_depth() or node_height() instead (bug # 22535)'
|
133
135
|
|
134
136
|
return 1 if is_leaf?
|
135
137
|
1 + @children.collect { |child| child.depth }.max
|
@@ -36,9 +36,12 @@
|
|
36
36
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
37
|
#
|
38
38
|
|
39
|
+
require_relative '../../../lib/tree'
|
40
|
+
|
39
41
|
module Tree::Utils
|
40
42
|
# Provides utility methods for path extraction
|
41
43
|
module TreePathHandler
|
44
|
+
# noinspection RubyUnusedLocalVariable
|
42
45
|
def self.included(base)
|
43
46
|
|
44
47
|
# @!group Node Path
|
@@ -53,7 +56,7 @@ module Tree::Utils
|
|
53
56
|
# @return [String] The node path with names separated using the specified
|
54
57
|
# separator.
|
55
58
|
def path_as_string(separator = '=>')
|
56
|
-
path_as_array
|
59
|
+
path_as_array.join(separator)
|
57
60
|
end
|
58
61
|
|
59
62
|
# Returns the node-names from this node to the root as an array. The first
|
@@ -61,8 +64,8 @@ module Tree::Utils
|
|
61
64
|
#
|
62
65
|
# @return [Array] The array containing the node names for the path to this
|
63
66
|
# node
|
64
|
-
def path_as_array
|
65
|
-
get_path_name_array
|
67
|
+
def path_as_array
|
68
|
+
get_path_name_array.reverse
|
66
69
|
end
|
67
70
|
|
68
71
|
# @!visibility private
|
@@ -76,10 +79,9 @@ module Tree::Utils
|
|
76
79
|
path_array = current_array_path + [name]
|
77
80
|
|
78
81
|
if !parent # If detached node or root node.
|
79
|
-
|
82
|
+
path_array
|
80
83
|
else # Else recurse to parent node.
|
81
84
|
path_array = parent.get_path_name_array(path_array)
|
82
|
-
return path_array
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
@@ -35,6 +35,8 @@
|
|
35
35
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
36
36
|
#
|
37
37
|
|
38
|
+
require_relative '../../../lib/tree/utils/utils'
|
39
|
+
|
38
40
|
# Provides utility methods to merge two {Tree::TreeNode} based trees.
|
39
41
|
# @since 0.9.0
|
40
42
|
module Tree::Utils::TreeMergeHandler
|
@@ -60,8 +62,7 @@ module Tree::Utils::TreeMergeHandler
|
|
60
62
|
# have the same root node as self.
|
61
63
|
def merge(other_tree)
|
62
64
|
check_merge_prerequisites(other_tree)
|
63
|
-
|
64
|
-
return new_tree
|
65
|
+
merge_trees(self.root.dup, other_tree.root)
|
65
66
|
end
|
66
67
|
|
67
68
|
# Merge in another tree (that shares the same root node) into +this+ tree.
|
@@ -102,7 +103,7 @@ module Tree::Utils::TreeMergeHandler
|
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
105
|
-
# Utility function to
|
106
|
+
# Utility function to recursively merge two subtrees.
|
106
107
|
#
|
107
108
|
# @author Darren Oakley (https://github.com/dazoakley)
|
108
109
|
#
|
@@ -123,7 +124,7 @@ module Tree::Utils::TreeMergeHandler
|
|
123
124
|
merge_trees( child, tree2[child.name] ) unless tree2[child.name].nil?
|
124
125
|
end
|
125
126
|
|
126
|
-
|
127
|
+
tree1
|
127
128
|
end
|
128
129
|
|
129
130
|
end
|
data/lib/tree/utils/utils.rb
CHANGED
data/lib/tree/version.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#
|
5
5
|
# Author:: Anupam Sengupta (anupamsg@gmail.com)
|
6
6
|
#
|
7
|
-
# Copyright (c) 2012, 2013, 2014, 2015 Anupam Sengupta
|
7
|
+
# Copyright (c) 2012, 2013, 2014, 2015, 2017 Anupam Sengupta
|
8
8
|
#
|
9
9
|
# All rights reserved.
|
10
10
|
#
|
@@ -37,5 +37,5 @@
|
|
37
37
|
#
|
38
38
|
module Tree
|
39
39
|
# Rubytree Package Version
|
40
|
-
VERSION = '0.
|
40
|
+
VERSION = '1.0.0'
|
41
41
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/tree_spec.rb
CHANGED
@@ -7,12 +7,12 @@
|
|
7
7
|
# Copyright (C) 2015 Anupam Sengupta <anupamsg@gmail.com>
|
8
8
|
#
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
10
|
+
require 'rspec'
|
11
|
+
require 'spec_helper'
|
12
12
|
|
13
13
|
describe Tree do
|
14
14
|
|
15
|
-
shared_examples_for
|
15
|
+
shared_examples_for 'any detached node' do
|
16
16
|
it 'should not equal "Object.new"' do
|
17
17
|
expect(@tree).not_to eq(Object.new)
|
18
18
|
end
|
@@ -22,53 +22,53 @@ describe Tree do
|
|
22
22
|
it 'identifies itself as a root node' do
|
23
23
|
expect(@tree.is_root?).to eq(true)
|
24
24
|
end
|
25
|
-
it
|
25
|
+
it 'does not have a parent node' do
|
26
26
|
expect(@tree.parent).to eq(nil)
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
30
|
-
context
|
30
|
+
context '#initialize', 'with empty name and nil content' do
|
31
31
|
before(:each) do
|
32
|
-
@tree = Tree::TreeNode.new(
|
32
|
+
@tree = Tree::TreeNode.new('')
|
33
33
|
end
|
34
34
|
it 'creates the tree node with name as ""' do
|
35
|
-
expect(@tree.name).to eq(
|
35
|
+
expect(@tree.name).to eq('')
|
36
36
|
end
|
37
37
|
it "has 'nil' content" do
|
38
38
|
expect(@tree.content).to eq(nil)
|
39
39
|
end
|
40
40
|
|
41
|
-
it_behaves_like
|
41
|
+
it_behaves_like 'any detached node'
|
42
42
|
end
|
43
43
|
|
44
|
-
context
|
44
|
+
context '#initialize', "with name 'A' and nil content" do
|
45
45
|
before(:each) do
|
46
|
-
@tree = Tree::TreeNode.new(
|
46
|
+
@tree = Tree::TreeNode.new('A')
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'creates the tree node with name as "A"' do
|
50
|
-
expect(@tree.name).to eq(
|
50
|
+
expect(@tree.name).to eq('A')
|
51
51
|
end
|
52
52
|
it "has 'nil' content" do
|
53
53
|
expect(@tree.content).to eq(nil)
|
54
54
|
end
|
55
55
|
|
56
|
-
it_behaves_like
|
56
|
+
it_behaves_like 'any detached node'
|
57
57
|
end
|
58
58
|
|
59
|
-
context
|
59
|
+
context '#initialize', "with node name 'A' and some content" do
|
60
60
|
before(:each) do
|
61
|
-
@sample =
|
62
|
-
@tree = Tree::TreeNode.new(
|
61
|
+
@sample = 'sample'
|
62
|
+
@tree = Tree::TreeNode.new('A', @sample)
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'creates the tree node with name as "A"' do
|
66
|
-
expect(@tree.name).to eq(
|
66
|
+
expect(@tree.name).to eq('A')
|
67
67
|
end
|
68
68
|
it "has some content #{@sample}" do
|
69
69
|
expect(@tree.content).to eq(@sample)
|
70
70
|
end
|
71
71
|
|
72
|
-
it_behaves_like
|
72
|
+
it_behaves_like 'any detached node'
|
73
73
|
end
|
74
74
|
end
|