source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/set.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 26.1 KB
Line 
1#!/usr/bin/env ruby
2#--
3# set.rb - defines the Set class
4#++
5# Copyright (c) 2002 Akinori MUSHA <[email protected]>
6#
7# Documentation by Akinori MUSHA and Gavin Sinclair.
8#
9# All rights reserved. You can redistribute and/or modify it under the same
10# terms as Ruby.
11#
12# $Id: set.rb 11980 2007-03-03 16:06:45Z knu $
13#
14# == Overview
15#
16# This library provides the Set class, which deals with a collection
17# of unordered values with no duplicates. It is a hybrid of Array's
18# intuitive inter-operation facilities and Hash's fast lookup. If you
19# need to keep values ordered, use the SortedSet class.
20#
21# The method +to_set+ is added to Enumerable for convenience.
22#
23# See the Set class for an example of usage.
24
25
26#
27# Set implements a collection of unordered values with no duplicates.
28# This is a hybrid of Array's intuitive inter-operation facilities and
29# Hash's fast lookup.
30#
31# Several methods accept any Enumerable object (implementing +each+)
32# for greater flexibility: new, replace, merge, subtract, |, &, -, ^.
33#
34# The equality of each couple of elements is determined according to
35# Object#eql? and Object#hash, since Set uses Hash as storage.
36#
37# Finally, if you are using class Set, you can also use Enumerable#to_set
38# for convenience.
39#
40# == Example
41#
42# require 'set'
43# s1 = Set.new [1, 2] # -> #<Set: {1, 2}>
44# s2 = [1, 2].to_set # -> #<Set: {1, 2}>
45# s1 == s2 # -> true
46# s1.add("foo") # -> #<Set: {1, 2, "foo"}>
47# s1.merge([2, 6]) # -> #<Set: {6, 1, 2, "foo"}>
48# s1.subset? s2 # -> false
49# s2.subset? s1 # -> true
50#
51class Set
52 include Enumerable
53
54 # Creates a new set containing the given objects.
55 def self.[](*ary)
56 new(ary)
57 end
58
59 # Creates a new set containing the elements of the given enumerable
60 # object.
61 #
62 # If a block is given, the elements of enum are preprocessed by the
63 # given block.
64 def initialize(enum = nil, &block) # :yields: o
65 @hash ||= Hash.new
66
67 enum.nil? and return
68
69 if block
70 enum.each { |o| add(block[o]) }
71 else
72 merge(enum)
73 end
74 end
75
76 # Copy internal hash.
77 def initialize_copy(orig)
78 @hash = orig.instance_eval{@hash}.dup
79 end
80
81 # Returns the number of elements.
82 def size
83 @hash.size
84 end
85 alias length size
86
87 # Returns true if the set contains no elements.
88 def empty?
89 @hash.empty?
90 end
91
92 # Removes all elements and returns self.
93 def clear
94 @hash.clear
95 self
96 end
97
98 # Replaces the contents of the set with the contents of the given
99 # enumerable object and returns self.
100 def replace(enum)
101 if enum.class == self.class
102 @hash.replace(enum.instance_eval { @hash })
103 else
104 enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
105 clear
106 enum.each { |o| add(o) }
107 end
108
109 self
110 end
111
112 # Converts the set to an array. The order of elements is uncertain.
113 def to_a
114 @hash.keys
115 end
116
117 def flatten_merge(set, seen = Set.new)
118 set.each { |e|
119 if e.is_a?(Set)
120 if seen.include?(e_id = e.object_id)
121 raise ArgumentError, "tried to flatten recursive Set"
122 end
123
124 seen.add(e_id)
125 flatten_merge(e, seen)
126 seen.delete(e_id)
127 else
128 add(e)
129 end
130 }
131
132 self
133 end
134 protected :flatten_merge
135
136 # Returns a new set that is a copy of the set, flattening each
137 # containing set recursively.
138 def flatten
139 self.class.new.flatten_merge(self)
140 end
141
142 # Equivalent to Set#flatten, but replaces the receiver with the
143 # result in place. Returns nil if no modifications were made.
144 def flatten!
145 if detect { |e| e.is_a?(Set) }
146 replace(flatten())
147 else
148 nil
149 end
150 end
151
152 # Returns true if the set contains the given object.
153 def include?(o)
154 @hash.include?(o)
155 end
156 alias member? include?
157
158 # Returns true if the set is a superset of the given set.
159 def superset?(set)
160 set.is_a?(Set) or raise ArgumentError, "value must be a set"
161 return false if size < set.size
162 set.all? { |o| include?(o) }
163 end
164
165 # Returns true if the set is a proper superset of the given set.
166 def proper_superset?(set)
167 set.is_a?(Set) or raise ArgumentError, "value must be a set"
168 return false if size <= set.size
169 set.all? { |o| include?(o) }
170 end
171
172 # Returns true if the set is a subset of the given set.
173 def subset?(set)
174 set.is_a?(Set) or raise ArgumentError, "value must be a set"
175 return false if set.size < size
176 all? { |o| set.include?(o) }
177 end
178
179 # Returns true if the set is a proper subset of the given set.
180 def proper_subset?(set)
181 set.is_a?(Set) or raise ArgumentError, "value must be a set"
182 return false if set.size <= size
183 all? { |o| set.include?(o) }
184 end
185
186 # Calls the given block once for each element in the set, passing
187 # the element as parameter.
188 def each
189 @hash.each_key { |o| yield(o) }
190 self
191 end
192
193 # Adds the given object to the set and returns self. Use +merge+ to
194 # add several elements at once.
195 def add(o)
196 @hash[o] = true
197 self
198 end
199 alias << add
200
201 # Adds the given object to the set and returns self. If the
202 # object is already in the set, returns nil.
203 def add?(o)
204 if include?(o)
205 nil
206 else
207 add(o)
208 end
209 end
210
211 # Deletes the given object from the set and returns self. Use +subtract+ to
212 # delete several items at once.
213 def delete(o)
214 @hash.delete(o)
215 self
216 end
217
218 # Deletes the given object from the set and returns self. If the
219 # object is not in the set, returns nil.
220 def delete?(o)
221 if include?(o)
222 delete(o)
223 else
224 nil
225 end
226 end
227
228 # Deletes every element of the set for which block evaluates to
229 # true, and returns self.
230 def delete_if
231 @hash.delete_if { |o,| yield(o) }
232 self
233 end
234
235 # Do collect() destructively.
236 def collect!
237 set = self.class.new
238 each { |o| set << yield(o) }
239 replace(set)
240 end
241 alias map! collect!
242
243 # Equivalent to Set#delete_if, but returns nil if no changes were
244 # made.
245 def reject!
246 n = size
247 delete_if { |o| yield(o) }
248 size == n ? nil : self
249 end
250
251 # Merges the elements of the given enumerable object to the set and
252 # returns self.
253 def merge(enum)
254 if enum.is_a?(Set)
255 @hash.update(enum.instance_eval { @hash })
256 else
257 enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
258 enum.each { |o| add(o) }
259 end
260
261 self
262 end
263
264 # Deletes every element that appears in the given enumerable object
265 # and returns self.
266 def subtract(enum)
267 enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
268 enum.each { |o| delete(o) }
269 self
270 end
271
272 # Returns a new set built by merging the set and the elements of the
273 # given enumerable object.
274 def |(enum)
275 enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
276 dup.merge(enum)
277 end
278 alias + | ##
279 alias union | ##
280
281 # Returns a new set built by duplicating the set, removing every
282 # element that appears in the given enumerable object.
283 def -(enum)
284 enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
285 dup.subtract(enum)
286 end
287 alias difference - ##
288
289 # Returns a new set containing elements common to the set and the
290 # given enumerable object.
291 def &(enum)
292 enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
293 n = self.class.new
294 enum.each { |o| n.add(o) if include?(o) }
295 n
296 end
297 alias intersection & ##
298
299 # Returns a new set containing elements exclusive between the set
300 # and the given enumerable object. (set ^ enum) is equivalent to
301 # ((set | enum) - (set & enum)).
302 def ^(enum)
303 enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
304 n = Set.new(enum)
305 each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }
306 n
307 end
308
309 # Returns true if two sets are equal. The equality of each couple
310 # of elements is defined according to Object#eql?.
311 def ==(set)
312 equal?(set) and return true
313
314 set.is_a?(Set) && size == set.size or return false
315
316 hash = @hash.dup
317 set.all? { |o| hash.include?(o) }
318 end
319
320 def hash # :nodoc:
321 @hash.hash
322 end
323
324 def eql?(o) # :nodoc:
325 return false unless o.is_a?(Set)
326 @hash.eql?(o.instance_eval{@hash})
327 end
328
329 # Classifies the set by the return value of the given block and
330 # returns a hash of {value => set of elements} pairs. The block is
331 # called once for each element of the set, passing the element as
332 # parameter.
333 #
334 # e.g.:
335 #
336 # require 'set'
337 # files = Set.new(Dir.glob("*.rb"))
338 # hash = files.classify { |f| File.mtime(f).year }
339 # p hash # => {2000=>#<Set: {"a.rb", "b.rb"}>,
340 # # 2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
341 # # 2002=>#<Set: {"f.rb"}>}
342 def classify # :yields: o
343 h = {}
344
345 each { |i|
346 x = yield(i)
347 (h[x] ||= self.class.new).add(i)
348 }
349
350 h
351 end
352
353 # Divides the set into a set of subsets according to the commonality
354 # defined by the given block.
355 #
356 # If the arity of the block is 2, elements o1 and o2 are in common
357 # if block.call(o1, o2) is true. Otherwise, elements o1 and o2 are
358 # in common if block.call(o1) == block.call(o2).
359 #
360 # e.g.:
361 #
362 # require 'set'
363 # numbers = Set[1, 3, 4, 6, 9, 10, 11]
364 # set = numbers.divide { |i,j| (i - j).abs == 1 }
365 # p set # => #<Set: {#<Set: {1}>,
366 # # #<Set: {11, 9, 10}>,
367 # # #<Set: {3, 4}>,
368 # # #<Set: {6}>}>
369 def divide(&func)
370 if func.arity == 2
371 require 'tsort'
372
373 class << dig = {} # :nodoc:
374 include TSort
375
376 alias tsort_each_node each_key
377 def tsort_each_child(node, &block)
378 fetch(node).each(&block)
379 end
380 end
381
382 each { |u|
383 dig[u] = a = []
384 each{ |v| func.call(u, v) and a << v }
385 }
386
387 set = Set.new()
388 dig.each_strongly_connected_component { |css|
389 set.add(self.class.new(css))
390 }
391 set
392 else
393 Set.new(classify(&func).values)
394 end
395 end
396
397 InspectKey = :__inspect_key__ # :nodoc:
398
399 # Returns a string containing a human-readable representation of the
400 # set. ("#<Set: {element1, element2, ...}>")
401 def inspect
402 ids = (Thread.current[InspectKey] ||= [])
403
404 if ids.include?(object_id)
405 return sprintf('#<%s: {...}>', self.class.name)
406 end
407
408 begin
409 ids << object_id
410 return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
411 ensure
412 ids.pop
413 end
414 end
415
416 def pretty_print(pp) # :nodoc:
417 pp.text sprintf('#<%s: {', self.class.name)
418 pp.nest(1) {
419 pp.seplist(self) { |o|
420 pp.pp o
421 }
422 }
423 pp.text "}>"
424 end
425
426 def pretty_print_cycle(pp) # :nodoc:
427 pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...')
428 end
429end
430
431# SortedSet implements a set which elements are sorted in order. See Set.
432class SortedSet < Set
433 @@setup = false
434
435 class << self
436 def [](*ary) # :nodoc:
437 new(ary)
438 end
439
440 def setup # :nodoc:
441 @@setup and return
442
443 module_eval {
444 # a hack to shut up warning
445 alias old_init initialize
446 remove_method :old_init
447 }
448 begin
449 require 'rbtree'
450
451 module_eval %{
452 def initialize(*args, &block)
453 @hash = RBTree.new
454 super
455 end
456 }
457 rescue LoadError
458 module_eval %{
459 def initialize(*args, &block)
460 @keys = nil
461 super
462 end
463
464 def clear
465 @keys = nil
466 super
467 end
468
469 def replace(enum)
470 @keys = nil
471 super
472 end
473
474 def add(o)
475 @keys = nil
476 @hash[o] = true
477 self
478 end
479 alias << add
480
481 def delete(o)
482 @keys = nil
483 @hash.delete(o)
484 self
485 end
486
487 def delete_if
488 n = @hash.size
489 @hash.delete_if { |o,| yield(o) }
490 @keys = nil if @hash.size != n
491 self
492 end
493
494 def merge(enum)
495 @keys = nil
496 super
497 end
498
499 def each
500 to_a.each { |o| yield(o) }
501 end
502
503 def to_a
504 (@keys = @hash.keys).sort! unless @keys
505 @keys
506 end
507 }
508 end
509
510 @@setup = true
511 end
512 end
513
514 def initialize(*args, &block) # :nodoc:
515 SortedSet.setup
516 initialize(*args, &block)
517 end
518end
519
520module Enumerable
521 # Makes a set from the enumerable object with given arguments.
522 # Needs to +require "set"+ to use this method.
523 def to_set(klass = Set, *args, &block)
524 klass.new(self, *args, &block)
525 end
526end
527
528# =begin
529# == RestricedSet class
530# RestricedSet implements a set with restrictions defined by a given
531# block.
532#
533# === Super class
534# Set
535#
536# === Class Methods
537# --- RestricedSet::new(enum = nil) { |o| ... }
538# --- RestricedSet::new(enum = nil) { |rset, o| ... }
539# Creates a new restricted set containing the elements of the given
540# enumerable object. Restrictions are defined by the given block.
541#
542# If the block's arity is 2, it is called with the RestrictedSet
543# itself and an object to see if the object is allowed to be put in
544# the set.
545#
546# Otherwise, the block is called with an object to see if the object
547# is allowed to be put in the set.
548#
549# === Instance Methods
550# --- restriction_proc
551# Returns the restriction procedure of the set.
552#
553# =end
554#
555# class RestricedSet < Set
556# def initialize(*args, &block)
557# @proc = block or raise ArgumentError, "missing a block"
558#
559# if @proc.arity == 2
560# instance_eval %{
561# def add(o)
562# @hash[o] = true if @proc.call(self, o)
563# self
564# end
565# alias << add
566#
567# def add?(o)
568# if include?(o) || [email protected](self, o)
569# nil
570# else
571# @hash[o] = true
572# self
573# end
574# end
575#
576# def replace(enum)
577# enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
578# clear
579# enum.each { |o| add(o) }
580#
581# self
582# end
583#
584# def merge(enum)
585# enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
586# enum.each { |o| add(o) }
587#
588# self
589# end
590# }
591# else
592# instance_eval %{
593# def add(o)
594# if @proc.call(o)
595# @hash[o] = true
596# end
597# self
598# end
599# alias << add
600#
601# def add?(o)
602# if include?(o) || [email protected](o)
603# nil
604# else
605# @hash[o] = true
606# self
607# end
608# end
609# }
610# end
611#
612# super(*args)
613# end
614#
615# def restriction_proc
616# @proc
617# end
618# end
619
620if $0 == __FILE__
621 eval DATA.read, nil, $0, __LINE__+4
622end
623
624__END__
625
626require 'test/unit'
627
628class TC_Set < Test::Unit::TestCase
629 def test_aref
630 assert_nothing_raised {
631 Set[]
632 Set[nil]
633 Set[1,2,3]
634 }
635
636 assert_equal(0, Set[].size)
637 assert_equal(1, Set[nil].size)
638 assert_equal(1, Set[[]].size)
639 assert_equal(1, Set[[nil]].size)
640
641 set = Set[2,4,6,4]
642 assert_equal(Set.new([2,4,6]), set)
643 end
644
645 def test_s_new
646 assert_nothing_raised {
647 Set.new()
648 Set.new(nil)
649 Set.new([])
650 Set.new([1,2])
651 Set.new('a'..'c')
652 Set.new('XYZ')
653 }
654 assert_raises(ArgumentError) {
655 Set.new(false)
656 }
657 assert_raises(ArgumentError) {
658 Set.new(1)
659 }
660 assert_raises(ArgumentError) {
661 Set.new(1,2)
662 }
663
664 assert_equal(0, Set.new().size)
665 assert_equal(0, Set.new(nil).size)
666 assert_equal(0, Set.new([]).size)
667 assert_equal(1, Set.new([nil]).size)
668
669 ary = [2,4,6,4]
670 set = Set.new(ary)
671 ary.clear
672 assert_equal(false, set.empty?)
673 assert_equal(3, set.size)
674
675 ary = [1,2,3]
676
677 s = Set.new(ary) { |o| o * 2 }
678 assert_equal([2,4,6], s.sort)
679 end
680
681 def test_clone
682 set1 = Set.new
683 set2 = set1.clone
684 set1 << 'abc'
685 assert_equal(Set.new, set2)
686 end
687
688 def test_dup
689 set1 = Set[1,2]
690 set2 = set1.dup
691
692 assert_not_same(set1, set2)
693
694 assert_equal(set1, set2)
695
696 set1.add(3)
697
698 assert_not_equal(set1, set2)
699 end
700
701 def test_size
702 assert_equal(0, Set[].size)
703 assert_equal(2, Set[1,2].size)
704 assert_equal(2, Set[1,2,1].size)
705 end
706
707 def test_empty?
708 assert_equal(true, Set[].empty?)
709 assert_equal(false, Set[1, 2].empty?)
710 end
711
712 def test_clear
713 set = Set[1,2]
714 ret = set.clear
715
716 assert_same(set, ret)
717 assert_equal(true, set.empty?)
718 end
719
720 def test_replace
721 set = Set[1,2]
722 ret = set.replace('a'..'c')
723
724 assert_same(set, ret)
725 assert_equal(Set['a','b','c'], set)
726 end
727
728 def test_to_a
729 set = Set[1,2,3,2]
730 ary = set.to_a
731
732 assert_equal([1,2,3], ary.sort)
733 end
734
735 def test_flatten
736 # test1
737 set1 = Set[
738 1,
739 Set[
740 5,
741 Set[7,
742 Set[0]
743 ],
744 Set[6,2],
745 1
746 ],
747 3,
748 Set[3,4]
749 ]
750
751 set2 = set1.flatten
752 set3 = Set.new(0..7)
753
754 assert_not_same(set2, set1)
755 assert_equal(set3, set2)
756
757 # test2; destructive
758 orig_set1 = set1
759 set1.flatten!
760
761 assert_same(orig_set1, set1)
762 assert_equal(set3, set1)
763
764 # test3; multiple occurrences of a set in an set
765 set1 = Set[1, 2]
766 set2 = Set[set1, Set[set1, 4], 3]
767
768 assert_nothing_raised {
769 set2.flatten!
770 }
771
772 assert_equal(Set.new(1..4), set2)
773
774 # test4; recursion
775 set2 = Set[]
776 set1 = Set[1, set2]
777 set2.add(set1)
778
779 assert_raises(ArgumentError) {
780 set1.flatten!
781 }
782
783 # test5; miscellaneous
784 empty = Set[]
785 set = Set[Set[empty, "a"],Set[empty, "b"]]
786
787 assert_nothing_raised {
788 set.flatten
789 }
790
791 set1 = empty.merge(Set["no_more", set])
792
793 assert_nil(Set.new(0..31).flatten!)
794
795 x = Set[Set[],Set[1,2]].flatten!
796 y = Set[1,2]
797
798 assert_equal(x, y)
799 end
800
801 def test_include?
802 set = Set[1,2,3]
803
804 assert_equal(true, set.include?(1))
805 assert_equal(true, set.include?(2))
806 assert_equal(true, set.include?(3))
807 assert_equal(false, set.include?(0))
808 assert_equal(false, set.include?(nil))
809
810 set = Set["1",nil,"2",nil,"0","1",false]
811 assert_equal(true, set.include?(nil))
812 assert_equal(true, set.include?(false))
813 assert_equal(true, set.include?("1"))
814 assert_equal(false, set.include?(0))
815 assert_equal(false, set.include?(true))
816 end
817
818 def test_superset?
819 set = Set[1,2,3]
820
821 assert_raises(ArgumentError) {
822 set.superset?()
823 }
824
825 assert_raises(ArgumentError) {
826 set.superset?(2)
827 }
828
829 assert_raises(ArgumentError) {
830 set.superset?([2])
831 }
832
833 assert_equal(true, set.superset?(Set[]))
834 assert_equal(true, set.superset?(Set[1,2]))
835 assert_equal(true, set.superset?(Set[1,2,3]))
836 assert_equal(false, set.superset?(Set[1,2,3,4]))
837 assert_equal(false, set.superset?(Set[1,4]))
838
839 assert_equal(true, Set[].superset?(Set[]))
840 end
841
842 def test_proper_superset?
843 set = Set[1,2,3]
844
845 assert_raises(ArgumentError) {
846 set.proper_superset?()
847 }
848
849 assert_raises(ArgumentError) {
850 set.proper_superset?(2)
851 }
852
853 assert_raises(ArgumentError) {
854 set.proper_superset?([2])
855 }
856
857 assert_equal(true, set.proper_superset?(Set[]))
858 assert_equal(true, set.proper_superset?(Set[1,2]))
859 assert_equal(false, set.proper_superset?(Set[1,2,3]))
860 assert_equal(false, set.proper_superset?(Set[1,2,3,4]))
861 assert_equal(false, set.proper_superset?(Set[1,4]))
862
863 assert_equal(false, Set[].proper_superset?(Set[]))
864 end
865
866 def test_subset?
867 set = Set[1,2,3]
868
869 assert_raises(ArgumentError) {
870 set.subset?()
871 }
872
873 assert_raises(ArgumentError) {
874 set.subset?(2)
875 }
876
877 assert_raises(ArgumentError) {
878 set.subset?([2])
879 }
880
881 assert_equal(true, set.subset?(Set[1,2,3,4]))
882 assert_equal(true, set.subset?(Set[1,2,3]))
883 assert_equal(false, set.subset?(Set[1,2]))
884 assert_equal(false, set.subset?(Set[]))
885
886 assert_equal(true, Set[].subset?(Set[1]))
887 assert_equal(true, Set[].subset?(Set[]))
888 end
889
890 def test_proper_subset?
891 set = Set[1,2,3]
892
893 assert_raises(ArgumentError) {
894 set.proper_subset?()
895 }
896
897 assert_raises(ArgumentError) {
898 set.proper_subset?(2)
899 }
900
901 assert_raises(ArgumentError) {
902 set.proper_subset?([2])
903 }
904
905 assert_equal(true, set.proper_subset?(Set[1,2,3,4]))
906 assert_equal(false, set.proper_subset?(Set[1,2,3]))
907 assert_equal(false, set.proper_subset?(Set[1,2]))
908 assert_equal(false, set.proper_subset?(Set[]))
909
910 assert_equal(false, Set[].proper_subset?(Set[]))
911 end
912
913 def test_each
914 ary = [1,3,5,7,10,20]
915 set = Set.new(ary)
916
917 assert_raises(LocalJumpError) {
918 set.each
919 }
920
921 assert_nothing_raised {
922 set.each { |o|
923 ary.delete(o) or raise "unexpected element: #{o}"
924 }
925
926 ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
927 }
928 end
929
930 def test_add
931 set = Set[1,2,3]
932
933 ret = set.add(2)
934 assert_same(set, ret)
935 assert_equal(Set[1,2,3], set)
936
937 ret = set.add?(2)
938 assert_nil(ret)
939 assert_equal(Set[1,2,3], set)
940
941 ret = set.add(4)
942 assert_same(set, ret)
943 assert_equal(Set[1,2,3,4], set)
944
945 ret = set.add?(5)
946 assert_same(set, ret)
947 assert_equal(Set[1,2,3,4,5], set)
948 end
949
950 def test_delete
951 set = Set[1,2,3]
952
953 ret = set.delete(4)
954 assert_same(set, ret)
955 assert_equal(Set[1,2,3], set)
956
957 ret = set.delete?(4)
958 assert_nil(ret)
959 assert_equal(Set[1,2,3], set)
960
961 ret = set.delete(2)
962 assert_equal(set, ret)
963 assert_equal(Set[1,3], set)
964
965 ret = set.delete?(1)
966 assert_equal(set, ret)
967 assert_equal(Set[3], set)
968 end
969
970 def test_delete_if
971 set = Set.new(1..10)
972 ret = set.delete_if { |i| i > 10 }
973 assert_same(set, ret)
974 assert_equal(Set.new(1..10), set)
975
976 set = Set.new(1..10)
977 ret = set.delete_if { |i| i % 3 == 0 }
978 assert_same(set, ret)
979 assert_equal(Set[1,2,4,5,7,8,10], set)
980 end
981
982 def test_collect!
983 set = Set[1,2,3,'a','b','c',-1..1,2..4]
984
985 ret = set.collect! { |i|
986 case i
987 when Numeric
988 i * 2
989 when String
990 i.upcase
991 else
992 nil
993 end
994 }
995
996 assert_same(set, ret)
997 assert_equal(Set[2,4,6,'A','B','C',nil], set)
998 end
999
1000 def test_reject!
1001 set = Set.new(1..10)
1002
1003 ret = set.reject! { |i| i > 10 }
1004 assert_nil(ret)
1005 assert_equal(Set.new(1..10), set)
1006
1007 ret = set.reject! { |i| i % 3 == 0 }
1008 assert_same(set, ret)
1009 assert_equal(Set[1,2,4,5,7,8,10], set)
1010 end
1011
1012 def test_merge
1013 set = Set[1,2,3]
1014
1015 ret = set.merge([2,4,6])
1016 assert_same(set, ret)
1017 assert_equal(Set[1,2,3,4,6], set)
1018 end
1019
1020 def test_subtract
1021 set = Set[1,2,3]
1022
1023 ret = set.subtract([2,4,6])
1024 assert_same(set, ret)
1025 assert_equal(Set[1,3], set)
1026 end
1027
1028 def test_plus
1029 set = Set[1,2,3]
1030
1031 ret = set + [2,4,6]
1032 assert_not_same(set, ret)
1033 assert_equal(Set[1,2,3,4,6], ret)
1034 end
1035
1036 def test_minus
1037 set = Set[1,2,3]
1038
1039 ret = set - [2,4,6]
1040 assert_not_same(set, ret)
1041 assert_equal(Set[1,3], ret)
1042 end
1043
1044 def test_and
1045 set = Set[1,2,3,4]
1046
1047 ret = set & [2,4,6]
1048 assert_not_same(set, ret)
1049 assert_equal(Set[2,4], ret)
1050 end
1051
1052 def test_xor
1053 set = Set[1,2,3,4]
1054 ret = set ^ [2,4,5,5]
1055 assert_not_same(set, ret)
1056 assert_equal(Set[1,3,5], ret)
1057 end
1058
1059 def test_eq
1060 set1 = Set[2,3,1]
1061 set2 = Set[1,2,3]
1062
1063 assert_equal(set1, set1)
1064 assert_equal(set1, set2)
1065 assert_not_equal(Set[1], [1])
1066
1067 set1 = Class.new(Set)["a", "b"]
1068 set2 = Set["a", "b", set1]
1069 set1 = set1.add(set1.clone)
1070
1071# assert_equal(set1, set2)
1072# assert_equal(set2, set1)
1073 assert_equal(set2, set2.clone)
1074 assert_equal(set1.clone, set1)
1075
1076 assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], "[ruby-dev:26127]")
1077 end
1078
1079 # def test_hash
1080 # end
1081
1082 # def test_eql?
1083 # end
1084
1085 def test_classify
1086 set = Set.new(1..10)
1087 ret = set.classify { |i| i % 3 }
1088
1089 assert_equal(3, ret.size)
1090 assert_instance_of(Hash, ret)
1091 ret.each_value { |value| assert_instance_of(Set, value) }
1092 assert_equal(Set[3,6,9], ret[0])
1093 assert_equal(Set[1,4,7,10], ret[1])
1094 assert_equal(Set[2,5,8], ret[2])
1095 end
1096
1097 def test_divide
1098 set = Set.new(1..10)
1099 ret = set.divide { |i| i % 3 }
1100
1101 assert_equal(3, ret.size)
1102 n = 0
1103 ret.each { |s| n += s.size }
1104 assert_equal(set.size, n)
1105 assert_equal(set, ret.flatten)
1106
1107 set = Set[7,10,5,11,1,3,4,9,0]
1108 ret = set.divide { |a,b| (a - b).abs == 1 }
1109
1110 assert_equal(4, ret.size)
1111 n = 0
1112 ret.each { |s| n += s.size }
1113 assert_equal(set.size, n)
1114 assert_equal(set, ret.flatten)
1115 ret.each { |s|
1116 if s.include?(0)
1117 assert_equal(Set[0,1], s)
1118 elsif s.include?(3)
1119 assert_equal(Set[3,4,5], s)
1120 elsif s.include?(7)
1121 assert_equal(Set[7], s)
1122 elsif s.include?(9)
1123 assert_equal(Set[9,10,11], s)
1124 else
1125 raise "unexpected group: #{s.inspect}"
1126 end
1127 }
1128 end
1129
1130 def test_inspect
1131 set1 = Set[1]
1132
1133 assert_equal('#<Set: {1}>', set1.inspect)
1134
1135 set2 = Set[Set[0], 1, 2, set1]
1136 assert_equal(false, set2.inspect.include?('#<Set: {...}>'))
1137
1138 set1.add(set2)
1139 assert_equal(true, set1.inspect.include?('#<Set: {...}>'))
1140 end
1141
1142 # def test_pretty_print
1143 # end
1144
1145 # def test_pretty_print_cycle
1146 # end
1147end
1148
1149class TC_SortedSet < Test::Unit::TestCase
1150 def test_sortedset
1151 s = SortedSet[4,5,3,1,2]
1152
1153 assert_equal([1,2,3,4,5], s.to_a)
1154
1155 prev = nil
1156 s.each { |o| assert(prev < o) if prev; prev = o }
1157 assert_not_nil(prev)
1158
1159 s.map! { |o| -2 * o }
1160
1161 assert_equal([-10,-8,-6,-4,-2], s.to_a)
1162
1163 prev = nil
1164 s.each { |o| assert(prev < o) if prev; prev = o }
1165 assert_not_nil(prev)
1166
1167 s = SortedSet.new([2,1,3]) { |o| o * -2 }
1168 assert_equal([-6,-4,-2], s.to_a)
1169 end
1170end
1171
1172class TC_Enumerable < Test::Unit::TestCase
1173 def test_to_set
1174 ary = [2,5,4,3,2,1,3]
1175
1176 set = ary.to_set
1177 assert_instance_of(Set, set)
1178 assert_equal([1,2,3,4,5], set.sort)
1179
1180 set = ary.to_set { |o| o * -2 }
1181 assert_instance_of(Set, set)
1182 assert_equal([-10,-8,-6,-4,-2], set.sort)
1183
1184 set = ary.to_set(SortedSet)
1185 assert_instance_of(SortedSet, set)
1186 assert_equal([1,2,3,4,5], set.to_a)
1187
1188 set = ary.to_set(SortedSet) { |o| o * -2 }
1189 assert_instance_of(SortedSet, set)
1190 assert_equal([-10,-8,-6,-4,-2], set.sort)
1191 end
1192end
1193
1194# class TC_RestricedSet < Test::Unit::TestCase
1195# def test_s_new
1196# assert_raises(ArgumentError) { RestricedSet.new }
1197#
1198# s = RestricedSet.new([-1,2,3]) { |o| o > 0 }
1199# assert_equal([2,3], s.sort)
1200# end
1201#
1202# def test_restriction_proc
1203# s = RestricedSet.new([-1,2,3]) { |o| o > 0 }
1204#
1205# f = s.restriction_proc
1206# assert_instance_of(Proc, f)
1207# assert(f[1])
1208# assert(!f[0])
1209# end
1210#
1211# def test_replace
1212# s = RestricedSet.new(-3..3) { |o| o > 0 }
1213# assert_equal([1,2,3], s.sort)
1214#
1215# s.replace([-2,0,3,4,5])
1216# assert_equal([3,4,5], s.sort)
1217# end
1218#
1219# def test_merge
1220# s = RestricedSet.new { |o| o > 0 }
1221# s.merge(-5..5)
1222# assert_equal([1,2,3,4,5], s.sort)
1223#
1224# s.merge([10,-10,-8,8])
1225# assert_equal([1,2,3,4,5,8,10], s.sort)
1226# end
1227# end
Note: See TracBrowser for help on using the repository browser.