utilrb 2.0.2.b2 → 2.1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.boring +40 -0
- data/.gitignore +13 -0
- data/.travis.yml +5 -0
- data/CMakeLists.txt +18 -0
- data/Gemfile +3 -0
- data/Makefile +8 -0
- data/Manifest.txt +0 -8
- data/{README.rd → README.md} +11 -7
- data/Rakefile +16 -63
- data/benchmarks/validate_options.rb +79 -0
- data/ext/utilrb/extconf.rb +1 -17
- data/ext/utilrb/utilrb.cc +0 -23
- data/lib/utilrb/column_formatter.rb +8 -5
- data/lib/utilrb/common.rb +1 -6
- data/lib/utilrb/enumerable/uniq.rb +2 -8
- data/lib/utilrb/event_loop.rb +5 -10
- data/lib/utilrb/kernel/load_dsl_file.rb +1 -2
- data/lib/utilrb/kernel/options.rb +25 -29
- data/lib/utilrb/logger/hierarchy.rb +0 -1
- data/lib/utilrb/logger/io.rb +3 -3
- data/lib/utilrb/logger/root.rb +12 -6
- data/lib/utilrb/module/ancestor_p.rb +0 -12
- data/lib/utilrb/module/is_singleton.rb +6 -0
- data/lib/utilrb/module/singleton_class_p.rb +14 -0
- data/lib/utilrb/object/attribute.rb +33 -65
- data/lib/utilrb/object/singleton_class.rb +1 -20
- data/lib/utilrb/pkgconfig.rb +21 -10
- data/lib/utilrb/socket/tcp_server.rb +2 -2
- data/lib/utilrb/spawn.rb +1 -1
- data/lib/utilrb/test.rb +65 -0
- data/lib/utilrb/thread_pool.rb +11 -13
- data/lib/utilrb/timepoints.rb +15 -0
- data/lib/utilrb/value_set.rb +10 -1
- data/lib/utilrb/version.rb +4 -0
- data/lib/utilrb/weakref.rb +11 -12
- data/lib/utilrb/yard.rb +0 -111
- data/lib/utilrb.rb +6 -1
- data/lib/yard-utilrb.rb +1 -0
- data/manifest.xml +19 -0
- data/package.xml +29 -0
- data/utilrb.gemspec +27 -0
- metadata +56 -107
- data/ext/utilrb/proc.c +0 -39
- data/ext/utilrb/readline.c +0 -52
- data/ext/utilrb/weakref.cc +0 -143
- data/lib/utilrb/models/inherited_enumerable.rb +0 -341
- data/lib/utilrb/models/registration.rb +0 -115
- data/lib/utilrb/module/inherited_enumerable.rb +0 -6
- data/lib/utilrb/objectstats.rb +0 -193
- data/lib/utilrb/ruby_object_graph.rb +0 -384
- data/test/data/test_pkgconfig.pc +0 -9
- data/test/data/test_pkgconfig_empty.pc +0 -10
- data/test/test_array.rb +0 -15
- data/test/test_config.rb +0 -4
- data/test/test_dir.rb +0 -22
- data/test/test_enumerable.rb +0 -119
- data/test/test_event_loop.rb +0 -407
- data/test/test_exception.rb +0 -38
- data/test/test_gc.rb +0 -34
- data/test/test_hash.rb +0 -102
- data/test/test_kernel.rb +0 -300
- data/test/test_logger.rb +0 -204
- data/test/test_misc.rb +0 -42
- data/test/test_models.rb +0 -212
- data/test/test_module.rb +0 -126
- data/test/test_object.rb +0 -77
- data/test/test_objectstats.rb +0 -26
- data/test/test_pkgconfig.rb +0 -84
- data/test/test_proc.rb +0 -31
- data/test/test_set.rb +0 -19
- data/test/test_thread_pool.rb +0 -409
- data/test/test_time.rb +0 -47
- data/test/test_unbound_method.rb +0 -23
- data/test/test_weakref.rb +0 -81
@@ -1,384 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
require 'utilrb/value_set'
|
3
|
-
require 'utilrb/kernel/options'
|
4
|
-
module Utilrb
|
5
|
-
begin
|
6
|
-
require 'roby/graph'
|
7
|
-
has_roby_graph = true
|
8
|
-
rescue LoadError
|
9
|
-
has_roby_graph = false
|
10
|
-
end
|
11
|
-
|
12
|
-
if has_roby_graph
|
13
|
-
class RubyObjectGraph
|
14
|
-
module GraphGenerationObjectMaker
|
15
|
-
def __ruby_object_graph_internal__; end
|
16
|
-
end
|
17
|
-
attr_reader :graph
|
18
|
-
attr_reader :references
|
19
|
-
|
20
|
-
# Takes a snapshot of all objects currently live
|
21
|
-
def self.snapshot
|
22
|
-
# Doing any Ruby code that do not modify the heap is impossible. List
|
23
|
-
# all existing objects once, and only then do the processing.
|
24
|
-
# +live_objects+ will be referenced in itself, but we are going to
|
25
|
-
# remove it later
|
26
|
-
GC.disable
|
27
|
-
live_objects = Array.new
|
28
|
-
ObjectSpace.each_object do |obj|
|
29
|
-
if obj.object_id != live_objects.object_id
|
30
|
-
live_objects << obj
|
31
|
-
end
|
32
|
-
end
|
33
|
-
GC.enable
|
34
|
-
live_objects
|
35
|
-
end
|
36
|
-
|
37
|
-
# Generates a graph of all the objects currently live, in dot format
|
38
|
-
def self.dot_snapshot(options = Hash.new)
|
39
|
-
r, w = IO.pipe
|
40
|
-
live_objects = RubyObjectGraph.snapshot
|
41
|
-
fork do
|
42
|
-
options, register_options = Kernel.filter_options options,
|
43
|
-
:collapse => nil
|
44
|
-
ruby_graph = RubyObjectGraph.new
|
45
|
-
ruby_graph.register_references_to(live_objects, register_options)
|
46
|
-
if options[:collapse]
|
47
|
-
ruby_graph.collapse(*options[:collapse])
|
48
|
-
end
|
49
|
-
w.write ruby_graph.to_dot
|
50
|
-
exit! true
|
51
|
-
end
|
52
|
-
w.close
|
53
|
-
r.read
|
54
|
-
end
|
55
|
-
|
56
|
-
def initialize
|
57
|
-
@graph = BGL::Graph.new
|
58
|
-
@references = Hash.new
|
59
|
-
end
|
60
|
-
|
61
|
-
def clear
|
62
|
-
graph.each_edge do |from, to, info|
|
63
|
-
info.clear
|
64
|
-
end
|
65
|
-
graph.clear
|
66
|
-
references.clear
|
67
|
-
end
|
68
|
-
|
69
|
-
# This class is used to store any ruby object into a BGL::Graph (i.e.
|
70
|
-
# the live graph)
|
71
|
-
class ObjectRef
|
72
|
-
# The referenced object
|
73
|
-
attr_reader :obj
|
74
|
-
|
75
|
-
def __ruby_object_graph_internal__; end
|
76
|
-
|
77
|
-
def initialize(obj)
|
78
|
-
@obj = obj
|
79
|
-
end
|
80
|
-
include BGL::Vertex
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_and_add_reference(obj_ref, var, desc)
|
84
|
-
var_ref = references[var.object_id]
|
85
|
-
if graph.include?(var_ref)
|
86
|
-
add_reference(obj_ref, var_ref, desc)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# Register a ruby object reference
|
91
|
-
#
|
92
|
-
# @param [ObjectRef] obj_ref the object that is referencing
|
93
|
-
# @param [ObjectRef] var_ref the object that is referenced
|
94
|
-
# @param desc the description for the link. For instance, if obj_ref
|
95
|
-
# references var_ref because of an instance variable, this is going to
|
96
|
-
# be the name of the instance variable
|
97
|
-
# @return [void]
|
98
|
-
def add_reference(obj_ref, var_ref, desc)
|
99
|
-
if graph.linked?(obj_ref, var_ref)
|
100
|
-
desc_set = obj_ref[var_ref, graph]
|
101
|
-
if !desc_set.include?(desc)
|
102
|
-
desc_set << desc
|
103
|
-
end
|
104
|
-
else
|
105
|
-
desc_set = [desc]
|
106
|
-
graph.link(obj_ref, var_ref, desc_set)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# Creates a BGL::Graph of ObjectRef objects which stores the current
|
111
|
-
# ruby object graph
|
112
|
-
#
|
113
|
-
# @param [Class] klass seed
|
114
|
-
# @option options [Array<Object>] roots (nil) if given, the list of root
|
115
|
-
# objects. Objects that are not referenced by one of these roots will
|
116
|
-
# not be included in the final graph
|
117
|
-
def register_references_to(live_objects, options = Hash.new)
|
118
|
-
orig_options = options # to exclude it from the graph
|
119
|
-
options = Kernel.validate_options options,
|
120
|
-
:roots => [Object], :excluded_classes => [], :excluded_objects => [],
|
121
|
-
:include_class_relation => false
|
122
|
-
roots_class, roots = options[:roots].partition { |obj| obj.kind_of?(Class) }
|
123
|
-
excluded_classes = options[:excluded_classes]
|
124
|
-
excluded_objects = options[:excluded_objects]
|
125
|
-
include_class_relation = options[:include_class_relation]
|
126
|
-
|
127
|
-
# Create a single ObjectRef per (interesting) live object, so that we
|
128
|
-
# can use a BGL::Graph to represent the reference graph. This will be
|
129
|
-
# what we are going to access later on. Use object IDs since we really
|
130
|
-
# want to refer to objects and not use eql? comparisons
|
131
|
-
desired_seeds = roots.map(&:object_id)
|
132
|
-
excludes = [live_objects, self, graph, references, orig_options, options, roots, roots_class].to_value_set
|
133
|
-
live_objects_total = live_objects.size
|
134
|
-
live_objects.delete_if do |obj|
|
135
|
-
if obj.kind_of?(DRbObject)
|
136
|
-
true
|
137
|
-
elsif excludes.include?(obj) || obj.respond_to?(:__ruby_object_graph_internal__)
|
138
|
-
true
|
139
|
-
else
|
140
|
-
references[obj.object_id] ||= ObjectRef.new(obj)
|
141
|
-
if roots_class.any? { |k| obj.kind_of?(k) }
|
142
|
-
if !excluded_classes.any? { |k| obj.kind_of?(k) }
|
143
|
-
if !excluded_objects.include?(obj)
|
144
|
-
desired_seeds << obj.object_id
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
false
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
desired_seeds.each do |obj_id|
|
153
|
-
graph.insert(references[obj_id])
|
154
|
-
end
|
155
|
-
ignored_enumeration = Hash.new
|
156
|
-
|
157
|
-
names = Hash[
|
158
|
-
:array => "Array",
|
159
|
-
:value_set => "ValueSet[]",
|
160
|
-
:vertex => "Vertex[]",
|
161
|
-
:edge => "Edge[]",
|
162
|
-
:hash_key => "Hash[key]",
|
163
|
-
:hash_value => "Hash[value]",
|
164
|
-
:proc => "Proc",
|
165
|
-
:ancestor => "Ancestor"]
|
166
|
-
puts "RubyObjectGraph: #{live_objects.size} objects found, #{desired_seeds.size} seeds and #{live_objects_total} total live objects"
|
167
|
-
loop do
|
168
|
-
old_graph_size = graph.size
|
169
|
-
live_objects.each do |obj|
|
170
|
-
obj_ref = references[obj.object_id]
|
171
|
-
|
172
|
-
if include_class_relation
|
173
|
-
test_and_add_reference(obj_ref, obj.class, "class")
|
174
|
-
end
|
175
|
-
|
176
|
-
for var_name in obj.instance_variables
|
177
|
-
var = obj.instance_variable_get(var_name)
|
178
|
-
test_and_add_reference(obj_ref, var, var_name.to_s)
|
179
|
-
end
|
180
|
-
|
181
|
-
case obj
|
182
|
-
when Array
|
183
|
-
for var in obj
|
184
|
-
test_and_add_reference(obj_ref, var, names[:array])
|
185
|
-
end
|
186
|
-
when ValueSet
|
187
|
-
for var in obj
|
188
|
-
test_and_add_reference(obj_ref, var, names[:value_set])
|
189
|
-
end
|
190
|
-
when BGL::Graph
|
191
|
-
obj.each_vertex do
|
192
|
-
test_and_add_reference(obj_ref, var, names[:vertex])
|
193
|
-
end
|
194
|
-
obj.each_edge do |_, _, info|
|
195
|
-
test_and_add_reference(obj_ref, info, names[:edge])
|
196
|
-
end
|
197
|
-
when Hash
|
198
|
-
for var in obj
|
199
|
-
test_and_add_reference(obj_ref, var[0], names[:hash_key])
|
200
|
-
test_and_add_reference(obj_ref, var[1], names[:hash_value])
|
201
|
-
end
|
202
|
-
when Proc
|
203
|
-
if obj.respond_to?(:references)
|
204
|
-
for var in obj.references
|
205
|
-
begin
|
206
|
-
test_and_add_reference(obj_ref, ObjectSpace._id2ref(var), names[:proc])
|
207
|
-
rescue RangeError
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
when Class
|
212
|
-
for ref in obj.ancestors
|
213
|
-
test_and_add_reference(obj_ref, ref, names[:ancestor])
|
214
|
-
end
|
215
|
-
else
|
216
|
-
if obj.respond_to?(:each)
|
217
|
-
if obj.kind_of?(Module) || obj.kind_of?(Class)
|
218
|
-
if !ignored_enumeration[obj]
|
219
|
-
ignored_enumeration[obj] = true
|
220
|
-
puts "ignoring enumerator class/module #{obj}"
|
221
|
-
end
|
222
|
-
else
|
223
|
-
if !ignored_enumeration[obj.class]
|
224
|
-
ignored_enumeration[obj.class] = true
|
225
|
-
puts "ignoring enumerator object of class #{obj.class}"
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
if old_graph_size == graph.size
|
232
|
-
break
|
233
|
-
end
|
234
|
-
end
|
235
|
-
live_objects.clear # to avoid making it a central node in future calls
|
236
|
-
return graph
|
237
|
-
end
|
238
|
-
|
239
|
-
def collapse(*klasses)
|
240
|
-
vertices = graph.vertices.dup
|
241
|
-
vertices.each do |v|
|
242
|
-
case v.obj
|
243
|
-
when *klasses
|
244
|
-
next if v.root?(graph) || v.leaf?(graph)
|
245
|
-
|
246
|
-
v.each_parent_vertex(graph) do |parent|
|
247
|
-
all_parent_info = parent[v, graph]
|
248
|
-
v.each_child_vertex(graph) do |child|
|
249
|
-
all_child_info = v[child, graph]
|
250
|
-
all_parent_info.each do |parent_info|
|
251
|
-
all_child_info.each do |child_info|
|
252
|
-
add_reference(parent, child, parent_info + "." + child_info)
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
257
|
-
graph.remove(v)
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
def live_chain_for(obj)
|
263
|
-
result = []
|
264
|
-
|
265
|
-
# Find one Roby task and look at the chain
|
266
|
-
ref = references[obj.object_id]
|
267
|
-
stack = [[ref.obj]]
|
268
|
-
graph.reverse.each_dfs(ref, BGL::Graph::TREE) do |source, target, info, kind|
|
269
|
-
source = source.obj
|
270
|
-
target = target.obj
|
271
|
-
if stack.last.first.object_id != source.object_id && stack.any? { |obj, _| obj.object_id == source.object_id }
|
272
|
-
result << stack.dup if stack.size != 1
|
273
|
-
while stack.last.first.object_id != source.object_id
|
274
|
-
stack.pop
|
275
|
-
end
|
276
|
-
end
|
277
|
-
stack.push [target, info]
|
278
|
-
end
|
279
|
-
if stack.size != 1
|
280
|
-
result << stack
|
281
|
-
end
|
282
|
-
result
|
283
|
-
end
|
284
|
-
|
285
|
-
|
286
|
-
def display_live_chains(chains)
|
287
|
-
chains.each do |stack|
|
288
|
-
puts stack.map { |obj, link| "#{link} #{obj}" }.join("\n >")
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
def to_dot
|
293
|
-
roots = graph.vertices.find_all do |v|
|
294
|
-
v.root?(graph)
|
295
|
-
end.to_value_set
|
296
|
-
|
297
|
-
io = StringIO.new("")
|
298
|
-
|
299
|
-
colors = Hash[
|
300
|
-
:green => 'green',
|
301
|
-
:magenta => 'magenta',
|
302
|
-
:black => 'black'
|
303
|
-
]
|
304
|
-
obj_label_format = "obj%i [label=\"%s\",color=%s];"
|
305
|
-
obj_label_format_elements = []
|
306
|
-
edge_label_format_0 = "obj%i -> obj%i [label=\""
|
307
|
-
edge_label_format_1 = "\"];"
|
308
|
-
edge_label_format_elements = []
|
309
|
-
|
310
|
-
all_seen = ValueSet.new
|
311
|
-
seen = ValueSet.new
|
312
|
-
io.puts "digraph {"
|
313
|
-
roots.each do |obj_ref|
|
314
|
-
graph.each_dfs(obj_ref, BGL::Graph::ALL) do |from_ref, to_ref, all_info, kind|
|
315
|
-
info = []
|
316
|
-
for str in all_info
|
317
|
-
info << str
|
318
|
-
end
|
319
|
-
|
320
|
-
if all_seen.include?(from_ref)
|
321
|
-
graph.prune
|
322
|
-
else
|
323
|
-
from_id = from_ref.obj.object_id
|
324
|
-
to_id = to_ref.obj.object_id
|
325
|
-
|
326
|
-
edge_label_format_elements.clear
|
327
|
-
edge_label_format_elements << from_id << to_id
|
328
|
-
str = edge_label_format_0 % edge_label_format_elements
|
329
|
-
first = true
|
330
|
-
for edge_info in all_info
|
331
|
-
if !first
|
332
|
-
str << ","
|
333
|
-
end
|
334
|
-
str << edge_info
|
335
|
-
first = false
|
336
|
-
end
|
337
|
-
str << edge_label_format_1
|
338
|
-
|
339
|
-
io.puts str
|
340
|
-
end
|
341
|
-
seen << from_ref << to_ref
|
342
|
-
end
|
343
|
-
|
344
|
-
for obj_ref in seen
|
345
|
-
if !all_seen.include?(obj_ref)
|
346
|
-
obj = obj_ref.obj
|
347
|
-
obj_id = obj_ref.obj.object_id
|
348
|
-
str =
|
349
|
-
if obj.respond_to?(:each)
|
350
|
-
"#{obj.class}: #{obj.object_id}"
|
351
|
-
else
|
352
|
-
obj.to_s
|
353
|
-
end
|
354
|
-
|
355
|
-
str = str.encode('UTF-8', :invalid => :replace, :undef => :replace, :replace => "")
|
356
|
-
str = str.gsub(/[^\w\.:<>]/, "")
|
357
|
-
|
358
|
-
color =
|
359
|
-
if obj.kind_of?(BGL::Graph)
|
360
|
-
:magenta
|
361
|
-
elsif obj.kind_of?(Hash) || obj.kind_of?(Array) || obj.kind_of?(ValueSet)
|
362
|
-
:green
|
363
|
-
else
|
364
|
-
:black
|
365
|
-
end
|
366
|
-
|
367
|
-
obj_label_format_elements = [obj_id, str.gsub(/[\\"\n]/, " "), colors[color]]
|
368
|
-
str = obj_label_format % obj_label_format_elements
|
369
|
-
io.puts(str)
|
370
|
-
end
|
371
|
-
end
|
372
|
-
all_seen.merge(seen)
|
373
|
-
seen.clear
|
374
|
-
end
|
375
|
-
roots.clear
|
376
|
-
all_seen.clear
|
377
|
-
seen.clear
|
378
|
-
io.puts "}"
|
379
|
-
io.string
|
380
|
-
end
|
381
|
-
end
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
data/test/data/test_pkgconfig.pc
DELETED
data/test/test_array.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require './test/test_config'
|
2
|
-
require 'utilrb/array'
|
3
|
-
|
4
|
-
class TC_Array < Test::Unit::TestCase
|
5
|
-
def test_to_s
|
6
|
-
assert_equal("[1, 2]", [1, 2].to_s)
|
7
|
-
end
|
8
|
-
def test_to_s_recursive
|
9
|
-
obj = [1, 2]
|
10
|
-
obj << obj
|
11
|
-
assert_equal("[1, 2, ...]", obj.to_s)
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
data/test/test_config.rb
DELETED
data/test/test_dir.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require './test/test_config'
|
2
|
-
|
3
|
-
require 'utilrb/dir'
|
4
|
-
require 'enumerator'
|
5
|
-
|
6
|
-
class TC_Dir < Test::Unit::TestCase
|
7
|
-
def test_empty
|
8
|
-
this_dir = File.dirname(__FILE__)
|
9
|
-
assert(!Dir.new(this_dir).empty?)
|
10
|
-
|
11
|
-
begin
|
12
|
-
Dir.mkdir(test_dir_path = File.join(this_dir, 'test_empty') )
|
13
|
-
rescue Errno::EEXIST
|
14
|
-
end
|
15
|
-
|
16
|
-
test_dir = Dir.new(test_dir_path)
|
17
|
-
assert(test_dir.empty?)
|
18
|
-
ensure
|
19
|
-
Dir.delete(test_dir_path) if test_dir_path
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
data/test/test_enumerable.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
require './test/test_config'
|
2
|
-
|
3
|
-
require 'utilrb/enumerable'
|
4
|
-
require 'utilrb/value_set'
|
5
|
-
|
6
|
-
class TC_Enumerable < Test::Unit::TestCase
|
7
|
-
|
8
|
-
def test_enum_uniq
|
9
|
-
# Test the enum_uniq enumerator
|
10
|
-
assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_uniq { |k| k }.to_a)
|
11
|
-
assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_uniq.to_a)
|
12
|
-
enum = [:a, :b, :a, :c].enum_uniq
|
13
|
-
assert_equal(enum, enum.each)
|
14
|
-
|
15
|
-
a, b, c, d = [1, 2], [1, 3], [2, 3], [3, 4]
|
16
|
-
|
17
|
-
test = [a, b, c, d]
|
18
|
-
assert_equal([a, c, d], test.enum_uniq { |x, y| x }.to_a)
|
19
|
-
assert_equal([a, b, d], test.enum_uniq { |x, y| y }.to_a)
|
20
|
-
|
21
|
-
klass = Class.new do
|
22
|
-
def initialize(base); @base = base end
|
23
|
-
def each(&iterator); @base.each { |x, y| yield [x, y] } end
|
24
|
-
include Enumerable
|
25
|
-
end
|
26
|
-
test = klass.new(test)
|
27
|
-
assert_equal([a, c, d], test.enum_uniq { |x, y| x }.to_a)
|
28
|
-
assert_equal([a, b, d], test.enum_uniq { |x, y| y }.to_a)
|
29
|
-
|
30
|
-
klass = Struct.new :x, :y
|
31
|
-
test = test.map { |x, y| klass.new(x, y) }
|
32
|
-
a, b, c, d = *test
|
33
|
-
assert_equal([a, c, d], [a, b, c, d].enum_uniq { |v| v.x }.to_a)
|
34
|
-
assert_equal([a, b, d], [a, b, c, d].enum_uniq { |v| v.y }.to_a)
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_each_uniq
|
38
|
-
assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_for(:each_uniq).to_a)
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_enum_sequence
|
42
|
-
c1 = [:a, :b, :c]
|
43
|
-
c2 = [:d, :e, :f]
|
44
|
-
assert_equal([:a, :b, :c, :d, :e, :f], (c1.to_enum + c2.to_enum).to_a)
|
45
|
-
assert_equal([:a, :b, :c, :d, :e, :f], [c1, c2].inject(null_enum) { |a, b| a + b }.to_a)
|
46
|
-
assert_equal([:a, :b, :c, :d, :e, :f], [c1, c2].inject(SequenceEnumerator.new) { |a, b| a << b }.to_a)
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_random_element
|
50
|
-
# Test on arrays
|
51
|
-
set = (1..100).to_a
|
52
|
-
100.times { set.delete(set.random_element) }
|
53
|
-
assert(set.empty?)
|
54
|
-
assert_equal(nil, [].random_element)
|
55
|
-
|
56
|
-
# Test on non-empty collection which defines #size
|
57
|
-
set = Hash[*(1..100).map { |i| [i.to_s, i] }.flatten]
|
58
|
-
100.times { set.delete(set.random_element.first) }
|
59
|
-
assert(set.empty?)
|
60
|
-
assert_equal(nil, {}.random_element)
|
61
|
-
end
|
62
|
-
|
63
|
-
Utilrb.require_ext('test_value_set') do
|
64
|
-
def test_value_set
|
65
|
-
a = [1, 3, 3, 4, 6, 8].to_value_set
|
66
|
-
b = [1, 2, 4, 3, 11, 11].to_value_set
|
67
|
-
assert_equal(5, a.size)
|
68
|
-
assert_equal([1, 3, 4, 6, 8], a.to_a)
|
69
|
-
assert(a.include?(1))
|
70
|
-
assert(a.include_all?([4, 1, 8].to_value_set))
|
71
|
-
assert(!a.include_all?(b))
|
72
|
-
|
73
|
-
assert(a.intersects?(b))
|
74
|
-
assert(b.intersects?(a))
|
75
|
-
assert(!a.intersects?([2, 9, 12].to_value_set))
|
76
|
-
|
77
|
-
assert(a.object_id == a.to_value_set.object_id)
|
78
|
-
|
79
|
-
assert_equal([1, 2, 3, 4, 6, 8, 11], (a.union(b)).to_a)
|
80
|
-
assert_equal([1, 3, 4], (a.intersection(b)).to_a)
|
81
|
-
assert_equal([6, 8], (a.difference(b)).to_a)
|
82
|
-
assert(! (a == :bla)) # check #== behaves correctly with a non-enumerable
|
83
|
-
|
84
|
-
a.delete(1)
|
85
|
-
assert(! a.include?(1))
|
86
|
-
a.merge(b);
|
87
|
-
assert_equal([1, 2, 3, 4, 6, 8, 11].to_value_set, a)
|
88
|
-
|
89
|
-
assert([].to_value_set.empty?)
|
90
|
-
|
91
|
-
assert([1, 2, 4, 3].to_value_set.clear.empty?)
|
92
|
-
|
93
|
-
assert_equal([1,3,5].to_value_set, [1, 2, 3, 4, 5, 6].to_value_set.delete_if { |v| v % 2 == 0 })
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_value_set_hash
|
97
|
-
a = [(obj = Object.new), 3, 4, [(obj2 = Object.new), Hash.new]].to_value_set
|
98
|
-
b = [obj, 3, 4, [obj2, Hash.new]].to_value_set
|
99
|
-
assert_equal a.hash, b.hash
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_value_set_to_s
|
103
|
-
obj = ValueSet.new
|
104
|
-
obj << 1
|
105
|
-
obj << 2
|
106
|
-
assert(obj.to_s =~ /\{(.*)\}/)
|
107
|
-
values = $1.split(", ")
|
108
|
-
assert_equal(["1", "2"].to_set, values.to_set)
|
109
|
-
|
110
|
-
obj << obj
|
111
|
-
assert(obj.to_s =~ /^(.+)\{(.*)\}>$/)
|
112
|
-
|
113
|
-
base_s = $1
|
114
|
-
values = $2.split(", ")
|
115
|
-
assert_equal(["1", "2", "#{base_s}...>"].to_set, values.to_set)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|