xqsr3 0.32.3 → 0.37.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/xqsr3/all_extensions.rb +6 -0
  3. data/lib/xqsr3/array_utilities.rb +10 -0
  4. data/lib/xqsr3/command_line_utilities.rb +10 -0
  5. data/lib/xqsr3/command_line_utilities/map_option_string.rb +3 -2
  6. data/lib/xqsr3/containers.rb +11 -0
  7. data/lib/xqsr3/containers/frequency_map.rb +18 -1
  8. data/lib/xqsr3/containers/multi_map.rb +290 -29
  9. data/lib/xqsr3/conversion.rb +11 -0
  10. data/lib/xqsr3/conversion/integer_parser.rb +3 -2
  11. data/lib/xqsr3/diagnostics.rb +11 -0
  12. data/lib/xqsr3/diagnostics/inspect_builder.rb +5 -1
  13. data/lib/xqsr3/extensions.rb +13 -0
  14. data/lib/xqsr3/extensions/array.rb +3 -0
  15. data/lib/xqsr3/extensions/hash.rb +6 -0
  16. data/lib/xqsr3/extensions/hash/except.rb +26 -0
  17. data/lib/xqsr3/extensions/hash/slice.rb +22 -0
  18. data/lib/xqsr3/extensions/io/writelines.rb +38 -6
  19. data/lib/xqsr3/extensions/test/unit/assert_raise_with_message.rb +22 -2
  20. data/lib/xqsr3/hash_utilities.rb +11 -0
  21. data/lib/xqsr3/hash_utilities/key_matching.rb +6 -4
  22. data/lib/xqsr3/internal_/test_unit_version_.rb +26 -0
  23. data/lib/xqsr3/io/writelines.rb +49 -13
  24. data/lib/xqsr3/quality.rb +8 -1
  25. data/lib/xqsr3/quality/parameter_checking.rb +3 -2
  26. data/lib/xqsr3/string_utilities.rb +16 -0
  27. data/lib/xqsr3/string_utilities/ends_with.rb +3 -2
  28. data/lib/xqsr3/string_utilities/nil_if_empty.rb +3 -2
  29. data/lib/xqsr3/string_utilities/nil_if_whitespace.rb +3 -2
  30. data/lib/xqsr3/string_utilities/quote_if.rb +7 -2
  31. data/lib/xqsr3/string_utilities/starts_with.rb +3 -2
  32. data/lib/xqsr3/string_utilities/to_symbol.rb +3 -2
  33. data/lib/xqsr3/string_utilities/truncate.rb +3 -2
  34. data/lib/xqsr3/version.rb +3 -2
  35. data/test/unit/containers/tc_multi_map.rb +174 -16
  36. data/test/unit/diagnostics/tc_exception_utilities.rb +7 -3
  37. data/test/unit/extensions/hash/tc_deep_transform.rb +0 -1
  38. data/test/unit/extensions/hash/tc_except.rb +67 -0
  39. data/test/unit/extensions/hash/tc_hash.rb +6 -0
  40. data/test/unit/extensions/hash/tc_slice.rb +31 -0
  41. data/test/unit/extensions/io/tc_writelines.rb +36 -0
  42. data/test/unit/extensions/kernel/tc_raise_with_options.rb +6 -3
  43. data/test/unit/tc_version.rb +1 -1
  44. metadata +22 -7
@@ -0,0 +1,11 @@
1
+
2
+ %w{
3
+
4
+ bool_parser
5
+ integer_parser
6
+ }.each do |name|
7
+
8
+ require File.join(File.dirname(__FILE__), 'conversion', name)
9
+ end
10
+
11
+
@@ -6,7 +6,7 @@
6
6
  # module
7
7
  #
8
8
  # Created: 21st November 2017
9
- # Updated: 12th April 2019
9
+ # Updated: 15th April 2019
10
10
  #
11
11
  # Home: http://github.com/synesissoftware/xqsr3
12
12
  #
@@ -58,7 +58,8 @@ module Conversion
58
58
  module IntegerParser
59
59
 
60
60
  private
