ruby_ex 0.1.1

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.
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
+