rhodes 2.0.0.beta1 → 2.0.0.beta2

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