61
- module IntegerParser_Helper_ # :nodoc:
61
+ # @!visibility private
62
+ module IntegerParser_Helper_ # :nodoc: all
62
63
 
63
64
  if Kernel.respond_to?(:xqsr3_Integer_original_method)
64
65
 
@@ -0,0 +1,11 @@
1
+
2
+ %w{
3
+
4
+ exception_utilities
5
+ inspect_builder
6
+ }.each do |name|
7
+
8
+ require File.join(File.dirname(__FILE__), 'diagnostics', name)
9
+ end
10
+
11
+
@@ -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
@@ -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
+
@@ -1,5 +1,11 @@
1
1
 
2
2
  require 'xqsr3/extensions/hash/deep_transform'
3
+ require 'xqsr3/extensions/hash/except'
3
4
  require 'xqsr3/extensions/hash/has_match'
4
5
  require 'xqsr3/extensions/hash/match'
5
6
 
7
+ unless (RUBY_VERSION.split('.').map { |v| v.to_i } <=> [ 2, 5, 0 ]) > 0
8
+
9
+ require 'xqsr3/extensions/hash/slice'
10
+ end
11
+
@@ -0,0 +1,26 @@
1
+
2
+ unless Hash.instance_methods.include? :except
3
+
4
+ class Hash
5
+
6
+ # Removes from the instance any key-value pairs matching the
7
+ # keys specified in +keys_to_delete+
8
+ def except!(*keys_to_delete)
9
+
10
+ keys_to_delete.each do |key|
11
+
12
+ self.delete key
13
+ end
14
+
15
+ self
16
+ end
17
+
18
+ # Obtains a copy of the instance wherein any key-value pairs
19
+ # matching the keys specified in +keys_to_delete+ are removed
20
+ def except(*keys_to_delete)
21
+
22
+ self.dup.except!(*keys_to_delete)
23
+ end
24
+ end
25
+ end
26
+
@@ -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
+
@@ -1,15 +1,21 @@
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
 
14
+ # @!visibility private
10
15
  AssertionFailedError_ = Test::Unit::AssertionFailedError # :nodoc:
11
16
  else
12
17
 
18
+ # @!visibility private
13
19
  class AssertionFailedError_ < ArgumentError; end # :nodoc:
14
20
  end
15
21
 
@@ -17,6 +23,8 @@ end # module X_assert_raise_with_message_
17
23
  end # module Internal_
18
24
  end # module Xqsr3
19
25
 
26
+ # :startdoc:
27
+
20
28
  module Test
21
29
  module Unit
22
30
 
@@ -27,6 +35,16 @@ module Assertions
27
35
  # Asserts that the attached block raises an exception of one of the
28
36
  # exceptions defined by +type_spec+ and/or has a message matching
29
37
  # +message_spec+
38
+ #
39
+ # === Signature
40
+ #
41
+ # * *Parameters:*
42
+ # - +type_spec+ (String, Regexp, [String], [Regexp], nil) Specification of type expectation(s)
43
+ # - +message_spec+ (String, Regexp, [String], [Regexp], nil) Specification of message expectation(s)
44
+ # - +failure_message+ (String, nil) Optional message to be used if the matching fails
45
+ #
46
+ # * *Block*
47
+ # A required block containing code that is expected to raise an exception
30
48
  def assert_raise_with_message(type_spec, message_spec, failure_message = nil, &block)
31
49
 
32
50
  unless block_given?
@@ -97,4 +115,6 @@ end # class Assertions
97
115
  end # module Unit
98
116
  end # module Test
99
117
 
118
+ # ############################## end of file ############################# #
119
+
100
120
 
@@ -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
+
@@ -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,47 @@
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
+ # :stopdoc:
29
+ # @!visibility private
20
30
  module Xqsr3
31
+ # @!visibility private
21
32
  module Internal_ # :nodoc:
33
+ # @!visibility private
22
34
  module TestUnitVersion_ # :nodoc:
23
35
 
36
+ # @!visibility private
24
37
  TEST_UNIT_VERSION_ = :not_found # :nodoc:
25
38
  end # module TestUnitVersion_
26
39
  end # module Internal_
27
40
  end # module Xqsr3
41
+
42
+ # :startdoc:
28
43
  end
