xqsr3 0.39.5 → 0.39.6
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/CHANGES.md +12 -1
- data/EXAMPLES.md +1 -1
- data/NEWS.md +1 -0
- data/examples/count_word_frequencies.md +1 -1
- data/lib/xqsr3/conversion/bool_parser.rb +24 -13
- data/lib/xqsr3/extensions/enumerable/unique.rb +30 -12
- data/lib/xqsr3/extensions/kernel/integer.rb +3 -3
- data/lib/xqsr3/hash_utilities/deep_transform.rb +8 -5
- data/lib/xqsr3/string_utilities/ends_with.rb +8 -5
- data/lib/xqsr3/string_utilities/starts_with.rb +8 -5
- data/lib/xqsr3/version.rb +2 -2
- data/test/unit/conversion/tc_to_bool.rb +31 -2
- data/test/unit/extensions/enumerable/tc_unique.rb +36 -0
- data/test/unit/extensions/hash/tc_deep_transform.rb +40 -0
- data/test/unit/extensions/kernel/tc_integer.rb +17 -0
- data/test/unit/extensions/string/tc_ends_with.rb +15 -0
- data/test/unit/extensions/string/tc_starts_with.rb +15 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6370aea72b56e6222b5bceb189340a255b87da7c047b058cbd67d6d4eb0b4bd9
|
|
4
|
+
data.tar.gz: db1fb7918b2737221db358636c2bdbb684d6f791a42582cee8df758b41f7ab2c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c9d4ba6de8d0390831931f32a0d8a41962d7fad41769d2e437aa566c0e89589a5df5bd33de774eb58ecff452695b8653d65ea49e30a4efe96a09a1f4975d8897
|
|
7
|
+
data.tar.gz: 04f7391d0212d72ad5c09a4aa2fd4c3b33304f9132f48b81f83e851b7fdad9027be7ea9344c8514be9c400fd8b072d9123d5b1268013a3f924a6f8c2bd2c03d2
|
data/CHANGES.md
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# xqsr3 - Changes <!-- omit in toc -->
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## 0.39.6 - 18th August 2026
|
|
5
|
+
|
|
6
|
+
* fixed **BoolParser** default matching to require whole-string `true`/`false` (case-insensitive), aligned `:default_value` / `:true_value` / `:false_value` options with documented names (legacy `:default` / `:true` / `:false` still accepted), and allowed falsy override values;
|
|
7
|
+
* fixed `Kernel#Integer` extension to honour the supplied +base+ (was always forced to +0+);
|
|
8
|
+
* fixed `Enumerable#unique` to honour its optional two-parameter equality comparator block;
|
|
9
|
+
* fixed `Hash#deep_transform!` (+NameError+ on +self+ check; arity-2 results were not written back);
|
|
10
|
+
* fixed `String#starts_with?` / `String#ends_with?` (+StringUtilities+) +to_str+ candidate path (was +s.prefix.to_str+);
|
|
11
|
+
* updated **run_all_unit_tests.sh** (from https://github.com/synesissoftware/misc-dev-scripts);
|
|
12
|
+
* fixed Windows CI by running **Gemfile.lock** removal under `bash` (`rm -f` is not valid PowerShell);
|
|
2
13
|
|
|
3
14
|
|
|
4
15
|
## 0.39.5 - 14th August 2026
|
data/EXAMPLES.md
CHANGED
data/NEWS.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Date | News Item |
|
|
4
4
|
| ------------------ | --------------------------- |
|
|
5
|
+
| 18th August 2026 | [**xqsr3** 0.39.6](https://github.com/synesissoftware/xqsr3/releases/tag/0.39.6) |
|
|
5
6
|
| 14th August 2026 | [**xqsr3** 0.39.5](https://github.com/synesissoftware/xqsr3/releases/tag/0.39.5) |
|
|
6
7
|
| 12th August 2026 | [**xqsr3** 0.39.4.1](https://github.com/synesissoftware/xqsr3/releases/tag/0.39.4.1) |
|
|
7
8
|
| 29th August 2025 | **xqsr3** 0.39.4 released |
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
# Purpose: Definition of the ::Xqsr3::Conversion::BoolParser module
|
|
6
6
|
#
|
|
7
7
|
# Created: 3rd June 2017
|
|
8
|
-
# Updated: 12th
|
|
8
|
+
# Updated: 12th August 2026
|
|
9
9
|
#
|
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
|
11
11
|
#
|
|
12
12
|
# Author: Matthew Wilson
|
|
13
13
|
#
|
|
14
|
-
# Copyright (c) 2019-
|
|
14
|
+
# Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems
|
|
15
15
|
# Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
|
|
16
16
|
# All rights reserved.
|
|
17
17
|
#
|
|
@@ -65,12 +65,24 @@ module Conversion
|
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
# Resolves an option that may be named by one or more keys, preserving
|
|
69
|
+
# explicitly supplied +nil+/+false+ values (unlike +Hash#fetch+ with +||+).
|
|
70
|
+
def self.option_value_ options, *keys, default_value
|
|
71
|
+
|
|
72
|
+
keys.each do |key|
|
|
73
|
+
|
|
74
|
+
return options[key] if options.key?(key)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
default_value
|
|
78
|
+
end
|
|
79
|
+
|
|
68
80
|
public
|
|
69
81
|
|
|
70
|
-
# Recognised truey values
|
|
71
|
-
DEFAULT_TRUE_VALUES = [ /
|
|
72
|
-
# Recognised falsey values
|
|
73
|
-
DEFAULT_FALSE_VALUES = [ /
|
|
82
|
+
# Recognised truey values (whole-string match)
|
|
83
|
+
DEFAULT_TRUE_VALUES = [ /\Atrue\z/i, '1' ]
|
|
84
|
+
# Recognised falsey values (whole-string match)
|
|
85
|
+
DEFAULT_FALSE_VALUES = [ /\Afalse\z/i, '0' ]
|
|
74
86
|
|
|
75
87
|
# Attempts to parse the given string +s+ to a Boolean value, based on the
|
|
76
88
|
# given +options+
|
|
@@ -84,18 +96,18 @@ module Conversion
|
|
|
84
96
|
# * *Options:*
|
|
85
97
|
# - +:false_values+ (+Array+) An array of strings or regular expressions against which to match for false value. Defaults to +DEFAULT_FALSE_VALUES+;
|
|
86
98
|
# - +:true_values+ (+Array+) An array of strings or regular expressions against which to match for true value. Defaults to +DEFAULT_TRUE_VALUES+;
|
|
87
|
-
# - +:default_value+ An object to be returned if matching fails.
|
|
88
|
-
# - +:false_value+ An object to be returned if matching succeeds to match against +:false_values+. Defaults to +false+;
|
|
89
|
-
# - +:true_value+ An object to be returned if matching succeeds to match against +:true_values+. Defaults to +true+;
|
|
99
|
+
# - +:default_value+ An object to be returned if matching fails. Defaults to +nil+. Alias: +:default+;
|
|
100
|
+
# - +:false_value+ An object to be returned if matching succeeds to match against +:false_values+. Defaults to +false+. Alias: +:false+;
|
|
101
|
+
# - +:true_value+ An object to be returned if matching succeeds to match against +:true_values+. Defaults to +true+. Alias: +:true+;
|
|
90
102
|
def self.to_bool s, **options
|
|
91
103
|
|
|
92
104
|
true_values = options[:true_values] || DEFAULT_TRUE_VALUES
|
|
93
105
|
true_values = [ true_values ] unless true_values.is_a? ::Array
|
|
94
106
|
false_values = options[:false_values] || DEFAULT_FALSE_VALUES
|
|
95
107
|
false_values = [ false_values ] unless false_values.is_a? ::Array
|
|
96
|
-
default_value = options
|
|
97
|
-
true_value = options
|
|
98
|
-
false_value = options
|
|
108
|
+
default_value = self.option_value_ options, :default_value, :default, nil
|
|
109
|
+
true_value = self.option_value_ options, :true_value, :true, true
|
|
110
|
+
false_value = self.option_value_ options, :false_value, :false, false
|
|
99
111
|
|
|
100
112
|
return true_value if true_values.any? { |v| self.matches_to_ s, v }
|
|
101
113
|
return false_value if false_values.any? { |v| self.matches_to_ s, v }
|
|
@@ -107,4 +119,3 @@ end # module Conversion
|
|
|
107
119
|
end # module Xqsr3
|
|
108
120
|
|
|
109
121
|
# ############################## end of file ############################# #
|
|
110
|
-
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
# Purpose: Adds a unique() method to the Enumerable module
|
|
6
6
|
#
|
|
7
7
|
# Created: 5th March 2007
|
|
8
|
-
# Updated: 12th
|
|
8
|
+
# Updated: 12th August 2026
|
|
9
9
|
#
|
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
|
11
11
|
#
|
|
12
12
|
# Author: Matthew Wilson
|
|
13
13
|
#
|
|
14
|
-
# Copyright (c) 2019-
|
|
14
|
+
# Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems
|
|
15
15
|
# Copyright (c) 2007-2019, Matthew Wilson and Synesis Software
|
|
16
16
|
# All rights reserved.
|
|
17
17
|
#
|
|
@@ -52,22 +52,27 @@ module Enumerable
|
|
|
52
52
|
|
|
53
53
|
# Removes all duplicate elements in a sequence subject to an optional
|
|
54
54
|
# two-parameter block in order to return an array containing unique
|
|
55
|
-
# elements
|
|
55
|
+
# elements. The first occurrence of each unique element is retained, in
|
|
56
|
+
# encounter order.
|
|
57
|
+
#
|
|
58
|
+
# Without a block, uniqueness is determined by +Hash+ membership (i.e.
|
|
59
|
+
# +#eql?+ / +#hash+).
|
|
60
|
+
#
|
|
61
|
+
# With a block of arity 2, the block is treated as an equality predicate:
|
|
62
|
+
# when it returns a truey value for +(kept, candidate)+, +candidate+ is
|
|
63
|
+
# treated as a duplicate of +kept+ and is discarded. Comparator mode is
|
|
64
|
+
# O(n^2) in the number of elements.
|
|
56
65
|
#
|
|
57
66
|
# [ 1, 2, 3 ].unique # => [ 1, 2, 3 ]
|
|
58
67
|
# [ 1, 2, 1, 3 ].unique # => [ 1, 2, 3 ]
|
|
68
|
+
# [ 1, 2, 1.0 ].unique { |a, b| a.to_s == b.to_s } # => [ 1, 2 ]
|
|
59
69
|
def unique(&block)
|
|
60
70
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return unique { |a, b| a == b }
|
|
64
|
-
else
|
|
65
|
-
|
|
66
|
-
raise ArgumentError, "block requires two parameters" unless block.arity == 2
|
|
71
|
+
ar = self.to_a
|
|
67
72
|
|
|
68
|
-
|
|
73
|
+
return ar if ar.length < 2
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
unless block
|
|
71
76
|
|
|
72
77
|
r = []
|
|
73
78
|
h = {}
|
|
@@ -83,8 +88,21 @@ module Enumerable
|
|
|
83
88
|
|
|
84
89
|
return r
|
|
85
90
|
end
|
|
91
|
+
|
|
92
|
+
raise ArgumentError, "block requires two parameters" unless block.arity == 2
|
|
93
|
+
|
|
94
|
+
r = []
|
|
95
|
+
|
|
96
|
+
ar.each do |v|
|
|
97
|
+
|
|
98
|
+
unless r.any? { |kept| yield(kept, v) }
|
|
99
|
+
|
|
100
|
+
r << v
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
return r
|
|
86
105
|
end
|
|
87
106
|
end # module Enumerable
|
|
88
107
|
|
|
89
108
|
# ############################## end of file ############################# #
|
|
90
|
-
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
# Purpose: Adds a Integer 'overload' to the Kernel module
|
|
6
6
|
#
|
|
7
7
|
# Created: 21st November 2017
|
|
8
|
-
# Updated: 12th
|
|
8
|
+
# Updated: 12th August 2026
|
|
9
9
|
#
|
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
|
11
11
|
#
|
|
12
12
|
# Author: Matthew Wilson
|
|
13
13
|
#
|
|
14
|
-
# Copyright (c) 2019-
|
|
14
|
+
# Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems
|
|
15
15
|
# Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
|
|
16
16
|
# All rights reserved.
|
|
17
17
|
#
|
|
@@ -70,7 +70,7 @@ module Kernel
|
|
|
70
70
|
# - +:nil+ Returns +nil+ if +arg+ is +nil+ or cannot be converted by (the original) +Kernel#Integer+. Ignored if +:default+ is specified;
|
|
71
71
|
def Integer(arg, base = 0, **options, &block)
|
|
72
72
|
|
|
73
|
-
::Xqsr3::Conversion::IntegerParser.to_integer arg, base
|
|
73
|
+
::Xqsr3::Conversion::IntegerParser.to_integer arg, base, **options, &block
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
private :xqsr3_Integer_original_method
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
# Purpose: Definition of the ::Xqsr3::HashUtilities::DeepTransform module
|
|
6
6
|
#
|
|
7
7
|
# Created: 3rd June 2017
|
|
8
|
-
# Updated: 12th
|
|
8
|
+
# Updated: 12th August 2026
|
|
9
9
|
#
|
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
|
11
11
|
#
|
|
12
12
|
# Author: Matthew Wilson
|
|
13
13
|
#
|
|
14
|
-
# Copyright (c) 2019-
|
|
14
|
+
# Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems
|
|
15
15
|
# Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
|
|
16
16
|
# All rights reserved.
|
|
17
17
|
#
|
|
@@ -92,7 +92,7 @@ module HashUtilities
|
|
|
92
92
|
|
|
93
93
|
def do_deep_transform_on_self_ &block # :nodoc:
|
|
94
94
|
|
|
95
|
-
::Xqsr3::Quality::ParameterChecking.check_parameter
|
|
95
|
+
::Xqsr3::Quality::ParameterChecking.check_parameter self, 'self', responds_to: [ :[]=, :delete, :keys ]
|
|
96
96
|
|
|
97
97
|
case block.arity
|
|
98
98
|
when 1
|
|
@@ -116,6 +116,8 @@ module HashUtilities
|
|
|
116
116
|
v = v.deep_transform(&block) if ::Hash === v
|
|
117
117
|
|
|
118
118
|
k, v = yield(k, v)
|
|
119
|
+
|
|
120
|
+
self[k] = v
|
|
119
121
|
end
|
|
120
122
|
else
|
|
121
123
|
|
|
@@ -134,7 +136,7 @@ module HashUtilities
|
|
|
134
136
|
end
|
|
135
137
|
|
|
136
138
|
# Executes the given mandatory 1- or 2-parameter block on the receiving
|
|
137
|
-
# instance,
|
|
139
|
+
# instance, which must be a +Hash+ or a type that responds to +[]+,
|
|
138
140
|
# +delete+, and +keys+ messages, changing the keys (1-parameter block)
|
|
139
141
|
# or keys and values (2-parameter block).
|
|
140
142
|
#
|
|
@@ -143,10 +145,11 @@ module HashUtilities
|
|
|
143
145
|
def deep_transform! &block
|
|
144
146
|
|
|
145
147
|
do_deep_transform_on_self_(&block)
|
|
148
|
+
|
|
149
|
+
self
|
|
146
150
|
end
|
|
147
151
|
end # module DeepTransform
|
|
148
152
|
end # module HashUtilities
|
|
149
153
|
end # module Xqsr3
|
|
150
154
|
|
|
151
155
|
# ############################## end of file ############################# #
|
|
152
|
-
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
# Purpose: Definition of the ::Xqsr3::StringUtilities::EndsWith module
|
|
6
6
|
#
|
|
7
7
|
# Created: 13th April 2016
|
|
8
|
-
# Updated: 12th
|
|
8
|
+
# Updated: 12th August 2026
|
|
9
9
|
#
|
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
|
11
11
|
#
|
|
12
12
|
# Author: Matthew Wilson
|
|
13
13
|
#
|
|
14
|
-
# Copyright (c) 2019-
|
|
14
|
+
# Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems
|
|
15
15
|
# Copyright (c) 2016-2019, Matthew Wilson and Synesis Software
|
|
16
16
|
# All rights reserved.
|
|
17
17
|
#
|
|
@@ -97,10 +97,13 @@ module StringUtilities
|
|
|
97
97
|
|
|
98
98
|
if prefix.respond_to? :to_str
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
r = self.string_ends_with_helper_ s, prefix.to_str
|
|
101
|
+
|
|
102
|
+
return r if r
|
|
103
|
+
else
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
raise TypeError, "ends_with? can be passed instances of #{::String}, or nil, or types that respond to to_str"
|
|
106
|
+
end
|
|
104
107
|
end
|
|
105
108
|
end
|
|
106
109
|
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
# Purpose: Definition of the ::Xqsr3::StringUtilities::StartsWith module
|
|
6
6
|
#
|
|
7
7
|
# Created: 13th April 2016
|
|
8
|
-
# Updated: 12th
|
|
8
|
+
# Updated: 12th August 2026
|
|
9
9
|
#
|
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
|
11
11
|
#
|
|
12
12
|
# Author: Matthew Wilson
|
|
13
13
|
#
|
|
14
|
-
# Copyright (c) 2019-
|
|
14
|
+
# Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems
|
|
15
15
|
# Copyright (c) 2016-2019, Matthew Wilson and Synesis Software
|
|
16
16
|
# All rights reserved.
|
|
17
17
|
#
|
|
@@ -97,10 +97,13 @@ module StringUtilities
|
|
|
97
97
|
|
|
98
98
|
if prefix.respond_to? :to_str
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
r = self.string_starts_with_helper_ s, prefix.to_str
|
|
101
|
+
|
|
102
|
+
return r if r
|
|
103
|
+
else
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
raise TypeError, "starts_with? can be passed instances of #{::String}, or nil, or types that respond to to_str"
|
|
106
|
+
end
|
|
104
107
|
end
|
|
105
108
|
end
|
|
106
109
|
|
data/lib/xqsr3/version.rb
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Purpose: Version for Xqsr3 library
|
|
6
6
|
#
|
|
7
7
|
# Created: 3rd April 2016
|
|
8
|
-
# Updated:
|
|
8
|
+
# Updated: 18th August 2026
|
|
9
9
|
#
|
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
|
11
11
|
#
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
module Xqsr3
|
|
52
52
|
|
|
53
53
|
# Current version of the Xqsr3 library
|
|
54
|
-
VERSION = '0.39.
|
|
54
|
+
VERSION = '0.39.6'
|
|
55
55
|
|
|
56
56
|
private
|
|
57
57
|
VERSION_PARTS_ = VERSION.split(/[.]/).collect { |n| n.to_i } # :nodoc:
|
|
@@ -9,14 +9,44 @@ require 'xqsr3/extensions/test/unit'
|
|
|
9
9
|
require 'test/unit'
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class
|
|
12
|
+
class Test_Xqsr3_Conversion_BoolParser < Test::Unit::TestCase
|
|
13
13
|
|
|
14
14
|
include ::Xqsr3::Conversion
|
|
15
15
|
|
|
16
16
|
def test_parse_normal
|
|
17
17
|
|
|
18
18
|
assert_true BoolParser.to_bool 'true'
|
|
19
|
+
assert_true BoolParser.to_bool 'TRUE'
|
|
20
|
+
assert_true BoolParser.to_bool '1'
|
|
19
21
|
assert_false BoolParser.to_bool 'false'
|
|
22
|
+
assert_false BoolParser.to_bool 'FALSE'
|
|
23
|
+
assert_false BoolParser.to_bool '0'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_parse_rejects_substring_defaults
|
|
27
|
+
|
|
28
|
+
assert_nil BoolParser.to_bool 'untrue'
|
|
29
|
+
assert_nil BoolParser.to_bool 'truest'
|
|
30
|
+
assert_nil BoolParser.to_bool 'unfalse'
|
|
31
|
+
assert_nil BoolParser.to_bool 'falsehood'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_parse_default_value_and_aliases
|
|
35
|
+
|
|
36
|
+
assert_equal :missing, BoolParser.to_bool('maybe', default_value: :missing)
|
|
37
|
+
assert_equal :legacy, BoolParser.to_bool('maybe', default: :legacy)
|
|
38
|
+
assert_nil BoolParser.to_bool('maybe', default_value: nil)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_parse_true_false_value_overrides
|
|
42
|
+
|
|
43
|
+
assert_equal :yes, BoolParser.to_bool('true', true_value: :yes)
|
|
44
|
+
assert_equal :no, BoolParser.to_bool('false', false_value: :no)
|
|
45
|
+
assert_false BoolParser.to_bool('true', true_value: false)
|
|
46
|
+
assert_true BoolParser.to_bool('false', false_value: true)
|
|
47
|
+
assert_nil BoolParser.to_bool('true', true_value: nil)
|
|
48
|
+
assert_false BoolParser.to_bool('true', true: false)
|
|
49
|
+
assert_true BoolParser.to_bool('false', false: true)
|
|
20
50
|
end
|
|
21
51
|
|
|
22
52
|
def test_parse_custom_true_false
|
|
@@ -45,4 +75,3 @@ class Test_Xqsr3_ConversionMultiMap < Test::Unit::TestCase
|
|
|
45
75
|
assert_nil BoolParser.to_bool 'false', true_values: true_values, false_values: false_values
|
|
46
76
|
end
|
|
47
77
|
end
|
|
48
|
-
|
|
@@ -69,5 +69,41 @@ class Test_Enumerable_unique_test < Test::Unit::TestCase
|
|
|
69
69
|
|
|
70
70
|
assert_equal exp, dest
|
|
71
71
|
end
|
|
72
|
+
|
|
73
|
+
def test_unique_with_comparator_block
|
|
74
|
+
|
|
75
|
+
src = [ 1, 2, 1.0, 3 ]
|
|
76
|
+
|
|
77
|
+
# Default uniqueness uses Hash (#eql?/#hash), so 1 and 1.0 both remain.
|
|
78
|
+
assert_equal [ 1, 2, 1.0, 3 ], src.unique
|
|
79
|
+
|
|
80
|
+
# Numeric == treats 1 and 1.0 as equal.
|
|
81
|
+
dest = src.unique { |a, b| a == b }
|
|
82
|
+
|
|
83
|
+
assert_equal [ 1, 2, 3 ], dest
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_unique_with_comparator_block_to_s
|
|
87
|
+
|
|
88
|
+
src = [ 1, 2, '1', 3, '2' ]
|
|
89
|
+
|
|
90
|
+
dest = src.unique { |a, b| a.to_s == b.to_s }
|
|
91
|
+
|
|
92
|
+
assert_equal [ 1, 2, 3 ], dest
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_unique_with_comparator_block_preserves_first
|
|
96
|
+
|
|
97
|
+
src = [ 'A', 'b', 'a', 'B' ]
|
|
98
|
+
|
|
99
|
+
dest = src.unique { |a, b| a.downcase == b.downcase }
|
|
100
|
+
|
|
101
|
+
assert_equal [ 'A', 'b' ], dest
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_unique_with_wrong_arity_block
|
|
105
|
+
|
|
106
|
+
assert_raise(ArgumentError) { [ 1, 2 ].unique { |a| a } }
|
|
107
|
+
end
|
|
72
108
|
end
|
|
73
109
|
|
|
@@ -16,6 +16,7 @@ class Test_Hash_deep_transform < Test::Unit::TestCase
|
|
|
16
16
|
def test_Hash_has_method
|
|
17
17
|
|
|
18
18
|
assert Hash.new.respond_to? :deep_transform
|
|
19
|
+
assert Hash.new.respond_to? :deep_transform!
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def test_with_empty
|
|
@@ -45,6 +46,45 @@ class Test_Hash_deep_transform < Test::Unit::TestCase
|
|
|
45
46
|
assert_equal h_1, h.deep_transform { |k, v| [ k.respond_to?(:to_sym) ? k.to_sym : k, v ] }
|
|
46
47
|
assert_equal h_2, h.deep_transform { |k, v| [ k.respond_to?(:to_sym) ? k.to_sym : k, v.respond_to?(:to_sym) ? v.to_sym : v ] }
|
|
47
48
|
end
|
|
49
|
+
|
|
50
|
+
def test_bang_transform_to_same
|
|
51
|
+
|
|
52
|
+
jkl = 12
|
|
53
|
+
h = { 'abc' => 'def', ghi: jkl, mno: { p: 'q', 'r' => 'st' } }
|
|
54
|
+
orig = h.dup
|
|
55
|
+
|
|
56
|
+
assert_same h, h.deep_transform! { |k| k }
|
|
57
|
+
assert_equal orig, h
|
|
58
|
+
|
|
59
|
+
h = orig.dup
|
|
60
|
+
assert_same h, h.deep_transform! { |k, v| [ k, v ] }
|
|
61
|
+
assert_equal orig, h
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_bang_transform_to_symbolise_keys
|
|
65
|
+
|
|
66
|
+
jkl = 12
|
|
67
|
+
h = { 'abc' => 'def', ghi: jkl, mno: { p: 'q', 'r' => 'st' } }
|
|
68
|
+
h_1 = { abc: 'def', ghi: jkl, mno: { p: 'q', r: 'st' } }
|
|
69
|
+
|
|
70
|
+
assert_same h, h.deep_transform! { |k| k.respond_to?(:to_sym) ? k.to_sym : k }
|
|
71
|
+
assert_equal h_1, h
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_bang_transform_keys_and_values
|
|
75
|
+
|
|
76
|
+
jkl = 12
|
|
77
|
+
h = { 'abc' => 'def', ghi: jkl, mno: { p: 'q', 'r' => 'st' } }
|
|
78
|
+
h_2 = { abc: :def, ghi: jkl, mno: { p: :q, r: :st } }
|
|
79
|
+
|
|
80
|
+
assert_same h, h.deep_transform! { |k, v| [ k.respond_to?(:to_sym) ? k.to_sym : k, v.respond_to?(:to_sym) ? v.to_sym : v ] }
|
|
81
|
+
assert_equal h_2, h
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_bang_wrong_arity
|
|
85
|
+
|
|
86
|
+
assert_raise(ArgumentError) { { a: 1 }.deep_transform! { |a, b, c| [ a, b ] } }
|
|
87
|
+
end
|
|
48
88
|
end
|
|
49
89
|
|
|
50
90
|
|
|
@@ -26,6 +26,23 @@ class Test_X_Kernel_Integer < Test::Unit::TestCase
|
|
|
26
26
|
assert_equal(-1, Integer('-1'))
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
def test_Integer_with_base
|
|
30
|
+
|
|
31
|
+
assert_equal 16, Integer('10', 16)
|
|
32
|
+
assert_equal 8, Integer('10', 8)
|
|
33
|
+
assert_equal 10, Integer('10', 10)
|
|
34
|
+
assert_equal 2, Integer('10', 2)
|
|
35
|
+
assert_equal 255, Integer('ff', 16)
|
|
36
|
+
assert_equal 255, Integer('FF', 16)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_Integer_with_base_and_options
|
|
40
|
+
|
|
41
|
+
assert_equal 16, Integer('10', 16, default: 0)
|
|
42
|
+
assert_equal 0, Integer('gg', 16, default: 0)
|
|
43
|
+
assert_nil Integer('gg', 16, nil: true)
|
|
44
|
+
end
|
|
45
|
+
|
|
29
46
|
def test_Integer_with_invalid_values
|
|
30
47
|
|
|
31
48
|
assert_raise(TypeError) { Integer nil }
|
|
@@ -66,6 +66,21 @@ class Test_String_ends_with < Test::Unit::TestCase
|
|
|
66
66
|
assert_nil 'd'.ends_with?(*prefixes)
|
|
67
67
|
assert 'abcdef'.ends_with?(*prefixes)
|
|
68
68
|
end
|
|
69
|
+
|
|
70
|
+
def test_with_to_str
|
|
71
|
+
|
|
72
|
+
suffix = Object.new
|
|
73
|
+
def suffix.to_str; 'cd'; end
|
|
74
|
+
|
|
75
|
+
assert_equal 'cd', 'abcd'.ends_with?(suffix)
|
|
76
|
+
assert_nil 'xyz'.ends_with?(suffix)
|
|
77
|
+
assert_equal 'cd', 'abcd'.ends_with?('zz', suffix)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_with_unsupported_type
|
|
81
|
+
|
|
82
|
+
assert_raise(TypeError) { 'abcd'.ends_with?(Object.new) }
|
|
83
|
+
end
|
|
69
84
|
end
|
|
70
85
|
|
|
71
86
|
|
|
@@ -66,6 +66,21 @@ class Test_String_starts_with < Test::Unit::TestCase
|
|
|
66
66
|
assert_nil 'd'.starts_with?(*prefixes)
|
|
67
67
|
assert 'defghi'.starts_with?(*prefixes)
|
|
68
68
|
end
|
|
69
|
+
|
|
70
|
+
def test_with_to_str
|
|
71
|
+
|
|
72
|
+
prefix = Object.new
|
|
73
|
+
def prefix.to_str; 'ab'; end
|
|
74
|
+
|
|
75
|
+
assert_equal 'ab', 'abcd'.starts_with?(prefix)
|
|
76
|
+
assert_nil 'xyz'.starts_with?(prefix)
|
|
77
|
+
assert_equal 'ab', 'abcd'.starts_with?('zz', prefix)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_with_unsupported_type
|
|
81
|
+
|
|
82
|
+
assert_raise(TypeError) { 'abcd'.starts_with?(Object.new) }
|
|
83
|
+
end
|
|
69
84
|
end
|
|
70
85
|
|
|
71
86
|
|
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.39.
|
|
4
|
+
version: 0.39.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matt Wilson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-18 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
|