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.
- checksums.yaml +4 -4
- data/lib/xqsr3/all_extensions.rb +6 -0
- data/lib/xqsr3/array_utilities.rb +10 -0
- data/lib/xqsr3/command_line_utilities.rb +10 -0
- data/lib/xqsr3/command_line_utilities/map_option_string.rb +3 -2
- data/lib/xqsr3/containers.rb +11 -0
- data/lib/xqsr3/containers/frequency_map.rb +18 -1
- data/lib/xqsr3/containers/multi_map.rb +290 -29
- data/lib/xqsr3/conversion.rb +11 -0
- data/lib/xqsr3/conversion/integer_parser.rb +3 -2
- data/lib/xqsr3/diagnostics.rb +11 -0
- data/lib/xqsr3/diagnostics/inspect_builder.rb +5 -1
- data/lib/xqsr3/extensions.rb +13 -0
- data/lib/xqsr3/extensions/array.rb +3 -0
- data/lib/xqsr3/extensions/hash.rb +6 -0
- data/lib/xqsr3/extensions/hash/except.rb +26 -0
- data/lib/xqsr3/extensions/hash/slice.rb +22 -0
- data/lib/xqsr3/extensions/io/writelines.rb +38 -6
- data/lib/xqsr3/extensions/test/unit/assert_raise_with_message.rb +22 -2
- data/lib/xqsr3/hash_utilities.rb +11 -0
- data/lib/xqsr3/hash_utilities/key_matching.rb +6 -4
- data/lib/xqsr3/internal_/test_unit_version_.rb +26 -0
- data/lib/xqsr3/io/writelines.rb +49 -13
- data/lib/xqsr3/quality.rb +8 -1
- data/lib/xqsr3/quality/parameter_checking.rb +3 -2
- data/lib/xqsr3/string_utilities.rb +16 -0
- data/lib/xqsr3/string_utilities/ends_with.rb +3 -2
- data/lib/xqsr3/string_utilities/nil_if_empty.rb +3 -2
- data/lib/xqsr3/string_utilities/nil_if_whitespace.rb +3 -2
- data/lib/xqsr3/string_utilities/quote_if.rb +7 -2
- data/lib/xqsr3/string_utilities/starts_with.rb +3 -2
- data/lib/xqsr3/string_utilities/to_symbol.rb +3 -2
- data/lib/xqsr3/string_utilities/truncate.rb +3 -2
- data/lib/xqsr3/version.rb +3 -2
- data/test/unit/containers/tc_multi_map.rb +174 -16
- data/test/unit/diagnostics/tc_exception_utilities.rb +7 -3
- data/test/unit/extensions/hash/tc_deep_transform.rb +0 -1
- data/test/unit/extensions/hash/tc_except.rb +67 -0
- data/test/unit/extensions/hash/tc_hash.rb +6 -0
- data/test/unit/extensions/hash/tc_slice.rb +31 -0
- data/test/unit/extensions/io/tc_writelines.rb +36 -0
- data/test/unit/extensions/kernel/tc_raise_with_options.rb +6 -3
- data/test/unit/tc_version.rb +1 -1
- metadata +22 -7
@@ -6,7 +6,7 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 21st November 2017
|
9
|
-
# Updated:
|
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
|
-
|
61
|
+
# @!visibility private
|
62
|
+
module IntegerParser_Helper_ # :nodoc: all
|
62
63
|
|
63
64
|
if Kernel.respond_to?(:xqsr3_Integer_original_method)
|
64
65
|
|
@@ -54,8 +54,10 @@ module Diagnostics
|
|
54
54
|
|
55
55
|
module InspectBuilder
|
56
56
|
|
57
|
-
|
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
|
@@ -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
|
+
|
@@ -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:
|
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-
|
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
|
58
|
-
#
|
59
|
-
|
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
|
-
|
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
|
-
|
6
|
-
module
|
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
|
|
@@ -6,13 +6,13 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 15th November 2017
|
9
|
-
# Updated: 15th
|
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
|
|
data/lib/xqsr3/io/writelines.rb
CHANGED
@@ -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:
|
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
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
88
|
+
contents.each do |element|
|
72
89
|
|
73
|
-
|
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.
|
99
|
+
if contents.instance_of? ::Hash
|
78
100
|
|
79
|
-
|
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
|
-
|
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
|
+
|