29
44
 
45
+ # :stopdoc:
46
+
30
47
  module Xqsr3
31
48
  module Internal_ # :nodoc:
32
49
  module TestUnitVersion_ # :nodoc:
@@ -47,6 +64,7 @@ module TestUnitVersion_ # :nodoc:
47
64
  TEST_UNIT_VERSION_PATCH_ = TEST_UNIT_VERSION_PARTS_[2] # :nodoc:
48
65
  end
49
66
 
67
+ # @!visibility private
50
68
  def self.less_ a1, a2 # :nodoc:
51
69
 
52
70
  n_common = a1.size < a2.size ? a1.size : a2.size
@@ -79,6 +97,7 @@ module TestUnitVersion_ # :nodoc:
79
97
  end
80
98
  end
81
99
 
100
+ # @!visibility private
82
101
  def self.is_major_at_least? j # :nodoc:
83
102
 
84
103
  return unless TEST_UNIT_VERSION_MAJOR_
@@ -86,6 +105,7 @@ module TestUnitVersion_ # :nodoc:
86
105
  return j >= TEST_UNIT_VERSION_MAJOR_
87
106
  end
88
107
 
108
+ # @!visibility private
89
109
  def self.is_minor_at_least? n # :nodoc:
90
110
 
91
111
  return unless TEST_UNIT_VERSION_MINOR_
@@ -93,6 +113,7 @@ module TestUnitVersion_ # :nodoc:
93
113
  return n >= TEST_UNIT_VERSION_MINOR_
94
114
  end
95
115
 
116
+ # @!visibility private
96
117
  def self.is_at_least? v # :nodoc:
97
118
 
98
119
  v = v.split(/\./).collect { |n| n.to_i } if String === v
@@ -100,6 +121,7 @@ module TestUnitVersion_ # :nodoc:
100
121
  return !less_(TEST_UNIT_VERSION_PARTS_, v)
101
122
  end
102
123
 
124
+ # @!visibility private
103
125
  def self.is_less? v # :nodoc:
104
126
 
105
127
  v = v.split(/\./).collect { |n| n.to_i } if String === v
@@ -111,4 +133,8 @@ end # module TestUnitVersion_
111
133
  end # module Internal_
112
134
  end # module Xqsr3
113
135
 
136
+ # :startdoc:
137
+
138
+ # ############################## end of file ############################# #
139
+
114
140
 
@@ -5,7 +5,7 @@
5
5
  # Purpose: Adds a writelines() method to the IO module
6
6
  #
7
7
  # Created: 13th April 2007
8
- # Updated: 12th April 2019
8
+ # Updated: 31st October 2019
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
@@ -56,27 +56,58 @@ module Xqsr3
56
56
  module IO
57
57
 
58
58
  private
59
- module WriteLine_Constants_ #:nodoc:
59
+ # @!visibility private
60
+ module WriteLine_Constants_ #:nodoc: all
60
61
 
61
62
  NUMBER_OF_LINES_TO_EXAMINE = 20
62
-
63
63
  end # module WriteLine_Constants_
64
64
 
65
65
  private
66
66
 
67
- def self.write_to_target_ target, contents, line_separator, column_separator
68
- $stderr.puts "#{self.class}.write_to_target_(target(#{target.class})='#{target}', contents(#{contents.class})='#{contents}', line_separator(#{line_separator.class})='#{line_separator}', column_separator=(#{column_separator.class})='#{column_separator}')" if $DEBUG
69
- if contents.instance_of? ::Hash
67
+ # @!visibility private
68
+ def self.write_to_target_ target, contents, line_separator, column_separator, no_last_eol # :nodoc:
69
+
70
+ $stderr.puts "#{self.class}.write_to_target_(target(#{target.class})='#{target}', contents(#{contents.class})='#{contents}', line_separator(#{line_separator.class})='#{line_separator}', column_separator(#{column_separator.class})='#{column_separator}', no_last_eol(#{no_last_eol.class})=#{no_last_eol})" if $DEBUG
71
+
72
+ if no_last_eol
73
+
74
+ first = true
75
+
76
+ if contents.instance_of? ::Hash
77
+
78
+ contents.each do |k, v|
79
+
80
+ target << line_separator unless first
81
+
82
+ target << "#{k}#{column_separator}#{v}"
83
+
84
+ first = false
85
+ end
86
+ else
70
87
 
