ruby_ex 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/AUTHORS +51 -0
  2. data/ChangeLog +1763 -0
  3. data/NEWS +3 -0
  4. data/README +1 -0
  5. data/Rakefile +8 -0
  6. data/SPEC.dyn.yml +10 -0
  7. data/SPEC.gem.yml +269 -0
  8. data/SPEC.yml +36 -0
  9. data/src/abstract.rb +253 -0
  10. data/src/abstract_node.rb +85 -0
  11. data/src/algorithms.rb +12 -0
  12. data/src/algorithms/simulated_annealing.rb +142 -0
  13. data/src/ask.rb +100 -0
  14. data/src/attributed_class.rb +303 -0
  15. data/src/cache.rb +350 -0
  16. data/src/checkout.rb +12 -0
  17. data/src/choose.rb +271 -0
  18. data/src/commands.rb +20 -0
  19. data/src/commands/command.rb +492 -0
  20. data/src/commands/datas.rb +16 -0
  21. data/src/commands/datas/composite.rb +31 -0
  22. data/src/commands/datas/data.rb +65 -0
  23. data/src/commands/datas/factory.rb +69 -0
  24. data/src/commands/datas/temp.rb +26 -0
  25. data/src/commands/factory.rb +67 -0
  26. data/src/commands/helpers.rb +81 -0
  27. data/src/commands/pipe.rb +66 -0
  28. data/src/commands/runners.rb +16 -0
  29. data/src/commands/runners/exec.rb +50 -0
  30. data/src/commands/runners/fork.rb +130 -0
  31. data/src/commands/runners/runner.rb +140 -0
  32. data/src/commands/runners/system.rb +57 -0
  33. data/src/commands/seq.rb +32 -0
  34. data/src/config_file.rb +95 -0
  35. data/src/const_regexp.rb +57 -0
  36. data/src/daemon.rb +135 -0
  37. data/src/diff.rb +665 -0
  38. data/src/dlogger.rb +62 -0
  39. data/src/drb/drb_observable.rb +95 -0
  40. data/src/drb/drb_observable_pool.rb +27 -0
  41. data/src/drb/drb_service.rb +44 -0
  42. data/src/drb/drb_undumped_attributes.rb +56 -0
  43. data/src/drb/drb_undumped_indexed_object.rb +55 -0
  44. data/src/drb/insecure_protected_methods.rb +101 -0
  45. data/src/drb_ex.rb +12 -0
  46. data/src/dumpable_proc.rb +57 -0
  47. data/src/filetype.rb +229 -0
  48. data/src/generate_id.rb +44 -0
  49. data/src/histogram.rb +222 -0
  50. data/src/hookable.rb +283 -0
  51. data/src/hooker.rb +54 -0
  52. data/src/indexed_node.rb +65 -0
  53. data/src/io_marshal.rb +99 -0
  54. data/src/ioo.rb +193 -0
  55. data/src/labeled_node.rb +62 -0
  56. data/src/logger_observer.rb +24 -0
  57. data/src/md5sum.rb +70 -0
  58. data/src/module/autoload_tree.rb +65 -0
  59. data/src/module/hierarchy.rb +334 -0
  60. data/src/module/instance_method_visibility.rb +71 -0
  61. data/src/node.rb +81 -0
  62. data/src/object_monitor.rb +143 -0
  63. data/src/object_monitor_activity.rb +34 -0
  64. data/src/observable.rb +138 -0
  65. data/src/observable_pool.rb +291 -0
  66. data/src/orderedhash.rb +252 -0
  67. data/src/pp_hierarchy.rb +30 -0
  68. data/src/random_generators.rb +29 -0
  69. data/src/random_generators/random_generator.rb +33 -0
  70. data/src/random_generators/ruby.rb +25 -0
  71. data/src/ruby_ex.rb +124 -0
  72. data/src/safe_eval.rb +346 -0
  73. data/src/sendmail.rb +214 -0
  74. data/src/service_manager.rb +122 -0
  75. data/src/shuffle.rb +30 -0
  76. data/src/spring.rb +134 -0
  77. data/src/spring_set.rb +134 -0
  78. data/src/symtbl.rb +108 -0
  79. data/src/synflow.rb +474 -0
  80. data/src/thread_mutex.rb +11 -0
  81. data/src/timeout_ex.rb +79 -0
  82. data/src/trace.rb +26 -0
  83. data/src/uri/druby.rb +78 -0
  84. data/src/uri/file.rb +63 -0
  85. data/src/uri/ftp_ex.rb +36 -0
  86. data/src/uri/http_ex.rb +41 -0
  87. data/src/uri/pgsql.rb +136 -0
  88. data/src/uri/ssh.rb +87 -0
  89. data/src/uri/svn.rb +113 -0
  90. data/src/uri_ex.rb +71 -0
  91. data/src/verbose_object.rb +70 -0
  92. data/src/yaml/basenode_ext.rb +63 -0
  93. data/src/yaml/chop_header.rb +24 -0
  94. data/src/yaml/transform.rb +450 -0
  95. data/src/yaml/yregexpath.rb +76 -0
  96. data/test/algorithms/simulated_annealing_test.rb +102 -0
  97. data/test/check-pkg-ruby_ex.yml +15 -0
  98. data/test/check-ruby_ex.yml +12 -0
  99. data/test/resources/autoload_tree/A.rb +11 -0
  100. data/test/resources/autoload_tree/B.rb +10 -0
  101. data/test/resources/autoload_tree/foo/C.rb +18 -0
  102. data/test/resources/foo.txt +6 -0
  103. data/test/sanity-suite.yml +12 -0
  104. data/test/sanity/multiple-requires.yml +20 -0
  105. data/test/sanity/single-requires.yml +24 -0
  106. data/test/test-unit-setup.rb +6 -0
  107. data/test/unit-suite.yml +14 -0
  108. metadata +269 -0
