xqsr3 0.32.2 → 0.36.0

Sign up to get free protection for your applications and to get access to all the features.
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