xqsr3 0.32.3 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5362a61770df81001025713c2465c5ed9bea6a49
4
- data.tar.gz: 70f643bccc5e09b76acf3a4944e02dbe0e763d6a
3
+ metadata.gz: '0873ccfa9e001a7bb29a4ef649e0f8859034943c'
4
+ data.tar.gz: 4ad53d843bf50bee3de784cd0d4f5a4c3a805ca2
5
5
  SHA512:
6
- metadata.gz: 8cc83e03876a54224a4f4a28ea3ebf4ff289b2a4f8b11d1c727c41716a3ef68e670d10dd0f796d5b3273124b9308a0e4701fae02a030856f1183a2dafae3b2cb
7
- data.tar.gz: 3b12d249383fddfde861575e9ed42a329220aba5b47f22204afdf0b5a3317290460004071e3c2d3a4c9590231b5eb61a01c38e1ca6f093ed2cd696ea7095469f
6
+ metadata.gz: 82bc550fbd48138ad719681c51eb82e6075a4878772154eb9daa190e78c745b70e0ace321e9c700fcaadbaec8eb7b707a484ac6e93e0fd531b777aa0b0a0be6e
7
+ data.tar.gz: f00c2be6e62d527c21ff3283004a1c0acdeccb65faec73af41fe74f471ef301bd3b7ac6fc23c6c1a107f4e7f5f09872dad5be0b50d6dcbe7ad00111743829721
@@ -5,7 +5,7 @@
5
5
  # Purpose: FrequencyMap container
6
6
  #
7
7
  # Created: 28th January 2005
8
- # Updated: 12th April 2019
8
+ # Updated: 15th April 2019
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
@@ -77,6 +77,7 @@ class FrequencyMap
77
77
  # fm[:z] # => 0
78
78
  ByElement = Class.new do
79
79
 
80
+ # Create an instance of Xqsr3::FrequencyMap from an array
80
81
  def self.[] *args
81
82
 
82
83
  fm = FrequencyMap.new
@@ -180,12 +181,16 @@ class FrequencyMap
180
181
 
181
182
  case rhs
182
183
  when ::NilClass
184
+
183
185
  return false
184
186
  when ::Hash
187
+
185
188
  return rhs.size == @elements.size && rhs == @elements
186
189
  when self.class
190
+
187
191
  return rhs.count == self.count && rhs == @elements
188
192
  else
193
+
189
194
  raise TypeError, "can compare #{self.class} only to instances of #{self.class} and #{::Hash}, but #{rhs.class} given"
190
195
  end
191
196
 
@@ -407,6 +412,12 @@ class FrequencyMap
407
412
 
408
413
  # Returns +true+ if an element with a count of the given +value+ is in the
409
414
  # map; +false+ otherwise
415
+ #
416
+ # * *Parameters:*
417
+ # - +value+ (Integer) The value of the count for which to search
418
+ #
419
+ # * *Exceptions:*
420
+ # - +::TypeError+ if +value+ is not an Integer
410
421
  def has_value? value
411
422
 
412
423
  case value
@@ -437,6 +448,8 @@ class FrequencyMap
437
448
  #
438
449
  # @elements.keep_if
439
450
  # end
451
+ =begin
452
+ =end
440
453
 
441
454
  # Returns the element that has the given count, or +nil+ if none found
442
455
  #
@@ -540,6 +553,8 @@ class FrequencyMap
540
553
  self
541
554
  end
542
555
 
556
+ # Removes a key-value pair from the instance and return as a two-item
557
+ # array
543
558
  def shift
544
559
 
545
560
  r = @elements.shift
@@ -589,11 +604,13 @@ class FrequencyMap
589
604
  @elements.to_hash
590
605
  end
591
606
 
607
+ # A string-form of the instance
592
608
  def to_s
593
609
 
594
610
  @elements.to_s
595
611
  end
596
612
 
613
+ # An array of all frequencies (without element keys) in the instance
597
614
  def values
598
615
 
599
616
  @elements.values
@@ -5,7 +5,7 @@
5
5
  # Purpose: multimap container
6
6
  #
7
7
  # Created: 21st March 2007
8
- # Updated: 12th April 2019
8
+ # Updated: 15th April 2019
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
@@ -73,16 +73,16 @@ class MultiMap < ::Hash
73
73
  return self.new
74
74
  when ::Hash
75
75
 
76
- fm = self.new
76
+ mm = self.new
77
77
 
78
78
  arg.each do |k, v|
79
79
 
