rubytree 0.9.4 → 0.9.5pre

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eef38e74f8b74480e08fbe55be05ae1ce1fd3f18
4
- data.tar.gz: ef1aa978ef83d54e4645a8d3cf5d7fc8fa77b547
3
+ metadata.gz: 93e0fdbd846f7fada7cd50d0e0ab414834f464dc
4
+ data.tar.gz: 3e70254cbc163580c3b7e40a497292a8e4d15128
5
5
  SHA512:
6
- metadata.gz: 1f4aef945397df03a11cc80ec577b00cc029c48974f005977782a60b8b6b0ac13e15555eab225b829f4170c6755e1f8a62b19e832cfc04163bdedbdbd2e06719
7
- data.tar.gz: cc6a69fe2a88e2a2cbf67982f1547bfd0386efa2e93058de001be9cdacd14c3a7add097b72938880b78577b3e5f245df13b9e697a45cc7db302475d9ffec9e67
6
+ metadata.gz: 957a7cdbb556f41f9c599f82483f058e72cf432837a73bf71d1c86a26c0a3f1c2e1d3a8706a419d1c057b46920215ba2b9046bd83f10720efe46f3bb29bb2486
7
+ data.tar.gz: e74fb819ae9e568a1d5409f98ae89c18e0bd85f98300df7cc272dbfa9a7c4f01aa1d9474a8bc7fbb0f334019e3b045e2313621f16b2276aaf206bec24f241c6e
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubytree (0.9.4)
4
+ rubytree (0.9.5pre)
5
5
  json (~> 1.8)
