xqsr3 0.32.2 → 0.36.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.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/lib/xqsr3/all_extensions.rb +6 -0
  3. data/lib/xqsr3/array_utilities.rb +10 -0
  4. data/lib/xqsr3/array_utilities/join_with_or.rb +7 -14
  5. data/lib/xqsr3/command_line_utilities.rb +10 -0
  6. data/lib/xqsr3/command_line_utilities/map_option_string.rb +21 -8
  7. data/lib/xqsr3/containers.rb +11 -0
  8. data/lib/xqsr3/containers/frequency_map.rb +19 -2
  9. data/lib/xqsr3/containers/multi_map.rb +316 -27
  10. data/lib/xqsr3/conversion.rb +11 -0
  11. data/lib/xqsr3/conversion/bool_parser.rb +11 -14
  12. data/lib/xqsr3/conversion/integer_parser.rb +10 -16
  13. data/lib/xqsr3/diagnostics.rb +11 -0
  14. data/lib/xqsr3/diagnostics/exception_utilities.rb +2 -2
  15. data/lib/xqsr3/diagnostics/exceptions/with_cause.rb +15 -7
  16. data/lib/xqsr3/diagnostics/inspect_builder.rb +16 -16
  17. data/lib/xqsr3/doc_.rb +138 -9
  18. data/lib/xqsr3/extensions.rb +13 -0
  19. data/lib/xqsr3/extensions/array.rb +3 -0
  20. data/lib/xqsr3/extensions/array/join_with_or.rb +6 -0
  21. data/lib/xqsr3/extensions/enumerable/collect_with_index.rb +5 -4
  22. data/lib/xqsr3/extensions/enumerable/detect_map.rb +6 -7
  23. data/lib/xqsr3/extensions/hash.rb +5 -0
  24. data/lib/xqsr3/extensions/hash/has_match.rb +7 -0
  25. data/lib/xqsr3/extensions/hash/match.rb +7 -0
  26. data/lib/xqsr3/extensions/hash/slice.rb +22 -0
  27. data/lib/xqsr3/extensions/io/writelines.rb +38 -6
  28. data/lib/xqsr3/extensions/kernel/integer.rb +6 -13
  29. data/lib/xqsr3/extensions/string/to_bool.rb +4 -0
  30. data/lib/xqsr3/extensions/test/unit/assert_eql.rb +1 -0
  31. data/lib/xqsr3/extensions/test/unit/assert_false.rb +1 -0
  32. data/lib/xqsr3/extensions/test/unit/assert_not.rb +1 -0
  33. data/lib/xqsr3/extensions/test/unit/assert_not_eql.rb +1 -0
  34. data/lib/xqsr3/extensions/test/unit/assert_raise_with_message.rb +25 -4
  35. data/lib/xqsr3/extensions/test/unit/assert_subclass_of.rb +1 -0
  36. data/lib/xqsr3/extensions/test/unit/assert_superclass_of.rb +1 -0
  37. data/lib/xqsr3/extensions/test/unit/assert_true.rb +1 -0
  38. data/lib/xqsr3/extensions/test/unit/assert_type_has_instance_methods.rb +3 -12
  39. data/lib/xqsr3/hash_utilities.rb +11 -0
  40. data/lib/xqsr3/hash_utilities/deep_transform.rb +2 -2
  41. data/lib/xqsr3/hash_utilities/key_matching.rb +6 -4
  42. data/lib/xqsr3/internal_/test_unit_version_.rb +30 -4
  43. data/lib/xqsr3/io/writelines.rb +55 -19
  44. data/lib/xqsr3/quality.rb +8 -1
  45. data/lib/xqsr3/quality/parameter_checking.rb +52 -78
  46. data/lib/xqsr3/string_utilities.rb +16 -0
  47. data/lib/xqsr3/string_utilities/ends_with.rb +16 -7
  48. data/lib/xqsr3/string_utilities/nil_if_empty.rb +8 -4
  49. data/lib/xqsr3/string_utilities/nil_if_whitespace.rb +9 -4
  50. data/lib/xqsr3/string_utilities/quote_if.rb +12 -14
  51. data/lib/xqsr3/string_utilities/starts_with.rb +23 -5
  52. data/lib/xqsr3/string_utilities/to_symbol.rb +24 -5
  53. data/lib/xqsr3/string_utilities/truncate.rb +20 -4
  54. data/lib/xqsr3/version.rb +3 -2
  55. data/test/unit/containers/tc_multi_map.rb +174 -16
  56. data/test/unit/extensions/hash/tc_hash.rb +6 -0
  57. data/test/unit/extensions/hash/tc_slice.rb +31 -0
  58. data/test/unit/extensions/io/tc_writelines.rb +36 -0
  59. metadata +16 -3