80
80
  raise ArgumentError, "mapped elements in hashes must be arrays, #{v.class} given" unless v.kind_of? ::Array
81
81
 
82
- fm.store k, *v
82
+ mm.store k, *v
83
83
  end
84
84
 
85
- return fm
85
+ return mm
86
86
  when ::Array
87
87
 
88
88
  # accepted forms:
@@ -133,6 +133,8 @@ class MultiMap < ::Hash
133
133
  # Initialises an instance
134
134
  def initialize
135
135
 
136
+ @merge_is_multi = true
137
+
136
138
  @inner = Hash.new
137
139
  end
138
140
 
@@ -143,6 +145,16 @@ class MultiMap < ::Hash
143
145
  return @inner[key]
144
146
  end
145
147
 
148
+ # Adds/assigns a new key+values pair. Equivalent to
149
+ #
150
+ # store(key, *values)
151
+ #
152
+ # * *Parameters:*
153
+ # - +key+ The element key
154
+ # - +values+ (Array) The values to be associated with the key
155
+ #
156
+ # * *Exceptions:*
157
+ # - +::TypeError+ if +values+ is not an array
146
158
  def []= key, values
147
159
 
148
160
  values = [] if values.nil?
@@ -203,9 +215,17 @@ class MultiMap < ::Hash
203
215
  @inner.delete key
204
216
  end
205
217
 
218
+ # Calls _block_ once for each key-value pair, passing the key and each
219
+ # of its values in turn. If the values for a given key are empty and
220
+ # +defaults+ is not empty, the block is invoked for that key (with
221
+ # +defaults[0]+) once
222
+ #
223
+ # * *Exceptions:*
224
+ # - +ArgumentError+ if more than 1 +defaults+ is provided, or no block is given
206
225
  def each *defaults
207
226
 
208
227
  raise ArgumentError, "may only supply 0 or 1 defaults" if defaults.size > 1
228
+ raise ArgumentError, 'block is required' unless block_given?
209
229
 
210
230
  @inner.each do |key, values|
211
231
 
@@ -220,8 +240,8 @@ class MultiMap < ::Hash
220
240
  end
221
241
  end
222
242
 
223
- # Calls _block_ once for each element in the instance, passing the
224
- # key. If no block is provided, an enumerator is returned
243
+ # Calls _block_ once for each key in the instance, passing the key. If no
244
+ # block is provided, an enumerator is returned
225
245
  def each_key
226
246
 
227
247
  return @inner.each_key unless block_given?
@@ -229,26 +249,46 @@ class MultiMap < ::Hash
229
249
  @inner.each_key { |key| yield key }
230
250
  end
231
251
 
252
+ # Calls _block_ once for each key-values pair, passing the key and its
253
+ # values array. If no block is provided, an enumerator is returned
232
254
  def each_unflattened
233
255
 
256
+ return @inner.each unless block_given?
257
+
234
258
  @inner.each { |key, value| yield key, value }
235
259
  end
236
260
 
261
+ # Calls _block_ once for each key-values pair, passing the key and its
262
+ # values array and a key index. If no block is provided, an enumerator
263
+ # is returned
237
264
  def each_unflattened_with_index
238
265
 
266
+ return @inner.each_with_index unless block_given?
267
+
239
268
  @inner.each_with_index { |kv, index| yield kv, index }
240
269
  end
241
270
 
271
+ # Calls _block_ once for each value in the instance, passing the value.
272
+ # If no block is provided, an enumerator is returned
242
273
  def each_value
243
274
 
275
+ return @inner.each_value unless block_given?
276
+
244
277
  @inner.each do |key, values|
245
278
 
246
279
  values.each { |value| yield value }
247
280
  end
248
281
  end
249
282
 
283
+ # Calls _block_ once for each key-values, passing the key and each of its
284
+ # values and a value index
285
+ #
286
+ # * *Exceptions:*
287
+ # - +ArgumentError+ if no block is given
250
288
  def each_with_index
251
289
 
290
+ raise ArgumentError, 'block is required' unless block_given?
291
+
252
292
  index = 0
253
293
  self.each do |key, value|
254
294
 
@@ -276,18 +316,26 @@ class MultiMap < ::Hash
276
316
  end
277
317
  end
278
318
 
279
- def fetch key, default = nil, &block
319
+ # Returns the values associated with the given key
320
+ #
321
+ # * *Parameters:*
322
+ # - +key+ The key
323
+ # - +default+ The default value
324
+ def fetch key, default = (default_parameter_defaulted_ = true; nil), &block
280
325
 