6
6
  structured_warnings (~> 0.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- coveralls (0.7.0)
11
+ coveralls (0.7.1)
12
12
  multi_json (~> 1.3)
13
13
  rest-client
14
14
  simplecov (>= 0.7)
@@ -16,27 +16,29 @@ GEM
16
16
  thor
17
17
  docile (1.1.5)
18
18
  json (1.8.1)
19
- mime-types (2.3)
19
+ mime-types (2.4.3)
20
20
  multi_json (1.10.1)
21
+ netrc (0.8.0)
21
22
  rake (10.3.2)
22
- rdoc (4.1.1)
23
+ rdoc (4.1.2)
23
24
  json (~> 1.4)
24
- rest-client (1.6.7)
25
- mime-types (>= 1.16)
25
+ rest-client (1.7.2)
26
+ mime-types (>= 1.16, < 3.0)
27
+ netrc (~> 0.7)
26
28
  rtags (0.98)
27
29
  rtagstask (0.0.4)
28
30
  rtags (> 0.0.0)
29
- simplecov (0.8.2)
31
+ simplecov (0.9.1)
30
32
  docile (~> 1.1.0)
31
- multi_json
33
+ multi_json (~> 1.0)
32
34
  simplecov-html (~> 0.8.0)
33
35
  simplecov-html (0.8.0)
34
36
  structured_warnings (0.1.4)
35
37
  term-ansicolor (1.3.0)
36
38
  tins (~> 1.0)
37
39
  thor (0.19.1)
38
- tins (1.3.0)
39
- yard (0.8.7.4)
40
+ tins (1.3.3)
41
+ yard (0.8.7.6)
40
42
 
41
43
  PLATFORMS
42
44
  ruby
data/History.rdoc CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  = History of Changes
4
4
 
5
+ === 0.9.5pre / 2014-11-01
6
+
7
+ * Fixed {issue 13}[https://github.com/evolve75/RubyTree/issues/13] with the
8
+ patch provided by {Jen Hamon}[http://www.github.com/jhamon].
9
+
10
+ * Fixed a bug in {Tree::TreeNode#print_tree} with the patch provided by
11
+ {https://github.com/packetmonkey Evan Sharp}.
12
+
13
+ * Fixed {issue 31}[https://github.com/evolve75/RubyTree/issues/31], which was
14
+ causing incorrect behavior n {Tree::TreeNode#postordered_each} and
15
+ {Tree::TreeNode#breadth_each} methods when a block was not provided.
16
+
5
17
  === 0.9.4 / 2014-07-04
6
18
 
7
19
  * Changed all references to {http://rubyforge.org}.
data/README.md CHANGED
@@ -210,6 +210,7 @@ A big thanks to the following contributors for helping improve **RubyTree**:
210
210
  duplicate node names in the tree (globally unique names).
211
211
  6. [Paul de Courcel](https://github.com/pdecourcel) for adding the
212
212
  `postordered_each` method.
213
+ 7. [Jen Hamon](http://www.github.com/jhamon) for adding the `from_hash` method.
213
214
 
214
215
  ## LICENSE: ##
215
216
 
data/TAGS ADDED
@@ -0,0 +1,242 @@
1
+
2
+ lib/rubytree.rb,0
3
+
4
+ lib/tree/binarytree.rb,795
5
+ module Tree::Tree43,1906
6
+ class BinaryTreeNode::Tree::BinaryTreeNode52,2215
7
+ def left_child::Tree::BinaryTreeNode#left_child62,2498
8
+ def right_child::Tree::BinaryTreeNode#right_child74,2889
9
+ def is_left_child?::Tree::BinaryTreeNode#is_left_child?83,3165
10
+ def is_right_child?::Tree::BinaryTreeNode#is_right_child?93,3496
11
+ def add::Tree::BinaryTreeNode#add110,4153
12
+ def add_from_hash::Tree::BinaryTreeNode#add_from_hash143,5539
13
+ def inordered_each::Tree::BinaryTreeNode#inordered_each160,6096
14
+ def set_child_at::Tree::BinaryTreeNode#set_child_at191,7032
15
+ def left_child=::Tree::BinaryTreeNode#left_child=210,7700
16
+ def right_child=::Tree::BinaryTreeNode#right_child=222,8069
17
+ def swap_children::Tree::BinaryTreeNode#swap_children227,8215
18
+
19
+ lib/tree/tree_deps.rb,0
20
+
21
+ lib/tree/utils/camel_case_method_handler.rb,324
22
+ module Tree::Tree41,1848
23
+ module CamelCaseMethodHandler::Tree::CamelCaseMethodHandler44,2004
24
+ def self.included::Tree::CamelCaseMethodHandler.included45,2038
25
+ def method_missing::Tree::CamelCaseMethodHandler#method_missing49,2186
26
+ def to_snake_case::Tree::CamelCaseMethodHandler#to_snake_case66,2798
27
+
28
+ lib/tree/utils/hash_converter.rb,265
29
+ module Tree::Tree40,1916
30
+ def self.included::Tree.included42,1953
31
+ module ClassMethods::Tree::ClassMethods49,2177
32
+ def from_hash::Tree::ClassMethods#from_hash86,3823
33
+ def add_from_hash::Tree#add_from_hash129,5519
34
+ def to_h::Tree#to_h151,6367
35
+
36
+ lib/tree/utils/json_converter.rb,258
37
+ module Tree::Tree42,1925
38
+ def self.included::Tree.included44,1962
39
+ def as_json::Tree#as_json61,2413
40
+ def to_json::Tree#to_json89,3121
41
+ module ClassMethods::Tree::ClassMethods94,3271
42
+ def json_create::Tree::ClassMethods#json_create113,3986
43
+
44
+ lib/tree/utils/metrics_methods.rb,718
45
+ module Tree::Tree41,1833
46
+ module TreeMetricsHandler::Tree::TreeMetricsHandler43,1918
47
+ def self.included::Tree::TreeMetricsHandler.included44,1948
48
+ def size::Tree::TreeMetricsHandler#size56,2317
49
+ def length::Tree::TreeMetricsHandler#length67,2661
50
+ def node_height::Tree::TreeMetricsHandler#node_height80,3078
51
+ def node_depth::Tree::TreeMetricsHandler#node_depth96,3689
52
+ def level::Tree::TreeMetricsHandler#level105,3875
53
+ def depth::Tree::TreeMetricsHandler#depth124,4560
54
+ def breadth::Tree::TreeMetricsHandler#breadth140,5197
55
+ def in_degree::Tree::TreeMetricsHandler#in_degree154,5660
56
+ def out_degree::Tree::TreeMetricsHandler#out_degree165,5973
57
+
58
+ lib/tree/utils/tree_merge_handler.rb,214
59
+ module Tree::Tree40,1769
60
+ def merge::Tree#merge57,2500
61
+ def merge!::Tree#merge!72,3134
62
+ def check_merge_prerequisites::Tree#check_merge_prerequisites85,3441
63
+ def merge_trees::Tree#merge_trees102,4086
64
+
65
+ lib/tree/utils/utils.rb,27
66
+ module Tree::Tree39,1838
67
+
68
+ lib/tree/version.rb,27
69
+ module Tree::Tree38,1723
70
+
71
+ lib/tree.rb,2790
72
+ module Tree::Tree48,2158
73
+ class TreeNode::Tree::TreeNode85,3731
74
+ attr_reader :name::Tree::TreeNode#name109,4522
75
+ attr_accessor :content::Tree::TreeNode#content116,4721
76
+ attr_reader :parent::Tree::TreeNode#parent120,4837
77
+ def root::Tree::TreeNode#root127,5049
78
+ def is_root?::Tree::TreeNode#is_root?138,5355
79
+ def has_content?::Tree::TreeNode#has_content?146,5538
80
+ def is_leaf?::Tree::TreeNode#is_leaf?157,5792
81
+ def parentage::Tree::TreeNode#parentage169,6167
82
+ def has_children?::Tree::TreeNode#has_children?187,6593
83
+ def initialize::Tree::TreeNode#Tree::TreeNode.new210,7419
84
+ def detached_copy::Tree::TreeNode#detached_copy228,8036
85
+ def detached_subtree_copy::Tree::TreeNode#detached_subtree_copy238,8322
86
+ alias :dup::Tree::TreeNode#dup247,8583
87
+ def marshal_dump::Tree::TreeNode#marshal_dump252,8761
88
+ def create_dump_rep::Tree::TreeNode#create_dump_rep258,8929
89
+ def marshal_load::Tree::TreeNode#marshal_load273,9467
90
+ def to_s::Tree::TreeNode#to_s298,10251
91
+ def <<::Tree::TreeNode#<<321,11022
92
+ def add::Tree::TreeNode#add356,12550
93
+ def insertion_range::Tree::TreeNode#insertion_range376,13512
94
+ def replace!::Tree::TreeNode#replace!391,13930
95
+ def replace_with::Tree::TreeNode#replace_with405,14303
96
+ def remove!::Tree::TreeNode#remove!423,15035
97
+ def parent=::Tree::TreeNode#parent=438,15438
98
+ def remove_from_parent!::Tree::TreeNode#remove_from_parent!451,15823
99
+ def remove_all!::Tree::TreeNode#remove_all!462,16195
100
+ def set_as_root!::Tree::TreeNode#set_as_root!473,16424
101
+ def freeze_tree!::Tree::TreeNode#freeze_tree!483,16750
102
+ def []::Tree::TreeNode#[]523,18268
103
+ def each::Tree::TreeNode#each548,19235
104
+ def preordered_each::Tree::TreeNode#preordered_each576,20195
105
+ def postordered_each::Tree::TreeNode#postordered_each588,20607
106
+ def breadth_each::Tree::TreeNode#breadth_each624,22052
107
+ def children::Tree::TreeNode#children650,23005
108
+ def each_leaf::Tree::TreeNode#each_leaf671,23626
109
+ def first_child::Tree::TreeNode#first_child688,24048
110
+ def last_child::Tree::TreeNode#last_child696,24259
111
+ def first_sibling::Tree::TreeNode#first_sibling712,24706
112
+ def is_first_sibling?::Tree::TreeNode#is_first_sibling?722,24980
113
+ def last_sibling::Tree::TreeNode#last_sibling736,25396
114
+ def is_last_sibling?::Tree::TreeNode#is_last_sibling?746,25666
115
+ def siblings::Tree::TreeNode#siblings762,26219
116
+ def is_only_child?::Tree::TreeNode#is_only_child?781,26771
117
+ def next_sibling::Tree::TreeNode#next_sibling794,27174
118
+ def previous_sibling::Tree::TreeNode#previous_sibling810,27648
119
+ def <=>::Tree::TreeNode#<=>826,28159
120
+ def print_tree::Tree::TreeNode#print_tree836,28539
121
+
122
+ test/run_test.rb,0
123
+
124
+ test/test_binarytree.rb,1361
125
+ module TestTree::TestTree39,1717
126
+ class TestBinaryTreeNode::TestTree::TestBinaryTreeNode41,1776
127
+ def setup::TestTree::TestBinaryTreeNode#setup44,1868
128
+ def teardown::TestTree::TestBinaryTreeNode#teardown52,2171
129
+ def test_initialize::TestTree::TestBinaryTreeNode#test_initialize59,2330
130
+ def test_from_hash::TestTree::TestBinaryTreeNode#test_from_hash66,2692
131
+ def test_add_from_hash::TestTree::TestBinaryTreeNode#test_add_from_hash101,4024
132
+ def test_add::TestTree::TestBinaryTreeNode#test_add134,5134
133
+ def test_inordered_each::TestTree::TestBinaryTreeNode#test_inordered_each157,6048
134
+ def test_left_child::TestTree::TestBinaryTreeNode#test_left_child201,7516
135
+ def test_right_child::TestTree::TestBinaryTreeNode#test_right_child209,7829
136
+ def test_left_child_equals::TestTree::TestBinaryTreeNode#test_left_child_equals217,8142
137
+ def test_right_child_equals::TestTree::TestBinaryTreeNode#test_right_child_equals236,9132
138
+ def test_is_left_child_eh::TestTree::TestBinaryTreeNode#test_is_left_child_eh256,10249
139
+ def test_is_right_child_eh::TestTree::TestBinaryTreeNode#test_is_right_child_eh271,10788
140
+ def test_swap_children::TestTree::TestBinaryTreeNode#test_swap_children285,11334
141
+ def test_old_camelCase_method_names::TestTree::TestBinaryTreeNode#test_old_camelCase_method_names303,12217
142
+
143
+ test/test_rubytree_require.rb,203
144
+ module TestTree::TestTree38,1678
145
+ class TestRequireRubytree::TestTree::TestRequireRubytree41,1759
146
+ def test_create_a_simple_node::TestTree::TestRequireRubytree#test_create_a_simple_node44,1884
147
+
148
+ test/test_subclassed_node.rb,389
149
+ module TestTree::TestTree39,1688
150
+ class TestSubclassedTreeNode::TestTree::TestSubclassedTreeNode42,1741
151
+ class MyNode::TestTree::TestSubclassedTreeNode::MyNode45,1868
152
+ def my_dummy_method::TestTree::TestSubclassedTreeNode::MyNode#my_dummy_method47,1967
153
+ def test_subclassed_camelcase_methods::TestTree::TestSubclassedTreeNode#test_subclassed_camelcase_methods52,2026
154
+
155
+ test/test_thread_and_fiber.rb,422
156
+ module TestTree::TestTree39,1695
157
+ class TestFiberAndThreadOnNode::TestTree::TestFiberAndThreadOnNode41,1747
158
+ def create_long_depth_trees::TestTree::TestFiberAndThreadOnNode#create_long_depth_trees44,1843
159
+ def test_fiber_for_recursion::TestTree::TestFiberAndThreadOnNode#test_fiber_for_recursion59,2260
160
+ def test_thread_for_recursion::TestTree::TestFiberAndThreadOnNode#test_thread_for_recursion73,2807
161
+
162
+ test/test_tree.rb,6262
163
+ module TestTree::TestTree39,1725
164
+ class TestTreeNode::TestTree::TestTreeNode41,1777
165
+ def setup::TestTree::TestTreeNode#setup65,2610
166
+ def setup_test_tree::TestTree::TestTreeNode#setup_test_tree77,3030
167
+ def teardown::TestTree::TestTreeNode#teardown84,3180
168
+ def test_has_version_number::TestTree::TestTreeNode#test_has_version_number89,3272
169
+ def test_root_setup::TestTree::TestTreeNode#test_root_setup94,3423
170
+ def test_root::TestTree::TestTreeNode#test_root111,4473
171
+ def test_from_hash::TestTree::TestTreeNode#test_from_hash123,4974
172
+ def test_from_hash_with_nils::TestTree::TestTreeNode#test_from_hash_with_nils175,6546
173
+ def test_add_from_hash::TestTree::TestTreeNode#test_add_from_hash221,7902
174
+ def test_to_h::TestTree::TestTreeNode#test_to_h253,8917
175
+ def test_to_h_from_hash_symmetry::TestTree::TestTreeNode#test_to_h_from_hash_symmetry279,9496
176
+ def test_has_content_eh::TestTree::TestTreeNode#test_has_content_eh295,9894
177
+ def test_length_is_size::TestTree::TestTreeNode#test_length_is_size306,10352
178
+ def test_spaceship::TestTree::TestTreeNode#test_spaceship312,10542
179
+ def test_is_comparable::TestTree::TestTreeNode#test_is_comparable338,11325
180
+ def test_to_s::TestTree::TestTreeNode#test_to_s356,12107
181
+ def test_first_sibling::TestTree::TestTreeNode#test_first_sibling389,13825
182
+ def test_is_first_sibling_eh::TestTree::TestTreeNode#test_is_first_sibling_eh402,14553
183
+ def test_is_last_sibling_eh::TestTree::TestTreeNode#test_is_last_sibling_eh413,15036
184
+ def test_last_sibling::TestTree::TestTreeNode#test_last_sibling424,15504
185
+ def test_siblings::TestTree::TestTreeNode#test_siblings436,16158
186
+ def test_is_only_child_eh::TestTree::TestTreeNode#test_is_only_child_eh464,17081
187
+ def test_next_sibling::TestTree::TestTreeNode#test_next_sibling475,17517
188
+ def test_previous_sibling::TestTree::TestTreeNode#test_previous_sibling486,18017
189
+ def test_add::TestTree::TestTreeNode#test_add497,18546
190
+ def test_add_duplicate::TestTree::TestTreeNode#test_add_duplicate518,19228
191
+ def test_add_at_specific_position::TestTree::TestTreeNode#test_add_at_specific_position559,20656
192
+ def test_replace_bang::TestTree::TestTreeNode#test_replace_bang623,23711
193
+ def test_replace_with::TestTree::TestTreeNode#test_replace_with647,24756
194
+ def test_remove_bang::TestTree::TestTreeNode#test_remove_bang665,25481
195
+ def test_remove_all_bang::TestTree::TestTreeNode#test_remove_all_bang697,26444
196
+ def test_remove_from_parent_bang::TestTree::TestTreeNode#test_remove_from_parent_bang707,26750
197
+ def test_children::TestTree::TestTreeNode#test_children726,27465
198
+ def test_first_child::TestTree::TestTreeNode#test_first_child762,29054
199
+ def test_last_child::TestTree::TestTreeNode#test_last_child771,29382
200
+ def test_find::TestTree::TestTreeNode#test_find780,29698
201
+ def test_parentage::TestTree::TestTreeNode#test_parentage795,30293
202
+ def test_each::TestTree::TestTreeNode#test_each804,30625
203
+ def test_each_leaf::TestTree::TestTreeNode#test_each_leaf823,31309
204
+ def test_parent::TestTree::TestTreeNode#test_parent850,32504
205
+ def test_indexed_access::TestTree::TestTreeNode#test_indexed_access861,32923
206
+ def test_print_tree::TestTree::TestTreeNode#test_print_tree872,33296
207
+ def test_marshal_dump::TestTree::TestTreeNode#test_marshal_dump879,33456
208
+ alias test_marshal_load::TestTree::TestTreeNode#test_marshal_load921,35578
209
+ def test_collect::TestTree::TestTreeNode#test_collect924,35699
210
+ def test_freeze_tree_bang::TestTree::TestTreeNode#test_freeze_tree_bang934,35965
211
+ def test_content::TestTree::TestTreeNode#test_content948,36487
212
+ def test_depth::TestTree::TestTreeNode#test_depth956,36878
213
+ def do_deprecated_depth::TestTree::TestTreeNode#do_deprecated_depth967,37251
214
+ def test_node_height::TestTree::TestTreeNode#test_node_height985,37819
215
+ def test_node_depth::TestTree::TestTreeNode#test_node_depth1010,39028
216
+ def test_level::TestTree::TestTreeNode#test_level1023,39465
217
+ def test_breadth::TestTree::TestTreeNode#test_breadth1038,40008
218
+ def test_breadth_each::TestTree::TestTreeNode#test_breadth_each1057,40655
219
+ def test_preordered_each::TestTree::TestTreeNode#test_preordered_each1106,42240
220
+ def test_postordered_each::TestTree::TestTreeNode#test_postordered_each1145,43494
221
+ def test_detached_copy::TestTree::TestTreeNode#test_detached_copy1194,45031
222
+ def test_detached_subtree_copy::TestTree::TestTreeNode#test_detached_subtree_copy1211,45759
223
+ def test_has_children_eh::TestTree::TestTreeNode#test_has_children_eh1245,48011
224
+ def test_is_leaf_eh::TestTree::TestTreeNode#test_is_leaf_eh1251,48173
225
+ def test_is_root_eh::TestTree::TestTreeNode#test_is_root_eh1258,48379
226
+ def test_content_equals::TestTree::TestTreeNode#test_content_equals1264,48542
227
+ def test_size::TestTree::TestTreeNode#test_size1272,48807
228
+ def test_lt2::TestTree::TestTreeNode#test_lt21281,49071
229
+ def test_index::TestTree::TestTreeNode#test_index1292,49563
230
+ def test_in_degree::TestTree::TestTreeNode#test_in_degree1313,50659
231
+ def test_out_degree::TestTree::TestTreeNode#test_out_degree1324,51126
232
+ def test_json_serialization::TestTree::TestTreeNode#test_json_serialization1335,51613
233
+ def test_json_deserialization::TestTree::TestTreeNode#test_json_deserialization1359,52413
234
+ def test_json_roundtrip::TestTree::TestTreeNode#test_json_roundtrip1387,53599
235
+ def test_old_camelCase_method_names::TestTree::TestTreeNode#test_old_camelCase_method_names1403,54340
236
+ def test_integer_node_names::TestTree::TestTreeNode#test_integer_node_names1434,55408
237
+ def test_add_node_to_self_as_child::TestTree::TestTreeNode#test_add_node_to_self_as_child1465,56638
238
+ def test_single_node_becomes_leaf::TestTree::TestTreeNode#test_single_node_becomes_leaf1481,57151
239
+ def test_unique_node_names::TestTree::TestTreeNode#test_unique_node_names1493,57572
240
+ def setup_other_test_tree::TestTree::TestTreeNode#setup_other_test_tree1507,57927
241
+ def test_merge::TestTree::TestTreeNode#test_merge1535,58916
242
+ def test_merge_bang::TestTree::TestTreeNode#test_merge_bang1564,60354
data/TODO.org CHANGED
@@ -186,8 +186,18 @@
186
186
 
187
187
 
188
188
 
189
+ * R0.9.5
190
+ ** DONE Pull the =hash= converter code from [[https://github.com/markthomas/RubyTree/commits/master][Mark Thomas]] ([[Issue:13][Issue #13]]). :ARCHIVE:
191
+ CLOSED: [2014-11-01 Sat 20:10]
192
+ This was contributed by @jhamon.
193
+ ** DONE Misc. bug fixes :ARCHIVE:
194
+ CLOSED: [2014-11-01 Sat 20:11]
195
+
196
+
197
+
198
+
189
199
  * Next Release
190
- DEADLINE: <2014-03-02 Sun>
200
+ DEADLINE: <2014-12-01 Mon>
191
201
  ** STARTED [#A] Resolve the infinite loop bug if a node is added to itself as a child :Partial:
192
202
  [[Issue:5][Issue #5.]]
193
203
 
@@ -219,19 +229,15 @@
219
229
  duplicates). This needs to be a hash (to allow O(1) access),
220
230
  and will sacrifice memory. There might be a need to
221
231
  restructure the internals to make better use of memory.
232
+ ** STARTED Convert all documentation to markdown mode.
222
233
  ** TODO Expand the examples section, and add supporting documentation
223
- ** TODO Pull the =hash= converter code from [[https://github.com/markthomas/RubyTree/commits/master][Mark Thomas]] ([[Issue:13][Issue #13]]).
224
- ** TODO Convert all documentation to markdown mode.
225
-
226
-
227
234
  * Unplanned / Not assigned to any release
228
- *** DONE [#A] Migrate the website and references from http://rubyforge.org/
235
+ *** DONE [#A] Migrate the website and references from http://rubyforge.org/ :ARCHIVE:
229
236
  CLOSED: [2014-07-04 Fri 22:18]
230
- *** TODO Create a cycle-detection/validation mechanism to prevent cyclic graphs of nodes.
231
- *** DONE Revert the forced install of rubygem 2.1.11 from [[file:.travis.yml][.travis.yml]]
237
+ *** DONE Revert the forced install of rubygem 2.1.11 from [[file:.travis.yml][.travis.yml]] :ARCHIVE:
232
238
  CLOSED: [2014-01-12 Sun 19:06]
233
239
  The issue seems to have been resolved with the 2.2.1 release of Rubygems.
234
-
240
+ *** TODO Create a cycle-detection/validation mechanism to prevent cyclic graphs of nodes.
235
241
  *** TODO Create a generic validation method to check for various issues in the created tree.
236
242
  *** TODO Add a FAQ document to the project.
237
243
  *** TODO The semantic of length is probably unclear. Should return the node_depth instead (or remove the method)
data/lib/tree.rb CHANGED
@@ -89,6 +89,7 @@ module Tree
89
89
  include Tree::Utils::CamelCaseMethodHandler
90
90
  include Tree::Utils::JSONConverter
91
91
  include Tree::Utils::TreeMergeHandler
92
+ include Tree::Utils::HashConverter
92
93
 
93
94
  # @!group Core Attributes
94
95
 
@@ -380,6 +381,31 @@ module Tree
380
381
 
381
382
  private :insertion_range
382
383
 
384
+
385
+ # Replaces the specified child node with another child node on this node.
386
+ #
387
+ # @param [Tree::TreeNode] old_child The child node to be replaced.
388
+ # @param [Tree::TreeNode] new_child The child node to be replaced with.
389
+ #
390
+ # @return [Tree::TreeNode] The removed child node
391
+ def replace!(old_child, new_child)
392
+ child_index = @children.find_index(old_child)
393
+
394
+ old_child = remove! old_child
395
+ add new_child, child_index
396
+
397
+ return old_child
398
+ end
399
+
400
+ # Replaces the node with another node
401
+ #
402
+ # @param [Tree::TreeNode] node The node to replace this node with
403
+ #
404
+ # @return [Tree::TreeNode] The replaced child node
405
+ def replace_with(node)
406
+ @parent.replace!(self, node)
407
+ end
408
+
383
409
  # Removes the specified child node from this node.
384
410
  #
385
411
  # This method can also be used for *pruning* a sub-tree, in cases where the removed child node is
@@ -560,7 +586,7 @@ module Tree
560
586
  # @return [Tree::TreeNode] this node, if a block if given
561
587
  # @return [Enumerator] an enumerator on this tree, if a block is *not* given
562
588
  def postordered_each(&block)
563
- return self.to_enum unless block_given?
589
+ return self.to_enum(:postordered_each) unless block_given?
564
590
 
565
591
  # Using a marked node in order to skip adding the children of nodes that
566
592
  # have already been visited. This allows the stack depth to be controlled,
@@ -596,7 +622,7 @@ module Tree
596
622
  # @return [Tree::TreeNode] this node, if a block if given
597
623
  # @return [Enumerator] an enumerator on this tree, if a block is *not* given
598
624
  def breadth_each(&block)
599
- return self.to_enum unless block_given?
625
+ return self.to_enum(:breadth_each) unless block_given?
600
626
 
601
627
  node_queue = [self] # Create a queue with self as the initial entry
602
628
 
@@ -805,20 +831,26 @@ module Tree
805
831
  # Pretty prints the (sub)tree rooted at this node.
806
832
  #
807
833
  # @param [Integer] level The indentation level (4 spaces) to start with.
808
- def print_tree(level = 0)
834
+ # @param [Integer] max_depth optional maximum depth at which the printing with stop.
835
+ # @param [Proc] block optional block to use for rendering
836
+ def print_tree(level = 0, max_depth = nil, block = lambda { |node, prefix| puts "#{prefix} #{node.name}" })
837
+ prefix = ''
838
+
809
839
  if is_root?
810
- print "*"
840
+ prefix << '*'
811
841
  else
812
- print "|" unless parent.is_last_sibling?
813
- print(' ' * (level - 1) * 4)
814
- print(is_last_sibling? ? "+" : "|")
815
- print "---"
816
- print(has_children? ? "+" : ">")
842
+ prefix << '|' unless parent.is_last_sibling?
843
+ prefix << (' ' * (level - 1) * 4)
844
+ prefix << (is_last_sibling? ? '+' : '|')
845
+ prefix << '---'
846
+ prefix << (has_children? ? '+' : '>')
817
847
  end
818
848
 
819
- puts " #{name}"
849
+ block.call(self, prefix)
850
+
851
+ return unless max_depth.nil? || level < max_depth # Exit if the max level is defined, and reached.
820
852
 
821
- children { |child| child.print_tree(level + 1) if child } # Child might be 'nil'
853
+ children { |child| child.print_tree(level + 1, max_depth, block) if child } # Child might be 'nil'
822
854
  end
823
855
 
824
856
  end
@@ -8,7 +8,7 @@
8
8
  # Author:: Anupam Sengupta (anupamsg@gmail.com)
9
9
  #
10
10
 
11
- # Copyright (c) 2007, 2008, 2009, 2010, 2012, 2013 Anupam Sengupta
11
+ # Copyright (c) 2007, 2008, 2009, 2010, 2012, 2013, 2014 Anupam Sengupta
12
12
  #
13
13
  # All rights reserved.
14
14
  #
@@ -113,6 +113,38 @@ module Tree
113
113
  super(child)
114
114
  end
115
115
 
116
+
117
+ # Instantiate and insert child nodes from data in a Ruby +Hash+
118
+ #
119
+ # This method is used in conjunction with {Tree::TreeNode.from_hash} to
120
+ # provide a convenient way of building and inserting child nodes present
121
+ # in a Ruby hashes.
122
+ #
123
+ # This method will instantiate a {Tree::TreeNode} instance for each top-
124
+ # level key of the input hash, to be inserted as children of the receiver
125
+ # instance.
126
+ #
127
+ # Nested hashes are expected and further child nodes will be created and
128
+ # added accordingly. If a hash key is a single value that value will be
129
+ # used as the name for the node. If a hash key is an Array, both node
130
+ # name and content will be populated.
131
+ #
132
+ # A leaf element of the tree should be represented as a hash key with
133
+ # corresponding value nil or {}.
134
+ #
135
+ # @example
136
+ # root = Tree::TreeNode.new(:A, "Root content!")
137
+ # root.add_from_hash({:B => {:D => {}}, [:C, "C content!"] => {}})
138
+ #
139
+ # @param [Hash] hashed_subtree The hash of child subtrees.
140
+ # @raise [ArgumentError] This exception is raised if hash contains too many children.
141
+ # @raise [ArgumentError] This exception is raised if a non-hash is passed.
142
+ # @return [Array] Array of child nodes added
143
+ def add_from_hash(hashed_subtree)
144
+ raise ArgumentError, "Too many children" if hashed_subtree.size + @children.size > 2
145
+ super(hashed_subtree)
146
+ end
147
+
116
148
  # Performs inorder traversal (including this node).
117
149
  #
118
150
  # @yieldparam node [Tree::BinaryTreeNode] Each node (in-order).
@@ -45,3 +45,4 @@ require 'tree/utils/metrics_methods'
45
45
  require 'tree/utils/camel_case_method_handler'
46
46
  require 'tree/utils/json_converter'
47
47
  require 'tree/utils/tree_merge_handler'
48
+ require 'tree/utils/hash_converter'
@@ -0,0 +1,161 @@
1
+ # hash_converter.rb - This file is part of the RubyTree package.
2
+ #
3
+ # = hash_converter.rb - Provides utility methods for converting between
4
+ # {Tree::TreeNode} and Ruby's native +Hash+.
5
+ #
6
+ # Author:: Jen Hamon (http://www.github.com/jhamon)
7
+ #
8
+ # Time-stamp: <2014-10-25 16:20:23 anupam>
9
+ #
10
+ # Copyright (C) 2014 Jen Hamon (http://www.github.com/jhamon) and
11
+ # Anupam Sengupta <anupamsg@gmail.com>
12
+ #
13
+ # All rights reserved.
14
+ #
15
+ # Redistribution and use in source and binary forms, with or without modification,
16
+ # are permitted provided that the following conditions are met:
17
+ #
18
+ # - Redistributions of source code must retain the above copyright notice, this
19
+ # list of conditions and the following disclaimer.
20
+ #
21
+ # - Redistributions in binary form must reproduce the above copyright notice, this
22
+ # list of conditions and the following disclaimer in the documentation and/or
23
+ # other materials provided with the distribution.
24
+ #
25
+ # - Neither the name of the organization nor the names of its contributors may
26
+ # be used to endorse or promote products derived from this software without
27
+ # specific prior written permission.
28
+ #
29
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
33
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
36
+ # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
+
40
+ module Tree::Utils::HashConverter
41
+
42
+ def self.included(base)
43
+ base.extend(ClassMethods)
44
+ end
45
+
46
+ # Methods in {Tree::Utils::HashConverter::ClassMethods} will be added as
47
+ # class methods on any class mixing in the {Tree::Utils::HashConverter}
48
+ # module.
49
+ module ClassMethods
50
+
51
+ # Factory method builds a {Tree::TreeNode} from a +Hash+.
52
+ #
53
+ # This method will interpret each key of your +Hash+ as a {Tree::TreeNode}.
54
+ # Nested hashes are expected and child nodes will be added accordingly. If
55
+ # a hash key is a single value that value will be used as the name for the
56
+ # node. If a hash key is an Array, both node name and content will be
57
+ # populated.
58
+ #
59
+ # A leaf element of the tree should be represented as a hash key with
60
+ # corresponding value +nil+ or +{}+.
61
+ #
62
+ # @example
63
+ # TreeNode.from_hash({:A => {:B => {}, :C => {:D => {}, :E => {}}}})
64
+ # # would be parsed into the following tree structure:
65
+ # # A
66
+ # # / \
67
+ # # B C
68
+ # # / \
69
+ # # D E
70
+ #
71
+ # # The same tree would result from this nil-terminated Hash
72
+ # {:A => {:B => nil, :C => {:D => nil, :E => nil}}}
73
+ #
74
+ # # A tree with equivalent structure but with content present for
75
+ # # nodes A and D could be built from a hash like this:
76
+ # {[:A, "A content"] => {:B => {}, :C => {[:D, "D content"] => {}, :E => {}}}}
77
+ #
78
+ # @author Jen Hamon (http://www.github.com/jhamon)
79
+ # @param [Hash] hash Hash to build tree from.
80
+ # @return [Tree::TreeNode] The {Tree::TreeNode} instance representing the root of your tree.
81
+ #
82
+ # @raise [ArgumentError] This exception is raised if a non-Hash is passed.
83
+ # @raise [ArgumentError] This exception is raised if the hash has multiple top-level elements.
84
+ # @raise [ArgumentError] This exception is raised if the hash contains values that are not hashes or nils.
85
+
86
+ def from_hash(hash)
87
+ raise ArgumentError, "Argument must be a type of hash" unless hash.is_a?(Hash)
88
+ raise ArgumentError, "Hash must have one top-level element" if hash.size != 1
89
+
90
+ root, children = hash.first
91
+
92
+ unless [Hash, NilClass].include?(children.class)
93
+ raise ArgumentError, "Invalid child. Must be nil or hash."
94
+ end
95
+
96
+ node = self.new(*root)
97
+ node.add_from_hash(children) unless children.nil?
98
+ node
99
+ end
100
+ end
101
+
102
+ # Instantiate and insert child nodes from data in a Ruby +Hash+
103
+ #
104
+ # This method is used in conjunction with from_hash to provide a
105
+ # convenient way of building and inserting child nodes present in a Ruby
106
+ # hashes.
107
+ #
108
+ # This method will instantiate a node instance for each top-
109
+ # level key of the input hash, to be inserted as children of the receiver
110
+ # instance.
111
+ #
112
+ # Nested hashes are expected and further child nodes will be created and
113
+ # added accordingly. If a hash key is a single value that value will be
114
+ # used as the name for the node. If a hash key is an Array, both node
115
+ # name and content will be populated.
116
+ #
117
+ # A leaf element of the tree should be represented as a hash key with
118
+ # corresponding value +nil+ or {}.
119
+ #
120
+ # @example
121
+ # root = Tree::TreeNode.new(:A, "Root content!")
122
+ # root.add_from_hash({:B => {:D => {}}, [:C, "C content!"] => {}})
123
+ #
124
+ # @author Jen Hamon (http://www.github.com/jhamon)
125
+ # @param [Hash] children The hash of child subtrees.
126
+ # @raise [ArgumentError] This exception is raised if a non-hash is passed.
127
+ # @return [Array] Array of child nodes added
128
+ # @see ClassMethods#from_hash
129
+ def add_from_hash(children)
130
+ raise ArgumentError, "Argument must be a type of hash" unless children.is_a?(Hash)
131
+
132
+ child_nodes = []
133
+ children.each do |child, grandchildren|
134
+ child_node = self.class.from_hash({child => grandchildren})
135
+ child_nodes << child_node
136
+ self << child_node
137
+ end
138
+
139
+ child_nodes
140
+ end
141
+
142
+ # Convert a node and its subtree into a Ruby hash.
143
+ #
144
+ # @example
145
+ # root = Tree::TreeNode.new(:root, "root content")
146
+ # root << Tree::TreeNode.new(:child1, "child1 content")
147
+ # root << Tree::TreeNode.new(:child2, "child2 content")
148
+ # root.to_h # => {[:root, "root content"] => { [:child1, "child1 content"] => {}, [:child2, "child2 content"] => {}}}
149
+ # @author Jen Hamon (http://www.github.com/jhamon)
150
+ # @return [Hash] Hash representation of tree.
151
+ def to_h
152
+ key = has_content? ? [name, content] : name
153
+
154
+ children_hash = {}
155
+ children do |child|
156
+ children_hash.merge! child.to_h
157
+ end
158
+
159
+ { key => children_hash }
160
+ end
161
+ end
@@ -1,12 +1,12 @@
1
- # json.rb - This file is part of the RubyTree package.
1
+ # json_converter.rb - This file is part of the RubyTree package.
2
2
  #
3
- # = json.rb - Provides conversion to and from JSON.
3
+ # = json_converter.rb - Provides conversion to and from JSON.
4
4
  #
5
5
  # Author:: Anupam Sengupta (anupamsg@gmail.com)
6
6
  #
7
- # Time-stamp: <2013-12-31 21:57:42 anupam>
7
+ # Time-stamp: <2014-10-25 16:16:23 anupam>
8
8
  #
9
- # Copyright (C) 2012, 2013 Anupam Sengupta <anupamsg@gmail.com>
9
+ # Copyright (C) 2012, 2013, 2014 Anupam Sengupta <anupamsg@gmail.com>
10
10
  #
11
11
  # All rights reserved.
12
12
  #
data/lib/tree/version.rb CHANGED
@@ -37,5 +37,5 @@
37
37
  #
38
38
  module Tree
39
39
  # Rubytree Package Version
40
- VERSION = '0.9.4'
40
+ VERSION = '0.9.5pre'
41
41
  end
@@ -63,6 +63,73 @@ module TestTree
63
63
  assert_equal(@root.children.size, 0, "Initially no children should be present")
64
64
  end
65
65
 
66
+ def test_from_hash
67
+ # Can make a root note without a name
68
+ assert_raise (ArgumentError) { Tree::BinaryTreeNode.from_hash({})}
69
+ # Can't have multiple roots
70
+ assert_raise (ArgumentError) { Tree::BinaryTreeNode.from_hash({:A => {}, :B => {}}) }
71
+
72
+ # Can't have more than 2 children
73
+ too_many_kids = {:A => {:B => {}, :C => {}, :D => {} } }
74
+ assert_raise(ArgumentError) { Tree::BinaryTreeNode.from_hash(too_many_kids) }
75
+
76
+ valid_hash = {:A => {:B => {}, :C => { :D => {} } } }
77
+ tree = Tree::BinaryTreeNode.from_hash(valid_hash)
78
+ # A
79
+ # / \
80
+ # B C
81
+ # |
82
+ # D
83
+
84
+ assert_same(tree.class, Tree::BinaryTreeNode)
85
+ assert_same(tree.name, :A)
86
+ assert_equal(tree.is_root?, true)
87
+ assert_equal(tree.is_leaf?, false)
88
+ assert_equal(tree.children.count, 2) # B, C, D
89
+ assert_equal(tree.size, 4)
90
+ assert_equal(tree.left_child.name, :B)
91
+ assert_equal(tree.right_child.name, :C)
92
+
93
+ valid_hash_with_content = {[:A, "Content!"] => {:B => {}, :C => { [:D, "More content"] => {} } } }
94
+ tree2 = Tree::BinaryTreeNode.from_hash(valid_hash_with_content)
95
+
96
+ assert_equal(tree2.class, Tree::BinaryTreeNode)
97
+ assert_equal(tree2.content, "Content!" )
98
+ assert_equal(tree2[:C][:D].content, "More content")
99
+ end
100
+
101
+ def test_add_from_hash
102
+ root = Tree::BinaryTreeNode.new("Root")
103
+
104
+ # Can't have too many children
105
+ too_many_kids = {:child1 => {}, :child2 => {}, :child3 => {}}
106
+ assert_raise(ArgumentError) { root.add_from_hash(too_many_kids) }
107
+ assert_equal(root.children.count, 0) # Nothing added
108
+
109
+ # Well behaved when adding nothing
110
+ assert_equal(root.add_from_hash({}), [])
111
+ assert_equal(root.size, 1)
112
+
113
+ valid_hash = {:A => {}, :B => { :C => {}, [:D, "leaf"] => {} } }
114
+ added = root.add_from_hash(valid_hash)
115
+ # root
116
+ # / \
117
+ # A B
118
+ # / \
119
+ # C D
120
+
121
+ assert_equal(added.class, Array)
122
+ assert_equal(added.count, 2)
123
+ assert_equal(root.size, 5)
124
+ assert_equal(root.children.count, 2)
125
+ assert_equal(root[:B][:D].content, "leaf")
126
+
127
+ # Can't add more than two children
128
+ assert_raise(ArgumentError) { root.add_from_hash({:X => {}}) }
129
+ node = Tree::BinaryTreeNode.new("Root 2")
130
+ assert_raise(ArgumentError) { node.add_from_hash({:A => {}, :B => {}, :C => {}}) }
131
+ end
132
+
66
133
  # Test the add method.
67
134
  def test_add
68
135
  @root.add @left_child1
data/test/test_tree.rb CHANGED
@@ -120,6 +120,177 @@ module TestTree
120
120
  assert_equal(2 , @root.node_height, "Root's height after adding the children should be 2")
121
121
  end
122
122
 
123
+ def test_from_hash
124
+ # A
125
+ # / | \
126
+ # B C D
127
+ # / \ /
128
+ # E F G
129
+ # / \
130
+ # H I
131
+
132
+ hash = {[:A, "Root content"] => {
133
+ :B => {
134
+ :E => {},
135
+ :F => {
136
+ :H => {},
137
+ [:I, "Leaf content"] => {}
138
+ }
139
+ },
140
+ :C => {},
141
+ :D => {
142
+ :G => {}
143
+ }
144
+ }
145
+ }
146
+
147
+ tree = Tree::TreeNode.from_hash(hash)
148
+
149
+ assert_same(tree.class, Tree::TreeNode)
150
+ assert_same(tree.name, :A)
151
+ assert_equal(tree.is_root?, true)
152
+ assert_equal(tree.is_leaf?, false)
153
+ assert_equal(tree.size, 9)
154
+ assert_equal(tree.content, "Root content")
155
+ assert_equal(tree.children.count, 3) # B, C, D
156
+
157
+ leaf_with_content = tree[:B][:F][:I]
158
+ assert_equal(leaf_with_content.content, "Leaf content")
159
+ assert_equal(leaf_with_content.is_leaf?, true)
160
+
161
+ leaf_without_content = tree[:C]
162
+ assert_equal(leaf_without_content.is_leaf?, true)
163
+
164
+ interior_node = tree[:B][:F]
165
+ assert_equal(interior_node.is_leaf?, false)
166
+ assert_equal(interior_node.children.count, 2)
167
+
168
+ # Can't make a node without a name
169
+ assert_raise (ArgumentError) { Tree::TreeNode.from_hash({}) }
170
+ # Can't have multiple roots
171
+ assert_raise (ArgumentError) { Tree::TreeNode.from_hash({:A => {}, :B => {}}) }
172
+
173
+ end
174
+
175
+ def test_from_hash_with_nils
176
+ # A
177
+ # / | \
178
+ # B C D
179
+ # / \ /
180
+ # E F G
181
+ # / \
182
+ # H I
183
+
184
+ hash = {[:A, "Root content"] => {
185
+ :B => {
186
+ :E => nil,
187
+ :F => {
188
+ :H => nil,
189
+ [:I, "Leaf content"] => nil
190
+ }
191
+ },
192
+ :C => nil,
193
+ :D => {
194
+ :G => nil
195
+ }
196
+ }
197
+ }
198
+
199
+ tree = Tree::TreeNode.from_hash(hash)
200
+
201
+ assert_same(tree.class, Tree::TreeNode)
202
+ assert_same(tree.name, :A)
203
+ assert_equal(tree.is_root?, true)
204
+ assert_equal(tree.is_leaf?, false)
205
+ assert_equal(tree.size, 9)
206
+ assert_equal(tree.content, "Root content")
207
+ assert_equal(tree.children.count, 3) # B, C, D
208
+
209
+ leaf_with_content = tree[:B][:F][:I]
210
+ assert_equal(leaf_with_content.content, "Leaf content")
211
+ assert_equal(leaf_with_content.is_leaf?, true)
212
+
213
+ leaf_without_content = tree[:C]
214
+ assert_equal(leaf_without_content.is_leaf?, true)
215
+
216
+ interior_node = tree[:B][:F]
217
+ assert_equal(interior_node.is_leaf?, false)
218
+ assert_equal(interior_node.children.count, 2)
219
+ end
220
+
221
+ def test_add_from_hash
222
+ tree = Tree::TreeNode.new(:A)
223
+
224
+ # Doesn't blow up when added an empty hash
225
+ hash = {}
226
+ assert_equal(tree.add_from_hash(hash), [])
227
+
228
+ # Okay, now try a real hash
229
+ hash = {:B => {:C => {:D => nil}, :E => {}, :F => {}}, [:G, "G content"] => {}}
230
+ # A
231
+ # / \
232
+ # B G
233
+ # /|\
234
+ # C E F
235
+ # |
236
+ # D
237
+
238
+ added_children = tree.add_from_hash(hash)
239
+ assert_equal(added_children.class, Array)
240
+ assert_equal(added_children.count, 2)
241
+ assert_equal(tree.size, 7)
242
+ assert_equal(tree[:G].content, "G content")
243
+ assert_equal(tree[:G].is_leaf?, true)
244
+ assert_equal(tree[:B].size, 5)
245
+ assert_equal(tree[:B].children.count, 3)
246
+
247
+ assert_raise (ArgumentError) { tree.add_from_hash([]) }
248
+ assert_raise (ArgumentError) { tree.add_from_hash("not a hash") }
249
+ assert_raise (ArgumentError) { tree.add_from_hash({:X => "Not a hash or nil"}) }
250
+ end
251
+
252
+ # Test exporting to ruby Hash
253
+ def test_to_h
254
+ a = Tree::TreeNode.new(:A)
255
+ b = Tree::TreeNode.new(:B)
256
+ c = Tree::TreeNode.new(:C)
257
+ d = Tree::TreeNode.new(:D)
258
+ e = Tree::TreeNode.new(:E)
259
+ f = Tree::TreeNode.new(:F)
260
+ g = Tree::TreeNode.new(:G)
261
+ # A
262
+ # / \
263
+ # B C
264
+ # | / \
265
+ # E F G
266
+
267
+ a << b
268
+ a << c
269
+ c << f
270
+ c << g
271
+ b << e
272
+
273
+ exported = a.to_h
274
+ expected = {:A => {:B => {:E => {}}, :C => {:F => {}, :G => {}}}}
275
+ assert_equal(exported, expected)
276
+ end
277
+
278
+ # Test that from_hash and to_h are symmetric
279
+ def test_to_h_from_hash_symmetry
280
+ # A
281
+ # / \
282
+ # B C
283
+ # /|\ \
284
+ # E F G H
285
+ # |\ |
286
+ # I J K
287
+
288
+ input = {:A => {:B => {:E => {:I => {}, :J =>{}}, :F => {}, :G => {}}, :C =>{:H => {:K => {}}}}}
289
+
290
+ node = Tree::TreeNode.from_hash(input)
291
+ assert_equal(node.to_h, input)
292
+ end
293
+
123
294
  # Test the presence of content in the nodes.
124
295
  def test_has_content_eh
125
296
  a_node = Tree::TreeNode.new("A Node")
@@ -448,6 +619,48 @@ module TestTree
448
619
  assert_equal(5, @root.children.size, "Should have five child nodes")
449
620
  end
450
621
 
622
+ # Test the replace! and replace_with! methods
623
+ def test_replace_bang
624
+ @root << @child1
625
+ @root << @child2
626
+ @root << @child3
627
+
628
+ assert_equal(4, @root.size, "Should have four nodes")
629
+ assert(@root.children.include?(@child1), "Should parent child1")
630
+ assert(@root.children.include?(@child2), "Should parent child2")
631
+ assert(@root.children.include?(@child3), "Should parent child3")
632
+ assert(!@root.children.include?(@child4), "Should not parent child4")
633
+
634
+ @root.replace!(@child2, @child4)
635
+
636
+ # Also test replacing with a node of the same name
637
+ @root.replace! @child4, @child4.detached_copy
638
+
639
+ assert_equal(4, @root.size, "Should have three nodes")
640
+ assert(@root.children.include?(@child1), "Should parent child1")
641
+ assert(!@root.children.include?(@child2), "Should not parent child2")
642
+ assert(@root.children.include?(@child3), "Should parent child3")
643
+ assert(@root.children.include?(@child4), "Should parent child4")
644
+ assert_equal(1, @root.children.find_index(@child4), "Should add child4 to index 1")
645
+ end
646
+
647
+ def test_replace_with
648
+ @root << @child1
649
+ @root << @child2
650
+
651
+ assert_equal(3, @root.size, "Should have three nodes")
652
+ assert(@root.children.include?(@child1), "Should parent child1")
653
+ assert(@root.children.include?(@child2), "Should parent child2")
654
+ assert(!@root.children.include?(@child3), "Should not parent child3")
655
+
656
+ @child2.replace_with @child3
657
+
658
+ assert_equal(3, @root.size, "Should have three nodes")
659
+ assert(@root.children.include?(@child1), "Should parent child1")
660
+ assert(!@root.children.include?(@child2), "Should not parent child2")
661
+ assert(@root.children.include?(@child3), "Should parent child3")
662
+ end
663
+
451
664
  # Test the remove! and remove_all! methods.
452
665
  def test_remove_bang
453
666
  @root << @child1
@@ -868,17 +1081,25 @@ module TestTree
868
1081
  f << h
869
1082
  j << k << z
870
1083
 
871
- # Create the response
872
- result_array = Array.new
1084
+ # Test when a block is given
1085
+ result_array = []
873
1086
  result = j.breadth_each { |node| result_array << node.detached_copy }
874
1087
 
875
- assert_equal(j, result)
1088
+ assert_equal(j, result) # The invocation target is returned
1089
+
1090
+ expected_array.each_index do |i|
1091
+ assert_equal(expected_array[i].name, result_array[i].name) # Match only the names.
1092
+ end
1093
+
1094
+ assert_equal(Enumerator, j.breadth_each.class) if defined?(Enumerator.class ) # Without a block
1095
+ assert_equal(Enumerable::Enumerator, j.breadth_each.class) if defined?(Enumerable::Enumerator.class) # Without a block
1096
+
1097
+ # Now test without a block
1098
+ result_array = j.breadth_each.collect { |node| node}
876
1099
  expected_array.each_index do |i|
877
1100
  assert_equal(expected_array[i].name, result_array[i].name) # Match only the names.
878
1101
  end
879
1102
 
880
- assert_equal(Enumerator, j.breadth_each.class) if defined?(Enumerator.class )# Without a block
881
- assert_equal(Enumerable::Enumerator, j.breadth_each.class) if defined?(Enumerable::Enumerator.class )# Without a block
882
1103
  end
883
1104
 
884
1105
  # Test the preordered_each method.
@@ -945,18 +1166,28 @@ module TestTree
945
1166
  f << h
946
1167
  j << k << z
947
1168
 
1169
+ # Test when a block is given
948
1170
  result_array = []
949
1171
  result = j.postordered_each { |node| result_array << node.detached_copy}
950
1172
 
951
- assert_equal(j, result) # Each returns the invocation target
1173
+ assert_equal(j, result) # The invocation target is returned
1174
+
1175
+ expected_array.each_index do |i|
1176
+ # Match only the names.
1177
+ assert_equal(expected_array[i].name, result_array[i].name)
1178
+ end
1179
+
1180
+ assert_equal(Enumerator, j.postordered_each.class) if defined?(Enumerator.class) # Without a block
1181
+ assert_equal(Enumerable::Enumerator, j.postordered_each.class) if defined?(Enumerable::Enumerator.class) # Without a block
1182
+
1183
+ # Now test without a block
1184
+ result_array = j.postordered_each.collect { |node| node }
952
1185
 
953
1186
  expected_array.each_index do |i|
954
1187
  # Match only the names.
955
1188
  assert_equal(expected_array[i].name, result_array[i].name)
956
1189
  end
957
1190
 
958
- assert_equal(Enumerator, j.postordered_each.class) if defined?(Enumerator.class )# Without a block
959
- assert_equal(Enumerable::Enumerator, j.postordered_each.class) if defined?(Enumerable::Enumerator.class )# Without a block
960
1191
  end
961
1192
 
962
1193
  # test the detached_copy method.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubytree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anupam Sengupta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-03 00:00:00.000000000 Z
11
+ date: 2014-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: structured_warnings
@@ -136,6 +136,7 @@ files:
136
136
  - LICENSE.md
137
137
  - README.md
138
138
  - Rakefile
139
+ - TAGS
139
140
  - TODO.org
140
141
  - examples/example_basic.rb
141
142
  - lib/rubytree.rb
@@ -143,6 +144,7 @@ files:
143
144
  - lib/tree/binarytree.rb
144
145
  - lib/tree/tree_deps.rb
145
146
  - lib/tree/utils/camel_case_method_handler.rb
147
+ - lib/tree/utils/hash_converter.rb
146
148
  - lib/tree/utils/json_converter.rb
147
149
  - lib/tree/utils/metrics_methods.rb
148
150
  - lib/tree/utils/tree_merge_handler.rb
@@ -179,12 +181,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
179
181
  version: 1.8.7
180
182
  required_rubygems_version: !ruby/object:Gem::Requirement
181
183
  requirements:
182
- - - ">="
184
+ - - ">"
183
185
  - !ruby/object:Gem::Version
184
- version: '0'
186
+ version: 1.3.1
185
187
  requirements: []
186
188
  rubyforge_project:
187
- rubygems_version: 2.2.1
189
+ rubygems_version: 2.2.2
188
190
  signing_key:
189
191
  specification_version: 4
190
192
  summary: A generic tree data structure.