data/src/ioo.rb ADDED
@@ -0,0 +1,193 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Pouillard. All rights reserved.
2
+ # Author: Nicolas Pouillard <ertai@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: ioo.rb 266 2005-06-01 14:27:18Z ertai $
7
+
8
+ require 'delegate'
9
+ require 'ruby_ex'
10
+
11
+ # With this class you can easily overwrite only write or read methods
12
+ # to change the whole IO.
13
+ #
14
+ # This is very usefull to produce a crypted IO for example.
15
+ module ImplIOO
16
+
17
+ def << ( obj )
18
+ write obj
19
+ self
20
+ end
21
+
22
+ def each ( sep_string=$/, &block )
23
+ begin
24
+ loop { block[readline(sep_string)] }
25
+ rescue EOFError
26
+ return self
27
+ end
28
+ end
29
+ alias :each_line :each
30
+
31
+ def each_byte ( &block )
32
+ begin
33
+ loop { block[readchar] }
34
+ rescue EOFError
35
+ return nil
36
+ end
37
+ end
38
+
39
+ def getc
40
+ begin
41
+ readchar
42
+ rescue EOFError
43
+ nil
44
+ end
45
+ end
46
+
47
+ def gets ( sep_string=$/ )
48
+ begin
49
+ readline(sep_string)
50
+ rescue EOFError
51
+ nil
52
+ end
53
+ end
54
+
55
+ def print ( *args )
56
+ if args.empty?
57
+ write $_
58
+ else
59
+ args.each { |x| write x }
60
+ end
61
+ nil
62
+ end
63
+
64
+ def printf ( fmt, *args )
65
+ write Kernel.sprintf(fmt, *args)
66
+ nil
67
+ end
68
+
69
+ def putc ( c )
70
+ case c
71
+ when Numeric then write c.chr
72
+ when String
73
+ if c.size == 1
74
+ write c
75
+ else
76
+ c = c[0].chr
77
+ write c
78
+ end
79
+ else
80
+ c = c.to_s[0].chr
81
+ write c
82
+ end
83
+ c
84
+ end
85
+
86
+ def puts ( *args )
87
+ if args.size == 0
88
+ write "\n"
89
+ else
90
+ args.each do |x|
91
+ x = x.to_s
92
+ write x
93
+ write "\n" unless x[-1] == ?\n
94
+ end
95
+ end
96
+ nil
97
+ end
98
+
99
+ def readchar
100
+ raise EOFError if eof?
101
+ read(1)[0]
102
+ end
103
+
104
+ def readline ( sep_string=$/ )
105
+ raise EOFError if eof?
106
+ buf = ''
107
+ begin
108
+ while (char = readchar) != ?\n
109
+ buf += char.chr
110
+ end
111
+ return buf + char.chr
112
+ rescue EOFError
113
+ return buf
114
+ end
115
+ end
116
+
117
+ def readlines ( sep_string=$/ )
118
+ res = []
119
+ each_line(sep_string) { |line| res << line }
120
+ res
121
+ end
122
+
123
+ end # module ImplIOO
124
+
125
+ class IOO < DelegateClass(IO)
126
+ include ImplIOO
127
+ end # class IOO
128
+
129
+ require 'socket'
130
+ class TCPSocket
131
+ alias :real_send :send
132
+ alias :real_recv :recv
133
+ end
134
+
135
+ class IOOTCPSocket < DelegateClass(TCPSocket)
136
+ include ImplIOO
137
+
138
+ def recv ( integer, flags=nil )
139
+ read(integer)
140
+ end
141
+
142
+ def read ( integer=nil, buffer='' )
143
+ raise ArgumentError unless buffer.is_a? String
144
+ raise NotImplementedError if integer.nil?
145
+ raise ArgumentError unless integer.is_a? Numeric
146
+ buffer += real_recv(integer, 0)
147
+ return buffer
148
+ end
149
+
150
+ def send ( obj, flags=nil )
151
+ write(obj)
152
+ end
153
+
154
+ def write ( obj )
155
+ real_send(obj.to_s, 0)
156
+ nil
157
+ end
158
+
159
+ end # class IOOTCPSocket
160
+
161
+
162
+ test_section __FILE__ do
163
+
164
+ class TestIOO < Test::Unit::TestCase
165
+
166
+ def setup
167
+ @tmp = TempPath.new('ioo')
168
+ @tmp.open('w') do |tmp|
169
+ tmp.puts 'foo'
170
+ tmp.puts
171
+ tmp.puts 'bar'
172
+ end
173
+ @readlines = @tmp.readlines
174
+ end
175
+
176
+ def teardown
177
+ @tmp.clean
178
+ @tmp = nil
179
+ end
180
+
181
+ def test_readlines
182
+ @tmp.open do |tmp|
183
+ assert_not_nil(tmp)
184
+ f = nil
185
+ assert_nothing_raised { f = IOO.new(tmp) }
186
+ assert_not_nil(f)
187
+ assert_equal(@readlines, f.readlines)
188
+ end
189
+ end
190
+
191
+ end # class TestIOO
192
+
193
+ end
@@ -0,0 +1,62 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: polrop $
6
+ # $Id: node.rb 171 2005-03-29 09:12:47Z polrop $
7
+
8
+
9
+ require 'ruby_ex'
10
+ require 'abstract_node'
11
+
12
+
13
+ class LabeledNode < AbstractNode
14
+ include Concrete
15
+
16
+ def initialize(data=nil, *sub_nodes)
17
+ if sub_nodes.empty?
18
+ @sub_nodes = {}
19
+ else
20
+ @sub_nodes = sub_nodes.first
21
+ end
22
+ super
23
+ end
24
+
25
+ def merge!(sub_nodes)
26
+ sub_nodes.each { |index, sub_node| check_sub_node_type(sub_node) }
27
+ @sub_nodes.merge(sub_nodes)
28
+ end
29
+
30
+ end # class LabeledNode
31
+
32
+
33
+ test_section __FILE__ do
34
+
35
+ class LabeledNodeTest < Test::Unit::TestCase
36
+
37
+ def test_simple
38
+ s11 = LabeledNode.new(11)
39
+ s12 = LabeledNode.new(12)
40
+ s = LabeledNode.new(1, 0 => s11, 1 => s12)
41
+ assert_equal(1, s.data)
42
+ assert_equal(s11, s.sub_nodes[0])
43
+ assert_equal(s12, s.sub_nodes[1])
44
+ end
45
+
46
+ def test_crochet_equal
47
+ s = LabeledNode.new(1)
48
+ assert_nothing_raised { s[0] = LabeledNode.new(10) }
49
+ assert_raises(TypeError) { s[1] = nil }
50
+ end
51
+
52
+ def test_merge
53
+ s = LabeledNode.new(1)
54
+ s11 = LabeledNode.new(11)
55
+ s12 = LabeledNode.new(12)
56
+ s.merge!({ 0 => s11, 1 => s12 })
57
+ end
58
+
59
+ end # class LabeledNodeTest
60
+
61
+ end
62
+
@@ -0,0 +1,24 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: logger_observer.rb 266 2005-06-01 14:27:18Z ertai $
7
+
8
+
9
+ require 'ruby_ex'
10
+ require 'logger'
11
+
12
+
13
+ class Logger
14
+
15
+ def update(*args, &block)
16
+ severity = UNKNOWN
17
+ if args.size > 0
18
+ (severity = Severity.cons_get(args[0].to_s.upcase)) rescue NameError
19
+ end
20
+ add(severity, "#{args.inspect} #{block.inspect if block}", $PROGRAME_NAME)
21
+ end
22
+
23
+ end # class Logger
24
+
data/src/md5sum.rb ADDED
@@ -0,0 +1,70 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: md5sum.rb 266 2005-06-01 14:27:18Z ertai $
7
+
8
+
9
+ require 'ruby_ex'
10
+ require 'md5'
11
+
12
+
13
+ class File
14
+
15
+ def self.md5sum(filename)
16
+ md5 = Digest::MD5.new
17
+ IO.foreach(filename) { |l| md5 << l }
18
+ md5
19
+ end
20
+
21
+ def md5sum
22
+ md5 = Digest::MD5.new
23
+ each { |l| md5 << l }
24
+ md5
25
+ end
26
+
27
+ end # module File
28
+
29
+
30
+ class Pathname
31
+
32
+ def md5sum
33
+ md5 = Digest::MD5.new
34
+ each_line { |l| md5 << l }
35
+ md5
36
+ end
37
+
38
+ end # class Pathname
39
+
40
+
41
+ #
42
+ # Unit test suite
43
+ #
44
+ test_section __FILE__ do
45
+
46
+
47
+ require 'ruby_ex'
48
+
49
+
50
+ class MD5SumTest < Test::Unit::TestCase
51
+
52
+ def setup
53
+ @source = __FILE__.to_path.dirname.parent + 'test/resources/foo.txt'
54
+ @ref = '9508b4f53cff19cf42c5a0f0fc127602'
55
+ end
56
+
57
+ #
58
+ # Tests
59
+ #
60
+ def test_simple
61
+ assert_equal(@ref, @source.md5sum.to_s)
62
+ assert_equal(@ref, File.md5sum(@source).to_s)
63
+ assert_equal(@ref, @source.open { |f| f.md5sum.to_s })
64
+ end
65
+
66
+ end # class MD5SumTest
67
+
68
+
69
+ end
70
+
@@ -0,0 +1,65 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: autoload_tree.rb 266 2005-06-01 14:27:18Z ertai $
7
+
8
+
9
+ require 'ruby_ex'
10
+
11
+
12
+ class Module
13
+
14
+ def autoload_tree(dir, recursive=true, &block)
15
+ pdir = Pathname.new(dir)
16
+ pdir.each_entry do |p|
17
+ next if p.to_s =~ /^\./
18
+ pfull = pdir + p
19
+ if pfull.directory? and recursive
20
+ name = p.to_s.capitalize!
21
+ const_set(name, Module.new) unless const_defined?(name)
22
+ const_get(name).autoload_tree(pfull, recursive, &block)
23
+ elsif pfull.file? and p.to_s =~ /\.rb$/
24
+ autoload(name.to_sym, pfull.to_s) if name = block[p]
25
+ end
26
+ end
27
+ end
28
+
29
+ def autoloaded_module ( file, recursive=true )
30
+ dir = file.sub(/\.rb$/, '').to_path
31
+ autoload_tree(dir) do |path|
32
+ path.basename.to_s.sub(/\.rb$/, '').gsub(/(?:^|_)([a-z])/) { $1.upcase }
33
+ end
34
+ end
35
+
36
+ end # class Module
37
+
38
+
39
+ test_section __FILE__ do
40
+
41
+ class AutoloadTreeTest < Test::Unit::TestCase
42
+
43
+ REPO_DIR = __FILE__.to_path.dirname.parent.parent + 'test/resources/autoload_tree'
44
+
45
+ module AutoloadTree; end
46
+
47
+ #
48
+ # Test
49
+ #
50
+ def test_autoload_tree
51
+ $: << REPO_DIR
52
+ AutoloadTree.autoload_tree(REPO_DIR) { |p| p.to_s.sub!(/\.rb$/, '') }
53
+ ["Foo", "B", "A"].each do |x|
54
+ assert(AutoloadTree.constants.include?(x), "#{x} is missing")
55
+ end
56
+ assert_equal(["C"], AutoloadTree::Foo.constants)
57
+ $:.delete(REPO_DIR)
58
+ end
59
+
60
+ end # class AutoloadTreeTest
61
+
62
+
63
+ end
64
+
65
+
@@ -0,0 +1,334 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: polrop $
6
+ # $Id: hierarchy.rb 266 2005-06-01 14:27:18Z ertai $
7
+
8
+ require 'ruby_ex'
9
+
10
+ # Extend the Module class with method to manipulate inheritance relation
11
+ # between constants of a module.
12
+ class Module
13
+
14
+ # Return the list of all sub classes of base_class (including itself).
15
+ # If force_autoload is false, not yet loaded constants will be ignored.
16
+ # If recursive is true sub modules will also be traversed.
17
+ def sub_classes(base_class, force_autoload=false, recursive=false)
18
+ check_const_is_class?(base_class)
19
+ result = []
20
+ constants.each do |const_name|
21
+ if autoload?(const_name).nil? or force_autoload
22
+ const = const_get(const_name)
23
+ if const.is_a?(Module)
24
+ if const.is_a?(Class)
25
+ result << const if const.ancestors.include?(base_class)
26
+ elsif recursive
27
+ result += const.sub_classes(base_class, force_autoload, recursive)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ result
33
+ end
34
+
35
+ # Remove a class from the hierarchy using remove_const. Sub classes of this
36
+ # class are also removed. It returns an array of the removed class name.
37
+ # See sub_classes for a description of the recursive argument.
38
+ def remove_class(base_class, recursive=false)
39
+ subs = sub_classes(base_class, true, recursive)
40
+ re = Regexp.new("^#{name}::")
41
+ result = []
42
+ subs.each do |sub|
43
+ sub_name = sub.to_s.sub!(re, '')
44
+ if sub_name =~ /^(.+)::(.+)$/
45
+ const_get($1).module_eval { remove_const($2.to_sym) }
46
+ else
47
+ remove_const(sub_name.to_sym)
48
+ end
49
+ result << sub_name
50
+ end
51
+ result
52
+ end
53
+
54
+ # Return the inheritance tree of the base_class.
55
+ # Example:
56
+ #
57
+ # module M
58
+ # class A; end
59
+ # class B < A; end
60
+ # class C < B; end
61
+ # class D < B; end
62
+ # class E < A; end
63
+ # module N
64
+ # class F < A; end
65
+ # class G < F; end
66
+ # class H < D; end
67
+ # class I < H; end
68
+ # class J < E; end
69
+ # class Y; end
70
+ # end
71
+ # class Z; end
72
+ # FOO = 42
73
+ # end
74
+ #
75
+ # M.sub_classes_tree(M::A)
76
+ #
77
+ # produces:
78
+ #
79
+ # {
80
+ # M::A => {
81
+ # M::B => {
82
+ # M::D => {},
83
+ # M::C => {}
84
+ # },
85
+ # M::E => {}
86
+ # }
87
+ # }
88
+ #
89
+ # and
90
+ #
91
+ # M.sub_classes_tree(M::A, false, true)
92
+ #
93
+ # produces:
94
+ #
95
+ # {
96
+ # M::A => {
97
+ # M::N::F => {
98
+ # M::N::G => {}
99
+ # },
100
+ # M::B => {
101
+ # M::C => {},
102
+ # M::D => {
103
+ # M::N::H => {
104
+ # M::N::I => {}
105
+ # }
106
+ # }
107
+ # },
108
+ # M::E => {
109
+ # M::N::J => {}
110
+ # }
111
+ # }
112
+ # }
113
+ def sub_classes_tree(base_class, force_autoload=false, recursive=false)
114
+ subs = sub_classes(base_class, force_autoload, recursive)
115
+ sub_classes_tree_rec([base_class], subs)
116
+ end
117
+
118
+ private
119
+ def sub_classes_tree_rec(base_classes, csts)
120
+ result = {}
121
+ next_csts = []
122
+ base_classes.each do |b|
123
+ next_base_classes = []
124
+ csts.each do |c|
125
+ c.superclass == b ? next_base_classes << c : next_csts << c;
126
+ end
127
+ result[b] = sub_classes_tree_rec(next_base_classes, next_csts)
128
+ end
129
+ result
130
+ end
131
+
132
+ private
133
+ def check_const_is_class?(*base_classes)
134
+ base_classes.each do |b|
135
+ raise(TypeError, "`#{b}' - not a class") unless b.is_a?(Class)
136
+ end
137
+ end
138
+
139
+ end # class Module
140
+
141
+
142
+ test_section __FILE__ do
143
+
144
+ require 'diff'
145
+
146
+
147
+ class HierarchyTest < Test::Unit::TestCase
148
+
149
+ module M
150
+
151
+ class A; end
152
+ class B < A; end
153
+ class C; end
154
+ FOO = 42
155
+
156
+ end
157
+
158
+ def test_sub_classes
159
+ sub_classes = M.sub_classes(HierarchyTest::M::A)
160
+ assert_equal(2, sub_classes.size)
161
+ [HierarchyTest::M::B, HierarchyTest::M::A].each do |x|
162
+ assert(sub_classes.include?(x))
163
+ end
164
+ assert_equal([HierarchyTest::M::C], M.sub_classes(M::C))
165
+ end
166
+
167
+ module Mautoload
168
+
169
+ class A; end
170
+ class B < A; end
171
+ autoload(:C, '/foo')
172
+ FOO = 42
173
+
174
+ end
175
+
176
+ def test_sub_classes_force_autoload
177
+ sub_classes = Mautoload.sub_classes(Mautoload::A)
178
+ assert_equal(2, sub_classes.size)
179
+ [Mautoload::B, Mautoload::A].each do |x|
180
+ assert(sub_classes.include?(x))
181
+ end
182
+ assert_equal(4, Mautoload.constants.size)
183
+ assert_not_nil(Mautoload.autoload?(:C))
184
+ assert_raises(LoadError) { Mautoload.sub_classes(Mautoload::A, true) }
185
+ assert_equal(3, Mautoload.constants.size)
186
+ assert_nil(Mautoload.autoload?(:C))
187
+ end
188
+
189
+ module Mrec
190
+ class A; end
191
+ class B < A; end
192
+ module M
193
+ class C < A; end
194
+ class D < B; end
195
+ class E < D; end
196
+ class Y; end
197
+ end
198
+ class Z; end
199
+ FOO = 42
200
+ end
201
+
202
+ def test_sub_classes_recursive
203
+ sub_classes = Mrec.sub_classes(Mrec::A)
204
+ assert_equal(2, sub_classes.size)
205
+ [Mrec::B, Mrec::A].each do |x|
206
+ assert(sub_classes.include?(x))
207
+ end
208
+ sub_classes = Mrec.sub_classes(Mrec::A, false, true)
209
+ assert_equal(5, sub_classes.size)
210
+ [Mrec::B, Mrec::A, Mrec::M::C, Mrec::M::D, Mrec::M::E].each do |x|
211
+ assert(sub_classes.include?(x))
212
+ end
213
+ r = Mrec.remove_class(Mrec::A, true)
214
+ assert_equal(5, r.size)
215
+ ['B', 'A', 'M::E', 'M::C', 'M::D'].each do |x|
216
+ assert(r.include?(x))
217
+ end
218
+ assert_equal(3, Mrec.constants.size)
219
+ ['FOO', 'M', 'Z'].each { |x| assert(Mrec.constants.include?(x)) }
220
+ assert_equal(1, Mrec::M.constants.size)
221
+ ['Y'].each { |x| assert(Mrec::M.constants.include?(x)) }
222
+ end
223
+
224
+ module Tree
225
+
226
+ class A; end
227
+ class B < A; end
228
+ class C < B; end
229
+ class D < B; end
230
+ class E < A; end
231
+ module M
232
+ class F < A; end
233
+ class G < F; end
234
+ class H < D; end
235
+ class I < H; end
236
+ class J < E; end
237
+ class Y; end
238
+ end
239
+ class Z; end
240
+ FOO = 42
241
+
242
+ end
243
+
244
+ def test_sub_classes_tree_rec
245
+ r = Tree.sub_classes_tree(HierarchyTest::Tree::A, false, true)
246
+ ref = {
247
+ HierarchyTest::Tree::A => {
248
+ HierarchyTest::Tree::M::F => {
249
+ HierarchyTest::Tree::M::G => {}
250
+ },
251
+ HierarchyTest::Tree::B => {
252
+ HierarchyTest::Tree::C => {},
253
+ HierarchyTest::Tree::D => {
254
+ HierarchyTest::Tree::M::H => {
255
+ HierarchyTest::Tree::M::I=>{}
256
+ }
257
+ }
258
+ },
259
+ HierarchyTest::Tree::E=> {
260
+ HierarchyTest::Tree::M::J=>{}
261
+ }
262
+ }
263
+ }
264
+ d = r.diff(ref)
265
+ assert_equal({}, d[:different])
266
+ assert_equal({}, d[:additional])
267
+ assert_equal({}, d[:missing])
268
+ end
269
+
270
+ def test_sub_classes_tree
271
+ r = Tree.sub_classes_tree(HierarchyTest::Tree::A)
272
+ ref = {
273
+ HierarchyTest::Tree::A => {
274
+ HierarchyTest::Tree::B => {
275
+ HierarchyTest::Tree::D => {},
276
+ HierarchyTest::Tree::C => {}
277
+ },
278
+ HierarchyTest::Tree::E => {}
279
+ }
280
+ }
281
+ d = r.diff(ref)
282
+ assert_equal({}, d[:different])
283
+ assert_equal({}, d[:additional])
284
+ assert_equal({}, d[:missing])
285
+ end
286
+
287
+ module Error
288
+ module M; end
289
+ end
290
+
291
+ def test_sub_classes_error
292
+ assert_raises(TypeError) do
293
+ Error.sub_classes_tree(HierarchyTest::Error::M)
294
+ end
295
+ assert_raises(TypeError) do
296
+ Error.sub_classes(HierarchyTest::Error::M)
297
+ end
298
+ assert_raises(TypeError) do
299
+ Error.remove_class(HierarchyTest::Error::M)
300
+ end
301
+ end
302
+
303
+ module RemoveClass
304
+
305
+ class A; end
306
+ class B < A; end
307
+ class C < B; end
308
+ class D < B; end
309
+ class E < D; end
310
+ class F < A; end
311
+ class Z; end
312
+ module M
313
+ class Y; end
314
+ end
315
+ BAR = 51
316
+
317
+ end
318
+
319
+ def test_remove_class
320
+ r = RemoveClass.remove_class(HierarchyTest::RemoveClass::B)
321
+ assert_equal(4, r.size)
322
+ ['B', 'D', 'E', 'C'].each { |x| assert(r.include?(x)) }
323
+ assert_equal(5, RemoveClass.constants.size)
324
+ ['A', 'F', 'Z', 'M', 'BAR'].each do |x|
325
+ assert(RemoveClass.constants.include?(x))
326
+ end
327
+ end
328
+
329
+ end # class HierarchyTest
330
+
331
+
332
+ end
333
+
334
+