281
- case default
282
- when ::NilClass, ::Array
283
- ;
284
- else
285
- raise TypeError, "default parameter ('#{default}') must be of type #{::Array}, but was of type #{default.class}"
326
+ unless default_parameter_defaulted_
327
+
328
+ case default
329
+ when ::NilClass, ::Array
330
+ ;
331
+ else
332
+ raise TypeError, "default parameter ('#{default}') must be of type #{::Array}, but was of type #{default.class}"
333
+ end
286
334
  end
287
335
 
288
336
  unless @inner.has_key? key
289
337
 
290
- return default unless default.nil?
338
+ return default unless default_parameter_defaulted_
291
339
 
292
340
  if block_given?
293
341
 
@@ -349,31 +397,127 @@ class MultiMap < ::Hash
349
397
  @inner.has_key? key
350
398
  end
351
399
 
400
+ # Returns +true+ if any key has the given +value+; +false+ otherwise
401
+ #
402
+ # * *Parameters:*
403
+ # - +value+ The value for which to search
352
404
  def has_value? value
353
405
 
354
- @inner.has_value? value
406
+ @inner.each do |k, vals|
407
+
408
+ return true if vals.include? value
409
+ end
410
+
411
+ false
412
+ end
413
+
414
+ # Returns +true+ if any key has the given +values+; +false+ otherwise
415
+ #
416
+ # * *Parameters:*
417
+ # - +values+ (Array) The values for which to search
418
+ #
419
+ # * *Exceptions:*
420
+ # - +::TypeError+ if +value+ is not an Array
421
+ def has_values? values
422
+
423
+ raise TypeError, "'values' parameter must be of type #{::Array}" unless Array === values
424
+
425
+ @inner.has_value? values
355
426
  end
356
427
 
357
- def key value
428
+ # Returns the key for the given value(s)
429
+ #
430
+ # * *Parameters:*
431
+ # - +values+ (Array) The value(s) for which to search
432
+ #
433
+ # If a single value is specified, the entries in the instance are
434
+ # searched first for an exact match to all (1) value(s); if that fails,
435
+ # then the first key with a values containing the given value is
436
+ # returned
437
+ def key *values
438
+
439
+ case values.size
440
+ when 0
441
+
442
+ return nil
443
+ when 1
444
+
445
+ i = nil
446
+
447
+ @inner.each do |k, vals|
448
+
449
+ return k if vals == values
450
+
451
+ if i.nil?
452
+
453
+ i = k if vals.include? values[0]
454
+ end
455
+ end
456
+
457
+ return i
458
+ else
459
+
460
+ @inner.each do |key, vals|
461
+
462
+ return key if vals == values
463
+ end
358
464
 
359
- @inner.key value
465
+ return nil
466
+ end
360
467
  end
361
468
 
362
- def merge fm
469
+ # The number of elements in the map
470
+ def length
363
471
 
364
- raise TypeError, "parameter must be an instance of type #{self.class}" unless fm.instance_of? self.class
472
+ @inner.size
473
+ end
365
474
 
366
- fm_new = self.class.new
475
+ # Returns a new instance containing a merging of the current instance and
476
+ # the +other+ instance
477
+ #
478
+ # NOTE: where any key is found in both merging instances the values
479
+ # resulting will be a concatenation of the sets of values
480
+ #
481
+ # * *Parameters:*
482
+ # - +other+ (MultiMap, Hash) The instance from which to merge
483
+ #
484
+ # * *Exceptions:*
485
+ # - +TypeError+ Raised if +other+ is not a MultiMap or a Hash
486
+ def multi_merge other
367
487
 
368
- fm_new.merge! self
369
- fm_new.merge! fm
488
+ mm = self.class.new
370
489
 
371
- fm_new
490
+ mm.merge! self
491
+ mm.merge! other
492
+
493
+ mm
372
494
  end
373
495
 
374
- def merge! fm
496
+ # Merges the contents of +other+ into the current instance
497
+ #
498
+ # NOTE: where any key is found in both merging instances the values
499
+ # resulting will be a concatenation of the sets of values
500
+ #
501
+ # * *Parameters:*
502
+ # - +other+ (MultiMap, Hash) The instance from which to merge
503
+ #
504
+ # * *Exceptions:*
505
+ # - +TypeError+ Raised if +other+ is not a MultiMap or a Hash
506
+ def multi_merge! other
507
+
508
+ case other
509
+ when self.class
510
+
511
+ ;
512
+ when ::Hash
375
513
 