@@ -0,0 +1,13 @@
1
+
2
+ %w{
3
+
4
+ array
5
+ enumerable
6
+ hash
7
+ io
8
+ }.each do |name|
9
+
10
+ require File.join(File.dirname(__FILE__), 'extensions', name)
11
+ end
12
+
13
+
@@ -0,0 +1,3 @@
1
+
2
+ require 'xqsr3/extensions/array/join_with_or'
3
+
@@ -3,6 +3,12 @@ require 'xqsr3/array_utilities/join_with_or'
3
3
 
4
4
  class Array
5
5
 
6
+ # Extended method implemented by JoinWithOr
7
+ #
8
+ # === Signature
9
+ #
10
+ # * *Parameters:*
11
+ # - +options+ (Hash) See Xqsr3::ArrayUtilities
6
12
  def join_with_or **options
7
13
 
8
14
  return ::Xqsr3::ArrayUtilities::JoinWithOr.join_with_or self, **options
@@ -5,13 +5,13 @@
5
5
  # Purpose: Adds a collect_with_index() method to the Enumerable module
6
6
  #
7
7
  # Created: 24th October 2010
8
- # Updated: 4th April 2016
8
+ # Updated: 12th April 2019
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
12
12
  # Author: Matthew Wilson
13
13
  #
14
- # Copyright (c) 2010-2016, Matthew Wilson and Synesis Software
14
+ # Copyright (c) 2010-2019, Matthew Wilson and Synesis Software
15
15
  # All rights reserved.
16
16
  #
17
17
  # Redistribution and use in source and binary forms, with or without
@@ -52,8 +52,9 @@
52
52
 
53
53
  module Enumerable
54
54
 
55
- ## Two-parameter #collect, where the second parameter is a #base-based
56
- # index, which increments by 1 for each enumerated element.
55
+ # Two-parameter variant of +Enumerable+#+collect+, where the second
56
+ # parameter is a +base+-based index, which increments by 1 for each
57
+ # enumerated element.
57
58
  def collect_with_index(base = 0)
58
59
 
59
60
  a = []
@@ -5,13 +5,13 @@
5
5
  # Purpose: ::Enumerable#detect_map extension
6
6
  #
7
7
  # Created: 3rd December 2017
8
- # Updated: 9th December 2017
8
+ # Updated: 12th April 2019
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
12
12
  # Author: Matthew Wilson
13
13
  #
14
- # Copyright (c) 2017, Matthew Wilson and Synesis Software
14
+ # Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
15
15
  # All rights reserved.
16
16
  #
17
17
  # Redistribution and use in source and binary forms, with or without
@@ -49,15 +49,15 @@
49
49
 
50
50
  module Enumerable
51
51
 
52
- # The +Enumerable#detect+ method provides a way to detect the presence
52
+ # The +Enumerable+#+detect+ method provides a way to detect the presence
53
53
  # of a particular value in a collection. The only constraint is that you
54
54
  # get back the object unchanged.
55
55
  #
