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/cache.rb ADDED
@@ -0,0 +1,350 @@
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: cache.rb 273 2005-06-03 00:00:26Z ertai $
7
+
8
+
9
+ require 'ruby_ex'
10
+ require 'md5sum'
11
+
12
+
13
+ class Cache
14
+
15
+ #
16
+ # Constants
17
+ #
18
+ REPOSITORY = '/var/cache/ruby_ex_cache'
19
+ MAX_SIZE = 50 * 1024 * 1024 # 50 MB
20
+ BLOCK_SIZE = 1024 # octets
21
+
22
+ #
23
+ # Attributs
24
+ #
25
+ attr_reader :repository, :max_size, :size
26
+
27
+ #
28
+ # Constructor
29
+ #
30
+ def initialize(repository=REPOSITORY, max_size=MAX_SIZE)
31
+ @repository = Pathname.new(repository)
32
+ @max_size = check_max_size(max_size)
33
+ create
34
+ end
35
+
36
+ #
37
+ # Methods
38
+ #
39
+ def create
40
+ @size = 0
41
+ @atime = []
42
+ if @repository.directory?
43
+ @repository.each_entry do |p|
44
+ next if p.to_s =~ /^\./
45
+ full_p = @repository + p
46
+ @atime << full_p
47
+ @size += full_p.size
48
+ end
49
+ @atime.sort! { |a, b| a.atime <=> b.atime }
50
+ else
51
+ @repository.mkdir
52
+ end
53
+ end
54
+
55
+ def clear
56
+ @repository.each_entry do |p|
57
+ (@repository + p).delete unless p.to_s =~ /^\./
58
+ end
59
+ @size = 0
60
+ @atime.clear
61
+ end
62
+
63
+ def recreate
64
+ clear
65
+ create
66
+ end
67
+
68
+ def open(md5sum=nil, mode='r', perm=0644, &block)
69
+ case mode
70
+ when 'r': read(md5sum, &block)
71
+ when 'w': write(perm, &block)
72
+ else
73
+ raise(ArgumentError, "`#{mode}' - bad mode")
74
+ end
75
+ end
76
+
77
+ def read(md5sum, &block)
78
+ p = @repository + md5sum.to_s
79
+ p.open('r', &block)
80
+ @atime.delete(p)
81
+ @atime << p
82
+ p
83
+ end
84
+
85
+ def write(perm=0644, &block)
86
+ TempPath.new('cache_file') do |tmp|
87
+ md5 = Digest::MD5.new
88
+ new_size = 0
89
+ tmp.open('w') do |out|
90
+ while (str = block[])
91
+ out.write(str)
92
+ md5 << str
93
+ new_size += str.size
94
+ end
95
+ end
96
+ p = @repository + md5.to_s
97
+ if p.exist?
98
+ @atime.delete(p)
99
+ else
100
+ @size += new_size
101
+ end
102
+ FileUtils.move(tmp.to_s, p.to_s)
103
+ p.chmod(perm)
104
+ @atime << p
105
+ adjust_size
106
+ return p
107
+ end
108
+ end
109
+
110
+ def import(filename)
111
+ p = nil
112
+ pathname = filename.to_path
113
+ pathname.open do |f|
114
+ p = write(pathname.stat.mode) { f.eof? ? nil : f.read(BLOCK_SIZE) }
115
+ end
116
+ p
117
+ end
118
+
119
+ def export(md5sum, dst_filename)
120
+ p = @repository + md5sum.to_s
121
+ FileUtils.copy_entry(p, dst_filename)
122
+ update_entry(p)
123
+ p
124
+ end
125
+
126
+ def present?(md5sum)
127
+ p = @repository + md5sum.to_s
128
+ p.exist? ? p : nil;
129
+ end
130
+
131
+ def each
132
+ @atime.each { |p| yield(p) }
133
+ end
134
+
135
+ def [](index)
136
+ @atime[index]
137
+ end
138
+
139
+ def max_size=(max_size)
140
+ @max_size = check_max_size(max_size)
141
+ adjust_size
142
+ end
143
+
144
+ def nb_files
145
+ @atime.size
146
+ end
147
+
148
+ protected
149
+ def adjust_size
150
+ while @size > @max_size
151
+ p = @atime.shift
152
+ @size -= p.size
153
+ p.delete
154
+ end
155
+ @size
156
+ end
157
+
158
+ protected
159
+ def check_max_size(max_size)
160
+ unless max_size > 0
161
+ raise(ArgumentError, "`#{max_size}' - bad cache maximum size")
162
+ end
163
+ max_size
164
+ end
165
+
166
+ end # class Cache
167
+
168
+
169
+ #
170
+ # Unit test suite
171
+ #
172
+ test_section __FILE__ do
173
+
174
+
175
+ class CacheTest < Test::Unit::TestCase
176
+
177
+ #
178
+ # Tests
179
+ #
180
+ def test_simple
181
+ # FIXME factor me using #setup, #teardown, and @cache instead of cache.
182
+ TempPath.new('cache') do |repo|
183
+ cache = nil
184
+ assert_nothing_raised { cache = Cache.new(repo) }
185
+ assert_equal(0, cache.nb_files, 'bad nb_files')
186
+ assert_nothing_raised { cache.create }
187
+ assert_equal(0, cache.nb_files, 'bad nb_files')
188
+ assert_nothing_raised { cache.clear }
189
+ assert_equal(0, cache.nb_files, 'bad nb_files')
190
+ assert_nothing_raised { cache.create }
191
+ assert_equal(0, cache.nb_files, 'bad nb_files')
192
+ assert_raises(Errno::ENOENT) { cache.open('toto', 'r') { |f| f.gets } }
193
+ assert_equal(0, cache.nb_files, 'bad nb_files')
194
+ assert_equal(0, cache.size)
195
+
196
+ data = [ "toto\n", "tata\n" ]
197
+ p1 = cache.open(nil, 'w') do
198
+ data.shift
199
+ end
200
+ assert(p1)
201
+ assert_equal(p1.md5sum.to_s, p1.basename.to_s, 'bad md5 open')
202
+ assert_equal(1, cache.nb_files, 'bad nb_files')
203
+ assert_equal(p1, cache[0])
204
+ assert_equal(10, cache.size)
205
+ assert_equal(p1, cache.present?(p1.basename))
206
+ tmp_p = cache.read(p1) do |f|
207
+ assert_equal("toto\n", f.gets)
208
+ assert_equal("tata\n", f.gets)
209
+ assert(f.eof?)
210
+ end
211
+ assert_equal(tmp_p, p1)
212
+ check_atime(cache)
213
+ assert_equal(1, cache.nb_files, 'bad nb_files')
214
+ assert(cache.present?(p1))
215
+ assert_equal(p1, cache[0])
216
+ assert(! cache.present?('foo'))
217
+
218
+ # FIXME man printf + Tempfile + File::md5sum
219
+ # resources/foo.txt + TempPath + Path#md5sum
220
+ tmp_file = Tempfile.new('cache')
221
+ system("man printf > #{tmp_file.path} 2> /dev/null")
222
+ md5 = File.md5sum(tmp_file.path)
223
+ p2 = cache.import(tmp_file.path)
224
+ assert_equal(md5.to_s, p2.basename.to_s, 'bad name after import')
225
+ assert(p2.exist?, 'file do not exist after import')
226
+ assert(FileUtils.cmp(tmp_file.path, p2.to_s), 'bad import')
227
+ assert_equal(md5.to_s, File.md5sum(p2.to_s).to_s, 'bad md5 import')
228
+ tmp_file.delete
229
+ assert_equal(2, cache.nb_files, 'bad nb_files')
230
+ assert_equal(p2, cache[1])
231
+ check_atime(cache)
232
+
233
+ data = [ "foo\n", "bar\n" ]
234
+ p3 = cache.open(nil, 'w') do
235
+ data.shift
236
+ end
237
+ assert_equal(File.md5sum(p3.to_s).to_s, p3.basename.to_s, 'bad md5 open')
238
+ assert_equal(3, cache.nb_files, 'bad nb_files')
239
+ assert_equal(p3, cache[2])
240
+ assert_equal(p3, cache.present?(p3.basename))
241
+
242
+ assert_equal(p1, cache[0], 'p1 first')
243
+ assert_equal(p2, cache[1], 'p2 second')
244
+ assert_equal(p3, cache[2], 'p3 third')
245
+ assert_equal(p1, cache.read(p1) { |f| f.gets })
246
+ assert_equal(p2, cache[0], 'p2 first')
247
+ assert_equal(p3, cache[1], 'p3 second')
248
+ assert_equal(p1, cache[2], 'p1 third')
249
+ check_atime(cache)
250
+ assert_equal(3, cache.nb_files, 'bad nb_files')
251
+
252
+
253
+ new_cache = nil
254
+ assert_nothing_raised { new_cache = Cache.new(repo) }
255
+ assert_equal(3, new_cache.nb_files, 'bad nb_files in new cache')
256
+ check_atime(new_cache)
257
+ assert_equal(cache.size, new_cache.size)
258
+
259
+ assert_equal(3, cache.nb_files, 'bad nb_files')
260
+ assert(cache.size > 1024)
261
+ cache.max_size = 1024
262
+ assert(cache.size < 1024)
263
+ assert_equal(p1.size + p3.size, cache.size)
264
+ assert_equal(2, cache.nb_files, 'bad nb_files')
265
+ assert_equal(p3, cache[0], 'p3 first')
266
+ assert_equal(p1, cache[1], 'p1 second')
267
+
268
+ cache.clear
269
+ assert_equal(0, cache.nb_files, 'bad nb_files')
270
+ assert_equal(0, cache.size)
271
+ end
272
+ end
273
+
274
+ def test_write_twice_the_same
275
+ TempPath.new('cache') do |repo|
276
+ cache = nil
277
+ assert_nothing_raised { cache = Cache.new(repo) }
278
+ assert_equal(0, cache.nb_files, 'bad nb_files')
279
+ assert_equal(0, cache.size)
280
+
281
+ data = [ "toto\n", "tata\n" ]
282
+ d = data.dup
283
+ p1 = cache.open(nil, 'w') do
284
+ d.shift
285
+ end
286
+
287
+ assert_kind_of(Pathname, p1)
288
+ assert_equal(p1.md5sum.to_s, p1.basename.to_s, 'bad md5 open')
289
+ assert_equal(1, cache.nb_files, 'bad nb_files')
290
+ assert_equal(p1, cache[0])
291
+ assert_equal(10, cache.size)
292
+ assert_equal(p1, cache.present?(p1.basename))
293
+
294
+ data = [ "toto\n", "tata\n" ]
295
+ d = data.dup
296
+ p2 = cache.open(nil, 'w') do
297
+ d.shift
298
+ end
299
+
300
+ assert_equal(File.md5sum(p1.to_s).to_s, p1.basename.to_s, 'bad md5 open')
301
+ assert_equal(1, cache.nb_files, 'bad nb_files')
302
+ assert_equal(p1, cache[0])
303
+ assert_equal(10, cache.size)
304
+ assert_equal(p1, cache.present?(p1.basename))
305
+ end
306
+ end
307
+
308
+ def test_nested_write
309
+ TempPath.new('cache') do |repo|
310
+ cache = nil
311
+ assert_nothing_raised { cache = Cache.new(repo) }
312
+ assert_equal(0, cache.nb_files, 'bad nb_files')
313
+ assert_equal(0, cache.size)
314
+
315
+ data = [ "toto\n", "tata\n" ]
316
+ d1 = data.dup
317
+ p1 = cache.open(nil, 'w') do
318
+ d2 = data.dup
319
+ p2 = cache.open(nil, 'w') do
320
+ d2.shift
321
+ end
322
+ d1.shift
323
+ end
324
+
325
+ assert(p1)
326
+ assert_equal(p1.md5sum.to_s, p1.basename.to_s, 'bad md5 open')
327
+ assert_equal(1, cache.nb_files, 'bad nb_files')
328
+ assert_equal(p1, cache[0])
329
+ assert_equal(10, cache.size)
330
+ assert_equal(p1, cache.present?(p1.basename))
331
+ end
332
+ end
333
+
334
+ #
335
+ # Utilities
336
+ #
337
+ protected
338
+ def check_atime(cache)
339
+ j = 0
340
+ for i in 1...cache.nb_files do
341
+ assert(cache[j].atime <= cache[i].atime, "bad atime order for #{i}")
342
+ j = i
343
+ end
344
+ end
345
+
346
+ end # class CacheTest
347
+
348
+
349
+ end
350
+
data/src/checkout.rb ADDED
@@ -0,0 +1,12 @@
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: checkout.rb 159 2005-02-18 12:07:23Z polrop $
7
+
8
+ require 'uri_ex'
9
+ require 'uri/http_ex'
10
+ require 'uri/ftp_ex'
11
+ require 'uri/file'
12
+ require 'uri/svn'
data/src/choose.rb ADDED
@@ -0,0 +1,271 @@
1
+ # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
2
+ # Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
3
+ # License:: GNU General Public License (GPL).
4
+ # Revision:: $Id: choose.rb 258 2005-06-01 00:22:51Z ertai $
5
+
6
+
7
+ require 'random_generators'
8
+
9
+
10
+ class Integer
11
+
12
+ def self.choose ( limit=nil, generator=nil )
13
+ limit.to_i.choose(generator)
14
+ end
15
+
16
+ def choose ( generator=nil )
17
+ (generator || RandomGenerators.default).choose_integer(self)
18
+ end
19
+
20
+ end # class Integer
21
+
22
+
23
+
24
+ class Float
25
+
26
+ def self.choose ( limit=nil, generator=nil )
27
+ (limit || 1.0).to_f.choose(generator)
28
+ end
29
+
30
+ def choose ( generator=nil )
31
+ (generator || RandomGenerators.default).choose_float(self)
32
+ end
33
+
34
+ end # class Float
35
+
36
+
37
+
38
+ class Hash
39
+
40
+ def choose ( limit=nil, generator=nil )
41
+ self[keys.choose(limit, generator)]
42
+ end
43
+
44
+ end # class Hash
45
+
46
+
47
+
48
+ class Array
49
+
50
+ def choose ( limit=nil, generator=nil )
51
+ n = size
52
+
53
+ # Out of limits: limit > size (FIXME warn)
54
+ limit = n if limit.nil? or limit > n
55
+
56
+ self[limit.choose(generator)]
57
+ end
58
+
59
+ end # class Array
60
+
61
+
62
+
63
+ module Enumerable
64
+
65
+ def choose ( limit=nil, generator=nil )
66
+ to_a.choose(limit, generator)
67
+ end
68
+
69
+ end # module Enumerable
70
+
71
+
72
+
73
+ class Range
74
+
75
+ def choose ( generator=nil )
76
+ case first
77
+ when Integer
78
+ first + (last + 1 - first).choose(generator)
79
+ else
80
+ super(nil, generator)
81
+ end
82
+ end
83
+
84
+ end # class Array
85
+
86
+
87
+
88
+ test_section __FILE__ do
89
+
90
+ class MockRandomGenerator < RandomGenerators::RandomGenerator
91
+ concrete
92
+ attr_reader :ref
93
+ def initialize ( tab_i, tab_f )
94
+ raise unless tab_i.is_a? Array
95
+ raise unless tab_f.is_a? Array
96
+ @ref, @ref_f, @pos = tab_i, tab_f, -1
97
+ end
98
+ def get ( tab )
99
+ tab[@pos = (@pos + 1) % tab.size]
100
+ end
101
+ def choose_integer ( n )
102
+ check_choose_integer(n)
103
+ get(@ref) % n
104
+ end
105
+ def choose_float ( f=1.0 )
106
+ check_choose_float(f)
107
+ get(@ref_f) * f
108
+ end
109
+ end # class MockRandomGenerator
110
+
111
+ class RandomMockRandomGenerator < MockRandomGenerator
112
+ def initialize ( n )
113
+ tab_i = (0 .. n - 1).to_a.shuffle
114
+ tab_f = []
115
+ n.times { tab_f << Float.choose() }
116
+ super(tab_i, tab_f)
117
+ end
118
+ end # class RandomMockRandomGenerator
119
+
120
+
121
+ require 'test/unit'
122
+ require 'set'
123
+
124
+ class ChooseTest < Test::Unit::TestCase
125
+
126
+ REF_5 = [1, 2, 4, 0, 3]
127
+ REF_F_5 = [0.187528345035389, 0.368857819121331, 0.06954449811019,
128
+ 0.188887464581057, 0.213757352204993]
129
+ REF_50 = [
130
+ 28, 12, 17, 10, 1, 37, 46, 25, 47, 2, 45, 36, 20, 5, 30, 14, 18, 39,
131
+ 8, 15, 16, 43, 27, 33, 22, 7, 32, 3, 35, 9, 19, 13, 21, 6, 23, 26, 4,
132
+ 40, 44, 11, 49, 29, 42, 24, 31, 48, 34, 0, 38, 41
133
+ ]
134
+ REF_F_50 = [
135
+ 0.643785412423313, 0.765736325876787, 0.604515956481919,
136
+ 0.133839202811942, 0.350400971015915, 0.966710213804618,
137
+ 0.904755113180727, 0.88459848286584, 0.163951952941716,
138
+ 0.808023529592901, 0.387806572020054, 0.659689131658524,
139
+ 0.289974238490686, 0.813535830006003, 0.565311754588038,
140
+ 0.889200099511072, 0.0668127918615937, 0.992091996129602,
141
+ 0.604403987759724, 0.89254002738744, 0.601499371463433,
142
+ 0.754795648856089, 0.751190354581922, 0.434389552799985,
143
+ 0.761369747575372, 0.174903159961104, 0.940325234550983,
144
+ 0.536097376374528, 0.957906004507095, 0.693120914744213,
145
+ 0.23448576242663, 0.638284107437357, 0.423910334473476,
146
+ 0.251349127152935, 0.457931924844161, 0.20579389645718,
147
+ 0.256057573715225, 0.584466924890876, 0.609375598141924,
148
+ 0.0856487881392241, 0.437958877766505, 0.432312048738822,
149
+ 0.81560374982655, 0.142059376928955, 0.118824432371184,
150
+ 0.958816710859537, 0.69899930502288, 0.118259542621672,
151
+ 0.52218786906451, 0.339233995880932
152
+ ]
153
+
154
+ def checker_n ( n, ref_i, ref_f, inp, ref, lim=nil )
155
+ mrg = MockRandomGenerator.new(ref_i, ref_f)
156
+ my = []
157
+ if lim == :no
158
+ n.times { my << inp.choose(mrg) }
159
+ else
160
+ n.times { my << inp.choose(lim, mrg) }
161
+ end
162
+ assert_equal(ref, my)
163
+ end
164
+
165
+ def checker_5 ( inp, ref, lim=nil )
166
+ checker_n(5, REF_5, REF_F_5, inp, ref, lim)
167
+ end
168
+
169
+ def checker_50 ( inp, ref, lim=nil )
170
+ checker_n(50, REF_50, REF_F_50, inp, ref, lim)
171
+ end
172
+
173
+
174
+
175
+
176
+ def test_integer
177
+ checker_5 Integer, REF_5, 5
178
+ checker_50 Integer, REF_50, 50
179
+ assert(Integer.choose(1000) < 1000)
180
+ end
181
+
182
+ def test_float
183
+ checker_5 Float, REF_F_5, 1.0
184
+ checker_50 Float, REF_F_50, 1.0
185
+ assert(Float.choose(2.0) < 2)
186
+ assert(Float.choose < 1)
187
+ end
188
+
189
+ def test_array_5
190
+ checker_5 [4], [4] * 5, 5
191
+ checker_5 [4, 5], [5, 4, 4, 4, 5], 5
192
+ checker_5 [4, 5, 6], [5, 6, 5, 4, 4], 5
193
+ checker_5 [2, 1, 0, 5, 4, 3], [1, 0, 4, 2, 5], 5
194
+ 10.times { assert(REF_50.include?(REF_50.choose)) }
195
+ end
196
+
197
+ def test_set_5
198
+ checker_5 Set[4], [4] * 5, 5
199
+ checker_5 Set[4, 5], [4, 5, 5, 5, 4], 5
200
+ checker_5 Set[4, 5, 6], [6, 4, 6, 5, 5], 5
201
+ checker_5 Set[2, 1, 0, 5, 4, 3], [0, 1, 3, 5, 2], 5
202
+ set = REF_50.to_set
203
+ 10.times { assert(set.include?(set.choose)) }
204
+ end
205
+
206
+ def test_hash
207
+ checker_5({ 1 => 2 }, [2] * 5, 5)
208
+ checker_5({ 1 => 2, 3 => 4 }, [4, 2, 2, 2, 4], 5)
209
+ end
210
+
211
+ def test_array_50
212
+ checker_50 [4], [4] * 50, 50
213
+ checker_50 [
214
+ 36, 16, 15, 6, 27, 33, 17, 10, 18, 39, 8, 43, 19, 23, 49, 40, 46, 37,
215
+ 9, 41, 35, 0, 38, 26, 22, 4, 7, 25, 21, 12, 42, 45, 28, 5, 31, 24, 34,
216
+ 48, 32, 30, 13, 29, 11, 2, 1, 20, 3, 44, 47, 14
217
+ ], [
218
+ 21, 19, 37, 8, 16, 48, 3, 4, 44, 15, 20, 34, 35, 33, 42, 49, 9, 30,
219
+ 18, 40, 46, 2, 25, 5, 38, 10, 28, 6, 24, 39, 41, 23, 0, 17, 26, 7, 27,
220
+ 13, 1, 43, 14, 12, 11, 22, 45, 47, 31, 36, 32, 29
221
+ ], 50
222
+ end
223
+
224
+ def test_integer_instances
225
+ assert_raise(ArgumentError) { checker_5 0, [], :no }
226
+ checker_5 1, [0] * 5, :no
227
+ checker_5 4, [1, 2, 0, 0, 3], :no
228
+ checker_5 10, REF_5, :no
229
+ assert(1000.choose < 1000)
230
+ end
231
+
232
+ def test_float_instances
233
+ assert_raise(ArgumentError) { checker_5 0.0, [], :no }
234
+ checker_5 1.0, [ 0.187528345035389, 0.368857819121331, 0.06954449811019,
235
+ 0.188887464581057, 0.213757352204993 ], :no
236
+ assert(2.0.choose < 2)
237
+ end
238
+
239
+ def test_integer_range_instances
240
+ checker_5 1..1, [1] * 5, :no
241
+ checker_5 1..2, [2, 1, 1, 1, 2], :no
242
+ checker_5 0..1, [1, 0, 0, 0, 1], :no
243
+ checker_5 0..4, [1, 2, 4, 0, 3], :no
244
+ end
245
+
246
+ class Xs
247
+ include Comparable
248
+ attr_reader :length
249
+ def initialize ( n )
250
+ @length = n
251
+ end
252
+ def succ
253
+ Xs.new(@length.succ)
254
+ end
255
+ def <=> ( rhs )
256
+ @length <=> rhs.length
257
+ end
258
+ def inspect
259
+ 'x' * @length
260
+ end
261
+ end
262
+
263
+ def test_range_instances
264
+ checker_5 'a'..'a', ['a'] * 5, :no
265
+ checker_5 'a'..'b', ['b', 'a', 'a', 'a', 'b'], :no
266
+ checker_5 Xs.new(1)..Xs.new(4), [2, 3, 1, 1, 4].map { |x| Xs.new(x) }, :no
267
+ end
268
+
269
+ end # class ChooseTest
270
+
271
+ end