376
- fm.each do |k, v|
514
+ ;
515
+ else
516
+
517
+ raise TypeError, "parameter must be an instance of #{self.class} or #{Hash}"
518
+ end
519
+
520
+ other.each do |k, v|
377
521
 
378
522
  self.push k, v
379
523
  end
@@ -381,6 +525,96 @@ class MultiMap < ::Hash
381
525
  self
382
526
  end
383
527
 
528
+ # Returns a new instance containing a merging of the current instance and
529
+ # the +other+ instance
530
+ #
531
+ # NOTE: where any key is found in both merging instances the values from
532
+ # +other+ will be used
533
+ #
534
+ # * *Parameters:*
535
+ # - +other+ (MultiMap, Hash) The instance from which to merge
536
+ #
537
+ # * *Exceptions:*
538
+ # - +TypeError+ Raised if +other+ is not a MultiMap or a Hash
539
+ def strict_merge other
540
+
541
+ mm = self.class.new
542
+
543
+ mm.strict_merge! self
544
+ mm.strict_merge! other
545
+
546
+ mm
547
+ end
548
+
549
+ # Merges the contents of +other+ into the current instance
550
+ #
551
+ # NOTE: where any key is found in both merging instances the values from
552
+ # +other+ will be used
553
+ #
554
+ # * *Parameters:*
555
+ # - +other+ (MultiMap, Hash) The instance from which to merge
556
+ #
557
+ # * *Exceptions:*
558
+ # - +TypeError+ Raised if +other+ is not a MultiMap or a Hash
559
+ def strict_merge! other
560
+
561
+ case other
562
+ when self.class
563
+
564
+ other.each_unflattened do |k, vals|
565
+
566
+ self.store k, *vals
567
+ end
568
+ when ::Hash
569
+
570
+ other.each do |k, v|
571
+
572
+ self.store k, v
573
+ end
574
+ else
575
+
576
+ raise TypeError, "parameter must be an instance of #{self.class} or #{Hash}"
577
+ end
578
+
579
+ self
580
+ end
581
+
582
+ # See #merge
583
+ def merge other
584
+
585
+ if @merge_is_multi
586
+
587
+ multi_merge other
588
+ else
589
+
590
+ strict_merge other
591
+ end
592
+ end
593
+
594
+ # See #merge!
595
+ def merge! other
596
+
597
+ if @merge_is_multi
598
+
599
+ multi_merge! other
600
+ else
601
+
602
+ strict_merge! other
603
+ end
604
+ end
605
+
606
+ # Pushes the given +key+ and +values+. If the +key+ is already in the
607
+ # map then the +values+ will be concatenated with those already present
608
+ #
609
+ # === Signature
610
+ #
611
+ # * *Parameters:*
612
+ # - +key+ The element key
613
+ # - +values+ (*Array) The value(s) to be pushed
614
+ #
615
+ # === Exceptions
616
+ # - +::RangeError+ raised if the value of +count+ results in a negative count for the given element
617
+ # - +::TypeError+ if +count+ is not an +::Integer+
384
618
  def push key, *values
385
619
 
386
620
  @inner[key] = [] unless @inner.has_key? key
@@ -388,33 +622,60 @@ class MultiMap < ::Hash
388
622
  @inner[key].push(*values)
389
623
  end
390
624
 
625
+ # Removes a key-value pair from the instance and return as a two-item
626
+ # array
391
627
  def shift
392
628
 
393
629
  @inner.shift
394
630
  end
395
631
 
396
- def size
397
-
398
- @inner.size
399
- end
632
+ alias size length
400
633
 
634
+ # Causes an element with the given +key+ and +values+ to be stored. If an
635
+ # element with the given +key+ already exists, its values will b
636
+ # replaced
401
637
  def store key, *values
402
638
 
403
639
  @inner[key] = values
404
640
  end
405
641
 
642
+ # Converts instance to an array of +[key,value]+ pairs
406
643
  def to_a
407
644
 
408
645
  self.flatten
409
646
  end
410
647
 
648
+ # Obtains reference to internal hash instance (which must *not* be modified)
411
649
  def to_h
412
650
 
413
- @inner.dup
651
+ @inner.to_h
414
652
  end
415
653
 
654
+ # Obtains equivalent hash to instance
655
+ def to_hash
656
+
657
+ @elements.to_hash
658
+ end
659
+
660
+ # A string-form of the instance
661
+ def to_s
662
+
663
+ @inner.to_s
664
+ end
665
+
666
+ # An array of all values in the instance
416
667
  def values