56
- # The +Enumerable#map+ method provides a way to transform the contents of
56
+ # The +Enumerable+#+map+ method provides a way to transform the contents of
57
57
  # a collection. The only constraint is that you get back another
58
58
  # collection.
59
59
  #
60
- # This extension method, +Enumerable#detect_map+ combines the features
60
+ # This extension method, +Enumerable+#+detect_map+ combines the features
61
61
  # of both, in that it detects the presence of a particular value in a
62
62
  # collection and transform the detected value.
63
63
  #
@@ -65,7 +65,7 @@ module Enumerable
65
65
  #
66
66
  # { :ab => 'cd', :ef => 'gh' }.detect_map { |k, v| v.upcase if k == :ef } # => 'GH'
67
67
  #
68
- # @note The block is required (for technical reasons), and must have
68
+ # *Note:* The block is required (for technical reasons), and must have
69
69
  # arity 1 for sequences or 2 for associations
70
70
  def detect_map &block
71
71
 
@@ -89,7 +89,6 @@ module Enumerable
89
89
 
90
90
  nil
91
91
  end
92
-
93
92
  end # module Enumerable
94
93
 
95
94
  # ############################## end of file ############################# #
@@ -3,3 +3,8 @@ require 'xqsr3/extensions/hash/deep_transform'
3
3
  require 'xqsr3/extensions/hash/has_match'
4
4
  require 'xqsr3/extensions/hash/match'
5
5
 
6
+ unless (RUBY_VERSION.split('.').map { |v| v.to_i } <=> [ 2, 5, 0 ]) > 0
7
+
8
+ require 'xqsr3/extensions/hash/slice'
9
+ end
10
+
@@ -3,6 +3,13 @@ require 'xqsr3/hash_utilities/key_matching'
3
3
 
4
4
  class Hash
5
5
 
6
+ # Extended method implemented by Xqsr3::HashUtilities::KeyMatching
7
+ #
8
+ # === Signature
9
+ #
10
+ # * *Parameters:*
11
+ # - +re+ (Regexp) The regular expression
12
+ # - +options+ (Hash) See Xqsr3::HashUtilities::KeyMatching
6
13
  def has_match? re, **options
7
14
 
8
15
  return ::Xqsr3::HashUtilities::KeyMatching.has_match? self, re, **options
@@ -3,6 +3,13 @@ require 'xqsr3/hash_utilities/key_matching'
3
3
 
4
4
  class Hash
5
5
 
6
+ # Extended method implemented by Xqsr3::HashUtilities::KeyMatching
7
+ #
8
+ # === Signature
9
+ #
10
+ # * *Parameters:*
11
+ # - +re+ (Regexp) The regular expression
12
+ # - +options+ (Hash) See Xqsr3::HashUtilities::KeyMatching
6
13
  def match re, **options
7
14
 
8
15
  return ::Xqsr3::HashUtilities::KeyMatching.match self, re, **options
@@ -0,0 +1,22 @@
1
+
2
+ unless Hash.instance_methods.include? :slice
3
+
4
+ class Hash
5
+
6
+ def slice(*args)
7
+
8
+ r = {}
9
+
10
+ args.each do |arg|
11
+
12
+ if self.has_key? arg
13
+
14
+ r[arg] = self[arg]
15
+ end
16
+ end
17
+
18
+ r
19
+ end
20
+ end
21
+ end
22
+
@@ -5,13 +5,13 @@
5
5
  # Purpose: Adds a writelines() method to the IO class
6
6
  #
7
7
  # Created: 13th April 2007
8
- # Updated: 10th June 2016
8
+ # Updated: 31st October 2019
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
12
12
  # Author: Matthew Wilson
13
13
  #
14
- # Copyright (c) 2007-2016, Matthew Wilson and Synesis Software
14
+ # Copyright (c) 2007-2019, Matthew Wilson and Synesis Software
15
15
  # All rights reserved.
16
16
  #
