xqsr3 0.32.3 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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