417
668
 
669
+ r = []
670
+
671
+ @inner.values.each { |vals| r += vals }
672
+
673
+ r
674
+ end
675
+
676
+ # An array of all sets of values in the instance
677
+ def values_unflattened
678
+
418
679
  @inner.values
419
680
  end
420
681
  end # class MultiMap
@@ -54,8 +54,10 @@ module Diagnostics
54
54
 
55
55
  module InspectBuilder
56
56
 
57
- module InspectBuilder_Utilities
57
+ # @!visibility private
58
+ module InspectBuilder_Utilities # :nodoc: all
58
59
 
60
+ # @!visibility private
59
61
  NORMALISE_FUNCTION = lambda { |ar| ar.map { |v| v.to_s }.map { |v| '@' == v[0] ? v : "@#{v}" } }
60
62
  end # module InspectBuilder_Utilities
61
63
 
@@ -157,6 +159,8 @@ module InspectBuilder
157
159
  end
158
160
 
159
161
  # Creates an inspect string from self
162
+ #
163
+ # see InspectBuilder::make_inspect
160
164
  def make_inspect **options
161
165
 
162
166
  ::Xqsr3::Diagnostics::InspectBuilder.make_inspect self, **options
@@ -6,13 +6,13 @@
6
6
  # module
7
7
  #
8
8
  # Created: 15th November 2017
9
- # Updated: 15th November 2017
9
+ # Updated: 15th April 2019
10
10
  #
11
11
  # Home: http://github.com/synesissoftware/xqsr3
12
12
  #
13
13
  # Author: Matthew Wilson
14
14
  #
15
- # Copyright (c) 2017, Matthew Wilson and Synesis Software
15
+ # Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
16
16
  # All rights reserved.
17
17
  #
18
18
  # Redistribution and use in source and binary forms, with or without
@@ -56,10 +56,12 @@ require 'xqsr3/quality/parameter_checking'
56
56
  module Xqsr3
57
57
  module HashUtilities
58
58
 
59
+ # +include+-able module that provides ::has_match?, #has_match?, ::match,
60
+ # and #match methods
59
61
  module KeyMatching
60
62
 
61
63
  private
62
- def self.do_match_ h, re, **options
64
+ def self.do_match_ h, re, **options # :nodoc:
63
65
 
64
66
  ::Xqsr3::Quality::ParameterChecking.check_parameter h, 'h', responds_to: [ :[], :has_key?, :each ]
65
67
 
@@ -97,7 +99,7 @@ module KeyMatching
97
99
  nil
98
100
  end
99
101
 
100
- def self.do_has_match_ h, re, **options
102
+ def self.do_has_match_ h, re, **options # :nodoc:
101
103
 
102
104
  ::Xqsr3::Quality::ParameterChecking.check_parameter h, 'h', responds_to: [ :[], :has_key?, :each ]
103
105
 
@@ -3,30 +3,46 @@
3
3
  # Test::Unit module
4
4
 
5
5
  require 'test/unit'
6
+
6
7
  begin
7
8
 
8
9
  require 'test/unit/version'
9
10
 
11
+ # :stopdoc:
12
+ # @!visibility private
10
13
  module Xqsr3
14
+ # @!visibility private
11
15
  module Internal_ # :nodoc:
16
+ # @!visibility private
12
17
  module TestUnitVersion_ # :nodoc:
13
18
 
19
+ # @!visibility private
14
20
  TEST_UNIT_VERSION_ = Test::Unit::VERSION # :nodoc:
15
21
  end # module TestUnitVersion_
16
22
  end # module Internal_
17
23
  end # module Xqsr3
24
+
25
+ # :startdoc:
18
26
  rescue LoadError
19
27
 
28
+ # @!visibility private
20
29
  module Xqsr3
30
+ # @!visibility private
21
31
  module Internal_ # :nodoc:
32
+ # @!visibility private
22
33
  module TestUnitVersion_ # :nodoc:
23
34
 
35
+ # @!visibility private
24
36
  TEST_UNIT_VERSION_ = :not_found # :nodoc:
25
37
  end # module TestUnitVersion_
26
38
  end # module Internal_
27
39
  end # module Xqsr3
40
+
41
+ # :startdoc:
28
42
  end
29
43
 
44
+ # :stopdoc:
45
+
30
46
  module Xqsr3
31
47
  module Internal_ # :nodoc:
32
48
  module TestUnitVersion_ # :nodoc:
@@ -47,6 +63,7 @@ module TestUnitVersion_ # :nodoc:
47
63
  TEST_UNIT_VERSION_PATCH_ = TEST_UNIT_VERSION_PARTS_[2] # :nodoc:
48
64
  end
49
65
 
66
+ # @!visibility private
50
67
  def self.less_ a1, a2 # :nodoc:
51
68
 
52
69
  n_common = a1.size < a2.size ? a1.size : a2.size
@@ -79,6 +96,7 @@ module TestUnitVersion_ # :nodoc:
79
96
  end
80
97
  end
81
98
 
99
+ # @!visibility private
82
100
  def self.is_major_at_least? j # :nodoc:
83
101
 
84
102
  return unless TEST_UNIT_VERSION_MAJOR_
@@ -86,6 +104,7 @@ module TestUnitVersion_ # :nodoc:
86
104
  return j >= TEST_UNIT_VERSION_MAJOR_
87
105
  end
88
106
 
107
+ # @!visibility private
89
108
  def self.is_minor_at_least? n # :nodoc:
90
109
 
91
110
  return unless TEST_UNIT_VERSION_MINOR_
@@ -93,6 +112,7 @@ module TestUnitVersion_ # :nodoc:
93
112
  return n >= TEST_UNIT_VERSION_MINOR_
94
113
  end
95
114
 
115
+ # @!visibility private
96
116
  def self.is_at_least? v # :nodoc:
97
117
 
98
118
  v = v.split(/\./).collect { |n| n.to_i } if String === v
@@ -100,6 +120,7 @@ module TestUnitVersion_ # :nodoc:
100
120
  return !less_(TEST_UNIT_VERSION_PARTS_, v)
101
121
  end
102
122
 
123
+ # @!visibility private
103
124
  def self.is_less? v # :nodoc:
104
125
 
105
126
  v = v.split(/\./).collect { |n| n.to_i } if String === v
@@ -111,4 +132,6 @@ end # module TestUnitVersion_
111
132
  end # module Internal_
112
133
  end # module Xqsr3
113
134
 
135
+ # :startdoc:
136
+
114
137
 
@@ -5,7 +5,7 @@
5
5
  # Purpose: Version for Xqsr3 library
6
6
  #
7
7
  # Created: 3rd April 2016
8
- # Updated: 12th April 2019
8
+ # Updated: 15th April 2019
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
@@ -50,7 +50,7 @@
50
50
  module Xqsr3
51
51
 
52
52
  # Current version of the Xqsr3 library
53
- VERSION = '0.32.3'
53
+ VERSION = '0.33.0'
54
54
 
55
55
  private
56
56
  VERSION_PARTS_ = VERSION.split(/[.]/).collect { |n| n.to_i } # :nodoc:
@@ -481,7 +481,7 @@ class Test_Xqsr3_Containers_MultiMap < Test::Unit::TestCase
481
481
 
482
482
  assert_not mm.has_key? :abc
483
483
 
484
- mm.push :abc
484
+ mm.push :abc, *[ :v1, :v2 ]
485
485
 
486
486
  assert mm.has_key? :abc
487
487
 
@@ -494,15 +494,37 @@ class Test_Xqsr3_Containers_MultiMap < Test::Unit::TestCase
494
494
 
495
495
  mm = MultiMap.new
496
496
 
497
- assert_not mm.has_value? []
497
+ assert_not mm.has_value? :abc
498
+
499
+ mm.push :abc, *[ :v1, :v2 ]
500
+
501
+ assert mm.has_value? :v1
502
+ assert mm.has_value? :v2
503
+ assert_not mm.has_value? :v3
504
+
505
+ mm.delete :abc
506
+
507
+ assert_not mm.has_value? :abc
508
+ end
509
+
510
+ def test_has_values?
511
+
512
+ mm = MultiMap.new
513
+
514
+ assert_not mm.has_values? []
498
515
 
499
516
  mm.push :abc
500
517
 
501
- assert mm.has_value? []
518
+ assert mm.has_values? []
519
+
520
+ mm.push :abc, * [ :v1, :v2 ]
521
+
522
+ assert_not mm.has_values? []
523
+ assert mm.has_values? [ :v1, :v2 ]
502
524
 
503
525
  mm.delete :abc
504
526
 
505
- assert_not mm.has_value? []
527
+ assert_not mm.has_values? []
506
528
  end
507
529
 
508
530
  def test_key