17
17
  # Redistribution and use in source and binary forms, with or without
@@ -54,13 +54,45 @@ require 'xqsr3/io/writelines'
54
54
 
55
55
  class IO
56
56
 
57
- # Extends +IO+ class with the ::Xqsr3::IO::write_lines
58
- # method
59
- def self.writelines(path, contents, lineSep = nil, columnSep = nil)
57
+ # Extends +IO+ class with the +::Xqsr3::IO::write_lines+ method
58
+ #
59
+ #
60
+ #def self.writelines(path, contents, lineSep = nil, columnSep = nil)
61
+ def self.writelines(path, contents, *args)
60
62
 
61
- ::Xqsr3::IO.writelines path, contents, line_separator: lineSep, column_separator: columnSep, eol_lookahead_limit: 20
63
+ options = {}
64
+
65
+ case args.size
66
+ when 0
67
+
68
+ ;
69
+ when 1
70
+
71
+ arg3 = args[0]
72
+
73
+ if arg3.respond_to?(:to_hash)
74
+
75
+ options.merge! arg3.to_hash
76
+ else
77
+
78
+ options[:line_separator] = arg3
79
+ end
80
+ when 2
81
+
82
+ arg3 = args[0]
83
+ arg4 = args[1]
84
+
85
+ options[:line_separator] = arg2
86
+ options[:column_separator] = arg2
87
+ else
88
+
89
+ raise ArgumentError, "wrong number of arguments (given #{2 + args.size}, expected 2..4)"
90
+ end
91
+
92
+ ::Xqsr3::IO.writelines path, contents, **options
62
93
  end
63
94
  end # class IO
64
95
 
65
96
  # ############################## end of file ############################# #
66
97
 
98
+
@@ -61,21 +61,14 @@ module Kernel
61
61
  # === Signature
62
62
  #
63
63
  # * *Parameters:*
64
- # - +arg+:: The argument to be converted (to +Fixnum+ or +Bignum+)
65
- # - +base+:: A value of 0, or between 2 and 36. Defaults to 0
66
- # - +options+:: An options hash, containing any of the following
67
- # options
68
- # - +block+:: An optional caller-supplied block that will be invoked
69
- # with the +ArgumentError+ exception, allowing the caller to take
70
- # additional action. If the block returns then its return value will
71
- # be returned to the caller
64
+ # - +arg+ The argument to be converted (to +Fixnum+ or +Bignum+)
65
+ # - +base+ A value of 0, or between 2 and 36. Defaults to 0
66
+ # - +options+ An options hash, containing any of the following options
67
+ # - +block+ An optional caller-supplied block that will be invoked with the +ArgumentError+ exception, allowing the caller to take additional action. If the block returns then its return value will be returned to the caller
72
68
  #
73
69
  # * *Options:*
74
- # - +:default+:: A default value to be used when +arg+ is +nil+ or
75
- # cannot be converted by (the original) +Kernel#Integer+
76
- # - +:nil+:: Returns +nil+ if +arg+ is +nil+ or cannot be
77
- # converted by (the original) +Kernel#Integer+. Ignored if
78
- # +:default+ is specified
70
+ # - +:default+ A default value to be used when +arg+ is +nil+ or cannot be converted by (the original) +Kernel#Integer+
71
+ # - +:nil+ Returns +nil+ if +arg+ is +nil+ or cannot be converted by (the original) +Kernel#Integer+. Ignored if +:default+ is specified
79
72
  def Integer(arg, base = 0, **options, &block)
80
73
 
81
74
  ::Xqsr3::Conversion::IntegerParser.to_integer arg, base = 0, **options, &block
@@ -3,6 +3,10 @@ require 'xqsr3/conversion/bool_parser'
3
3
 
4
4
  class String
5
5
 
6
+ # Attempts to convert instance to a Boolean value, based on the given
7
+ # +options+
8
+ #
9
+ # See Xqsr3::Conversion::BoolParser
6
10
  def to_bool **options
