rubytree 0.9.7 → 1.0.0
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.
- 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
|