@@ -512,13 +534,43 @@ class Test_Xqsr3_Containers_MultiMap < Test::Unit::TestCase
512
534
  assert_nil mm.key []
513
535
  assert_nil mm.key :not_defined
514
536
 
515
- mm.push :abc
537
+ mm.push :abc, :v1
516
538
 
517
- assert_equal :abc, mm.key([])
539
+ assert_equal :abc, mm.key(:v1)
540
+ assert_nil mm.key(:v2)
518
541
 
519
- mm.push :abc, 1
542
+ mm.push :abc, :v2
543
+
544
+ assert_equal :abc, mm.key(:v1)
545
+ assert_equal :abc, mm.key(:v2)
546
+ assert_equal :abc, mm.key(:v1, :v2)
547
+ assert_nil mm.key(:v2, :v1)
548
+ assert_nil mm.key([:v1, :v2])
549
+
550
+ mm.delete :abc
551
+
552
+ mm.push :def, :v2, :v1
553
+
554
+ assert_equal :def, mm.key(:v2, :v1)
555
+ assert_nil mm.key(:v1, :v2)
556
+ assert_equal :def, mm.key(:v1)
557
+ assert_equal :def, mm.key(:v2)
558
+
559
+ mm.delete :def
560
+
561
+ mm.push :ghi, [ :v2, :v1 ]
562
+
563
+ assert_equal :ghi, mm.key([:v2, :v1])
564
+ assert_nil mm.key([:v1, :v2])
565
+ assert_nil mm.key(:v1)
566
+ assert_nil mm.key(:v2)
567
+
568
+ mm.push :ghi, :v1
520
569
 
521
- assert_equal :abc, mm.key([ 1 ])
570
+ assert_equal :ghi, mm.key([:v2, :v1])
571
+ assert_nil mm.key([:v1, :v2])
572
+ assert_equal :ghi, mm.key(:v1)
573
+ assert_nil mm.key(:v2)
522
574
  end
523
575
 
524
576
  def test_length_and_size
@@ -549,7 +601,7 @@ class Test_Xqsr3_Containers_MultiMap < Test::Unit::TestCase
549
601
  test_length_and_size
550
602
  end
551
603
 
552
- def test_merge
604
+ def test_multi_merge
553
605
 
554
606
  mm1 = MultiMap.new
555
607
 
@@ -562,12 +614,42 @@ class Test_Xqsr3_Containers_MultiMap < Test::Unit::TestCase
562
614
  mm2.push :abc, 4, 5
563
615
  mm2.push :def, 'a'
564
616
 
565
- mm3 = mm1.merge mm2
617
+ mm3 = mm1.multi_merge mm2
566
618
 
567
- assert_equal [ :abc, 1, :abc, 2, :abc, 3, :abc, 4, :abc, 5, :def, 'a' ], mm3.flatten
619
+ h = Hash.new
620
+
621
+ h.store :ghi, 'x'
622
+
623
+ mm4 = mm3.multi_merge h
624
+
625
+ assert_equal [ :abc, 1, :abc, 2, :abc, 3, :abc, 4, :abc, 5, :def, 'a', :ghi, 'x' ], mm4.flatten
626
+ end
627
+
628
+ def test_multi_merge!
629
+
630
+ mm1 = MultiMap.new
631
+
632
+ mm1.push :abc, 1, 2, 3
633
+
634
+ assert_equal [ :abc, 1, :abc, 2, :abc, 3 ], mm1.flatten
635
+
636
+ mm2 = MultiMap.new
637
+
638
+ mm2.push :abc, 4, 5
639
+ mm2.push :def, 'a'
640
+
641
+ mm1.multi_merge! mm2
642
+
643
+ h = Hash.new
644
+
645
+ h.store :ghi, 'x'
646
+
647
+ mm1.multi_merge! h
648
+
649
+ assert_equal [ :abc, 1, :abc, 2, :abc, 3, :abc, 4, :abc, 5, :def, 'a', :ghi, 'x' ], mm1.flatten
568
650
  end
569
651
 
570
- def test_merge!
652
+ def test_strict_merge
571
653
 
572
654
  mm1 = MultiMap.new
573
655
 
@@ -580,9 +662,43 @@ class Test_Xqsr3_Containers_MultiMap < Test::Unit::TestCase
580
662
  mm2.push :abc, 4, 5
581
663
  mm2.push :def, 'a'
582
664
 
583
- mm1.merge! mm2
665
+ mm3 = mm1.strict_merge mm2
666
+
667
+ h = Hash.new
668
+
669
+ h.store :ghi, 'x'
670
+
671
+ mm4 = mm3.strict_merge h
584
672
 
