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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72ece61bc93710b647adac7e93687c835d7bcee3787814644ce872dca526d5f8
4
- data.tar.gz: 58e1e026954a52664444da7b343169470754a9c44c2c4211f8493cfc3112345d
3
+ metadata.gz: 6370aea72b56e6222b5bceb189340a255b87da7c047b058cbd67d6d4eb0b4bd9
4
+ data.tar.gz: db1fb7918b2737221db358636c2bdbb684d6f791a42582cee8df758b41f7ab2c
5
5
  SHA512:
6
- metadata.gz: 8d3e1a6ac02ff6288a95550bb2d8efa04e5f247e0e4db6e617fb9e60d44386df803681566bd17f2e7e2336e7b04913474bbf61ab63854ff7625589975edae720
7
- data.tar.gz: '03638e1c40996a359a6ff04bf7a801b5760366e538f30942808e871c568464444d45335279b1d0a78da04138353ab4f3394f11800db5eb2c4dbf4d71f71ea201'
6
+ metadata.gz: c9d4ba6de8d0390831931f32a0d8a41962d7fad41769d2e437aa566c0e89589a5df5bd33de774eb58ecff452695b8653d65ea49e30a4efe96a09a1f4975d8897
7
+ data.tar.gz: 04f7391d0212d72ad5c09a4aa2fd4c3b33304f9132f48b81f83e851b7fdad9027be7ea9344c8514be9c400fd8b072d9123d5b1268013a3f924a6f8c2bd2c03d2
data/CHANGES.md CHANGED
@@ -1,4 +1,15 @@
1
- # **xqsr3** Changes <!-- omit in toc -->
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
@@ -1,4 +1,4 @@
1
- # **xqsr3** Examples <!-- omit in toc -->
1
+ # xqsr3 - Examples <!-- omit in toc -->
2
2
 
3
3
  |Name|Source & Description|Summary|
4
4
  |---|---|---|
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 |
@@ -1,4 +1,4 @@
1
- # xqsr3 Example - **count_word_frequencies**
1
+ # xqsr3 - Example - **count_word_frequencies**
2
2
 
3
3
  ## Summary
4
4
 
@@ -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 April 2024
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-2024, Matthew Wilson and Synesis Information Systems
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 = [ /true/i, '1' ]
72
- # Recognised falsey values
73
- DEFAULT_FALSE_VALUES = [ /false/i, '0' ]
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. Defaults to +nil+;
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[:default] || nil
97
- true_value = options[:true] || true
98
- false_value = options[:false] || false
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 April 2024
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-2024, Matthew Wilson and Synesis Information Systems
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
- if not block
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
- ar = self.to_a
73
+ return ar if ar.length < 2
69
74
 
70
- return ar if ar.length < 2
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 April 2024
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-2024, Matthew Wilson and Synesis Information Systems
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 = 0, **options, &block
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 April 2024
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-2024, Matthew Wilson and Synesis Information Systems
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 h, 'h', responds_to: [ :[]=, :delete, :keys ]
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, whihc must be a +Hash+ or a type that responds to +[]+,
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 April 2024
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-2024, Matthew Wilson and Synesis Information Systems
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
- return self.string_ends_with_helper_ s.prefix.to_str
101
- end
100
+ r = self.string_ends_with_helper_ s, prefix.to_str
101
+
102
+ return r if r
103
+ else
102
104
 
103
- raise TypeError, "ends_with? can be passed instances of #{::String}, or nil, or types that respond to to_str"
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 April 2024
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-2024, Matthew Wilson and Synesis Information Systems
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
- return self.string_starts_with_helper_ s.prefix.to_str
101
- end
100
+ r = self.string_starts_with_helper_ s, prefix.to_str
101
+
102
+ return r if r
103
+ else
102
104
 
103
- raise TypeError, "starts_with? can be passed instances of #{::String}, or nil, or types that respond to to_str"
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: 14th August 2026
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.5'
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 Test_Xqsr3_ConversionMultiMap < Test::Unit::TestCase
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.5
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-14 00:00:00.000000000 Z
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