7
11
 
8
12
  return ::Xqsr3::Conversion::BoolParser.to_bool self, **options
@@ -6,6 +6,7 @@ module Assertions
6
6
 
7
7
  unless respond_to? :assert_eql
8
8
 
9
+ # Assert that +expected+ and +actual+ have the same hash key
9
10
  def assert_eql(expected, actual, failure_message = '')
10
11
 
11
12
  assert expected.eql?(actual), failure_message
@@ -6,6 +6,7 @@ module Assertions
6
6
 
7
7
  unless respond_to? :assert_false
8
8
 
9
+ # Assert that +expression+ is +false+
9
10
  def assert_false(expression, failure_message = '')
10
11
 
11
12
  assert ::FalseClass === (expression), failure_message
@@ -6,6 +6,7 @@ module Assertions
6
6
 
7
7
  unless respond_to? :assert_not
8
8
 
9
+ # Assert that +expression+ is _falsey_
9
10
  def assert_not(expression, failure_message = '')
10
11
 
11
12
  assert !(expression), failure_message
@@ -6,6 +6,7 @@ module Assertions
6
6
 
7
7
  unless respond_to? :assert_not_eql
8
8
 
9
+ # Assert that +expected+ and +actual+ have different hash keys
9
10
  def assert_not_eql(expected, actual, failure_message = '')
10
11
 
11
12
  assert !(expected.eql?(actual)), failure_message
@@ -1,22 +1,28 @@
1
1
 
2
2
  require 'xqsr3/internal_/test_unit_version_'
3
3
 
4
+ # :stopdoc:
5
+
4
6
  module Xqsr3
5
- module Internal_ # :nodoc:
6
- module X_assert_raise_with_message_ # :nodoc:
7
+ # @!visibility private
8
+ module Internal_ # :nodoc: all
9
+ # @!visibility private
10
+ module X_assert_raise_with_message_ # :nodoc: all
7
11
 
8
12
  if TestUnitVersion_.is_at_least? [ 3, 0, 8 ]
9
13
 
10
- AssertionFailedError_ = Test::Unit::AssertionFailedError
14
+ AssertionFailedError_ = Test::Unit::AssertionFailedError # :nodoc:
11
15
  else
12
16
 
13
- class AssertionFailedError_ < ArgumentError; end
17
+ class AssertionFailedError_ < ArgumentError; end # :nodoc:
14
18
  end
15
19
 
16
20
  end # module X_assert_raise_with_message_
17
21
  end # module Internal_
18
22
  end # module Xqsr3
19
23
 
24
+ # :startdoc:
25
+
20
26
  module Test
21
27
  module Unit
22
28
 
@@ -24,6 +30,19 @@ module Assertions
24
30
 
25
31
  undef :assert_raise_with_message if respond_to? :assert_raise_with_message
26
32
 
33
+ # Asserts that the attached block raises an exception of one of the
34
+ # exceptions defined by +type_spec+ and/or has a message matching
35
+ # +message_spec+
36
+ #
37
+ # === Signature
38
+ #
39
+ # * *Parameters:*
40
+ # - +type_spec+ (String, Regexp, [String], [Regexp], nil) Specification of type expectation(s)
41
+ # - +message_spec+ (String, Regexp, [String], [Regexp], nil) Specification of message expectation(s)
42
+ # - +failure_message+ (String, nil) Optional message to be used if the matching fails
43
+ #
44
+ # * *Block*
45
+ # A required block containing code that is expected to raise an exception
27
46
  def assert_raise_with_message(type_spec, message_spec, failure_message = nil, &block)
28
47
 
29
48
  unless block_given?
@@ -94,4 +113,6 @@ end # class Assertions
94
113
  end # module Unit
95
114
  end # module Test
96
115
 
116
+ # ############################## end of file ############################# #
117
+
97
118
 