585
- assert_equal [ :abc, 1, :abc, 2, :abc, 3, :abc, 4, :abc, 5, :def, 'a' ], mm1.flatten
673
+ assert_equal [ :abc, 4, :abc, 5, :def, 'a', :ghi, 'x' ], mm4.flatten
674
+ end
675
+
676
+ def test_strict_merge!
677
+
678
+ mm1 = MultiMap.new
679
+
680
+ mm1.push :abc, 1, 2, 3
681
+ #$stderr.puts "mm1(#{mm1.class})=#{mm1}"
682
+
683
+ assert_equal [ :abc, 1, :abc, 2, :abc, 3 ], mm1.flatten
684
+
685
+ mm2 = MultiMap.new
686
+
687
+ mm2.push :abc, 4, 5
688
+ mm2.push :def, 'a'
689
+ #$stderr.puts "mm2(#{mm2.class})=#{mm2}"
690
+
691
+ mm1.strict_merge! mm2
692
+ #$stderr.puts "mm1(#{mm1.class})=#{mm1}"
693
+
694
+ h = Hash.new
695
+
696
+ h.store :ghi, 'x'
697
+
698
+ mm1.strict_merge! h
699
+ #$stderr.puts "mm1(#{mm1.class})=#{mm1}"
700
+
701
+ assert_equal [ :abc, 4, :abc, 5, :def, 'a', :ghi, 'x' ], mm1.flatten
586
702
  end
587
703
 
588
704
  def test_push
@@ -698,6 +814,25 @@ class Test_Xqsr3_Containers_MultiMap < Test::Unit::TestCase
698
814
  assert_equal ({ abc: [ 1, 2, 3, 4, 5 ], def: [] }), mm.to_h
699
815
  end
700
816
 
817
+ def test_values_unflattened
818
+
819
+ mm = MultiMap.new
820
+
821
+ assert_equal [], mm.values_unflattened
822
+
823
+ mm.store :abc
824
+
825
+ assert_equal [ [] ], mm.values_unflattened
826
+
827
+ mm.store :abc, 1, 2, '3', nil, false
828
+
829
+ assert_equal [ [ 1, 2, '3', nil, false ] ], mm.values_unflattened
830
+
831
+ mm.store :def, true
832
+
833
+ assert_equal [ [ 1, 2, '3', nil, false ], [ true ] ], mm.values_unflattened
834
+ end
835
+
701
836
  def test_values
702
837
 
703
838
  mm = MultiMap.new
@@ -706,11 +841,38 @@ class Test_Xqsr3_Containers_MultiMap < Test::Unit::TestCase
706
841
 
707
842
  mm.store :abc
708
843
 
709
- assert_equal [ [] ], mm.values
844
+ assert_equal [], mm.values
710
845
 
711
846
  mm.store :abc, 1, 2, '3', nil, false
712
847
 
713
- assert_equal [ [ 1, 2, '3', nil, false ] ], mm.values
848
+ assert_equal [ 1, 2, '3', nil, false ], mm.values
849
+
850
+ mm.store :def, true
851
+
852
+ assert_equal [ 1, 2, '3', nil, false, true ], mm.values
853
+ end
854
+
855
+ def test_to_s
856
+
857
+ mm = MultiMap[]
858
+
859
+ assert_equal "{}", mm.to_s
860
+
861
+ mm.store :abc
862
+
863
+ assert_equal "{:abc=>[]}", mm.to_s
864
+
865
+ mm.store :abc, 1
866
+
867
+ assert_equal "{:abc=>[1]}", mm.to_s
868
+
869
+ mm.store :abc, 1, 23
870
+
871
+ assert_equal "{:abc=>[1, 23]}", mm.to_s
872
+
873
+ mm.store :def, *(0...10).to_a
874
+
875
+ assert_equal "{:abc=>[1, 23], :def=>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}", mm.to_s
714
876
  end
715
877
  end
716
878
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xqsr3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.3
4
+ version: 0.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Wilson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-12 00:00:00.000000000 Z
11
+ date: 2019-04-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  eXtensions by fine Quantum for Standard Ruby and 3rd-party libraries is a
@@ -157,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
157
  version: '0'
158
158
  requirements: []
159
159
  rubyforge_project:
160
- rubygems_version: 2.2.5
160
+ rubygems_version: 2.6.11
161
161
  signing_key:
162
162
  specification_version: 4
163
163
  summary: xqsr3