motion-kramdown 0.5.0

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