@@ -6,6 +6,7 @@ module Assertions
6
6
 
7
7
  unless respond_to? :assert_subclass_of
8
8
 
9
+ # Assert that +tested_class+ is a sub-class of +parent_class+
9
10
  def assert_subclass_of(parent_class, tested_class, failure_message = nil)
10
11
 
11
12
  failure_message ||= "#{tested_class} is not a subclass of #{parent_class}"
@@ -6,6 +6,7 @@ module Assertions
6
6
 
7
7
  unless respond_to? :assert_superclass_of
8
8
 
9
+ # Assert that +tested_class+ is a super-class of +child_class+
9
10
  def assert_superclass_of(child_class, tested_class, failure_message = nil)
10
11
 
11
12
  failure_message ||= "#{tested_class} is not a superclass of #{child_class}"
@@ -6,6 +6,7 @@ module Assertions
6
6
 
7
7
  unless respond_to? :assert_true
8
8
 
9
+ # Assert that +expression+ is +true+
9
10
  def assert_true(expression, failure_message = '')
10
11
 
11
12
  assert ::TrueClass === (expression), failure_message
@@ -12,18 +12,9 @@ module Assertions
12
12
  # === Signature
13
13
  #
14
14
  # * *Parameters:*
15
- # - +type+:: [::Class] The type
16
- # - +message_spec+:: [::Symbol, ::Array, ::Hash] A specification
17
- # of message(s) received by the instances of +type+. If a
18
- # ::Symbol, then instances must respond to this single message.
19
- # If an ::Array (all elements of which must be ::Symbol), then
20
- # instances must respond to _all_ messages. If a ::Hash, then
21
- # instances must respond to _all_ messages represented by the
22
- # keys; the values are available for specifying a custom failure
23
- # message (or value is +nil+ for stock message)
24
- # - +failure_message+:: [::String] If specified, is used when
25
- # instances of +type+ do not respond to a message and no custom
26
- # failure message is provided for it
15
+ # - +type+ (::Class) The type
16
+ # - +message_spec+ (::Symbol, ::Array, ::Hash) A specification of message(s) received by the instances of +type+. If a ::Symbol, then instances must respond to this single message. If an ::Array (all elements of which must be ::Symbol), then instances must respond to _all_ messages. If a ::Hash, then instances must respond to _all_ messages represented by the keys; the values are available for specifying a custom failure message (or value is +nil+ for stock message)
17
+ # - +failure_message+ (::String) If specified, is used when instances of +type+ do not respond to a message and no custom failure message is provided for it
27
18
  def assert_type_has_instance_methods(type, message_spec, failure_message = nil)
28
19
 
29
20
  warn "type parameter - '#{type} (#{type.class})' - should be a Class" unless type.is_a?(::Class)
@@ -0,0 +1,11 @@
1
+
2
+ %w{
3
+
4
+ deep_transform
5
+ key_matching
6
+ }.each do |name|
7
+
8
+ require File.join(File.dirname(__FILE__), 'hash_utilities', name)
9
+ end
10
+
11
+
@@ -59,7 +59,7 @@ module HashUtilities
59
59
  module DeepTransform
60
60
 
61
61
  private
62
- def self.do_deep_transform_on_hashlike_ h, &block
62
+ def self.do_deep_transform_on_hashlike_ h, &block # :nodoc:
63
63
 
64
64
  ::Xqsr3::Quality::ParameterChecking.check_parameter h, 'h', responds_to: [ :map ]
65
65
 
@@ -92,7 +92,7 @@ module DeepTransform
92
92
  h
93
93
  end
94
94
 
95
- def do_deep_transform_on_self_ &block
95
+ def do_deep_transform_on_self_ &block # :nodoc:
96
96
 
97
97
  ::Xqsr3::Quality::ParameterChecking.check_parameter h, 'h', responds_to: [ :[]=, :delete, :keys ]
98
98