71
- contents.each do |k, v|
88
+ contents.each do |element|
72
89
 
73
- target << "#{k}#{column_separator}#{v}#{line_separator}"
90
+ target << line_separator unless first
91
+
92
+ target << "#{element}"
93
+
94
+ first = false
95
+ end
74
96
  end
75
97
  else
76
98
 
77
- contents.each do |element|
99
+ if contents.instance_of? ::Hash
78
100
 
79
- target << "#{element}#{line_separator}"
101
+ contents.each do |k, v|
102
+
103
+ target << "#{k}#{column_separator}#{v}#{line_separator}"
104
+ end
105
+ else
106
+
107
+ contents.each do |element|
108
+
109
+ target << "#{element}#{line_separator}"
110
+ end
80
111
  end
81
112
  end
82
113
 
@@ -87,7 +118,9 @@ $stderr.puts "#{self.class}.write_to_target_(target(#{target.class})='#{target}'
87
118
  # embedded eol, in which case the empty string is returned to force no
88
119
  # (additional) separator will be used. Otherwise, it returns "\n" to
89
120
  # ensure that that is used.
90
- def self.deduce_line_separator_ contents, eol_lookahead_limit
121
+ #
122
+ # @!visibility private
123
+ def self.deduce_line_separator_ contents, eol_lookahead_limit # :nodoc:
91
124
 
92
125
  if contents.instance_of? ::Hash
93
126
 
@@ -134,6 +167,7 @@ $stderr.puts "#{self.class}.write_to_target_(target(#{target.class})='#{target}'
134
167
  # - +:column_separator+ {optional} The column separator, to be applied between each field in the case where +contents+ is a +Hash+.
135
168
  # - +:eol_lookahead_limit+ {optional} The number of content elements (line/pair) to inspect to determine whether element has a terminating end-of-line sequence. Defaults to 20. If 0, and +:line_separator+ is not specified, then will default to <tt>"\n"</tt>. If +nil+, then every line will be inspected.
136
169
  # - +:line_separator+ {optional} The line separator, to be applied to the end of line created from each entry. When not specified, it will be deduced by inspecting +contents+ (according to +eol_lookahead_limit+).
170
+ # - +:no_last_eol+ {optional} If present and _truey_, causes suppression of the addition of the +:line_separator+ on the last line.
137
171
  #
138
172
  # === Return
139
173
  #
@@ -165,6 +199,7 @@ $stderr.puts "#{self.class}.write_to_target_(target(#{target.class})='#{target}'
165
199
  options ||= {}
166
200
  eol_lookahead_limit = options[:eol_lookahead_limit] || WriteLine_Constants_::NUMBER_OF_LINES_TO_EXAMINE
167
201
  column_separator = options[:column_separator] || ''
202
+ no_last_eol = options[:no_last_eol] || false
168
203
  line_separator = nil
169
204
  line_separator ||= options[:line_separator]
170
205
  line_separator ||= self.deduce_line_separator_(contents, eol_lookahead_limit) unless !eol_lookahead_limit.kind_of?(::Integer) || 0 == eol_lookahead_limit
@@ -181,11 +216,11 @@ $stderr.puts "#{self.class}.write_to_target_(target(#{target.class})='#{target}'
181
216
 
182
217
  File.open(target, "w") do |io|
183
218
 
184
- self.write_to_target_ io, contents, line_separator, column_separator
219
+ self.write_to_target_ io, contents, line_separator, column_separator, no_last_eol
185
220
  end
186
221
  else
187
222
 
188
- self.write_to_target_ target, contents, line_separator, column_separator
223
+ self.write_to_target_ target, contents, line_separator, column_separator, no_last_eol
189
224
  end
190
225
  end # writelines
191
226
  end # module IO
@@ -193,3 +228,4 @@ end # module Xqsr3
193
228
 
194
229
  # ############################## end of file ############################# #
195
230
 
231
+