xqsr3 0.10.2 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 522223b0b707f9057fdafa48580809911ecd8c9d
4
- data.tar.gz: 9203708c9ca41f78025c5882f72fa7f55170a095
3
+ metadata.gz: b23c1bd7f01f0540f8cd11ba2a619fa6d2fb334c
4
+ data.tar.gz: 7b79521e19d9f76bc869a83c8003cbddec3ad576
5
5
  SHA512:
6
- metadata.gz: fcb1fb10938327574cb3ea10ce57a91d795d6cc524cd95aae6770daace4306ae63f17957920bb3e32932ce11f350139cc70151485a38b86f072622b7c34260e4
7
- data.tar.gz: 4aef021764d9cff5977379ae18136713cbbcb346afd87014de9f2dffd31e25e03aa51899494a6940af39d44ebd637a49b4145d52e940be7556ef93035ee95665
6
+ metadata.gz: 1c53ef621526a41f9f47afe099d1ff8df7dc775700a2974ecab2834a317f31fd012c98c679aa1499fb2ce696daf9f257ddf64424fa232517a6df0cff3383c212
7
+ data.tar.gz: bc62c09071304cb569e896217f719337038c5e888882b35ecdec4df67eb4c89202e8f6d896d12d9788918428888297fc87895b2b21dd998a737fb369008e56e1
@@ -0,0 +1,8 @@
1
+
2
+ require 'xqsr3/hash_utilities/deep_transform'
3
+
4
+ class Hash
5
+
6
+ include ::Xqsr3::HashUtilities::DeepTransform
7
+ end # class Hash
8
+
@@ -1,6 +1,7 @@
1
1
 
2
2
  require 'xqsr3/extensions/string/ends_with'
3
3
  require 'xqsr3/extensions/string/map_option_string'
4
+ require 'xqsr3/extensions/string/quote_if'
4
5
  require 'xqsr3/extensions/string/starts_with'
5
6
  require 'xqsr3/extensions/string/to_symbol'
6
7
 
@@ -0,0 +1,9 @@
1
+
2
+ require 'xqsr3/string_utilities/quote_if'
3
+
4
+ class String
5
+
6
+ include ::Xqsr3::StringUtilities::QuoteIf
7
+ end # class String
8
+
9
+
@@ -0,0 +1,155 @@
1
+
2
+ # ######################################################################## #
3
+ # File: lib/xqsr3/hash_utilities/deep_transform.rb
4
+ #
5
+ # Purpose: Definition of the ::Xqsr3::HashUtilities::DeepTransform
6
+ # module
7
+ #
8
+ # Created: 3rd June 2017
9
+ # Updated: 7th June 2017
10
+ #
11
+ # Home: http://github.com/synesissoftware/xqsr3
12
+ #
13
+ # Author: Matthew Wilson
14
+ #
15
+ # Copyright (c) 2017, Matthew Wilson and Synesis Software
16
+ # All rights reserved.
17
+ #
18
+ # Redistribution and use in source and binary forms, with or without
19
+ # modification, are permitted provided that the following conditions are
20
+ # met:
21
+ #
22
+ # * Redistributions of source code must retain the above copyright notice,
23
+ # this list of conditions and the following disclaimer.
24
+ #
25
+ # * Redistributions in binary form must reproduce the above copyright
26
+ # notice, this list of conditions and the following disclaimer in the
27
+ # documentation and/or other materials provided with the distribution.
28
+ #
29
+ # * Neither the names of the copyright holder nor the names of its
30
+ # contributors may be used to endorse or promote products derived from
31
+ # this software without specific prior written permission.
32
+ #
33
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
34
+ # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
35
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
37
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
39
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
40
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
+ #
45
+ # ######################################################################## #
46
+
47
+
48
+ # ##########################################################
49
+ # ::Xqsr3::HashUtilities::DeepTransform
50
+
51
+ =begin
52
+ =end
53
+
54
+ module Xqsr3
55
+ module HashUtilities
56
+
57
+ module DeepTransform
58
+
59
+ private
60
+ def self.do_deep_transform_on_hashlike_ h, &block
61
+
62
+ ::Xqsr3::Quality::ParameterChecking.check_parameter h, 'h', responds_to: [ :map ]
63
+
64
+ case block.arity
65
+ when 1
66
+
67
+ h =
68
+ Hash[h.map do |k, v|
69
+
70
+ k = k.deep_transform &block if ::Hash === k
71
+ v = v.deep_transform &block if ::Hash === v
72
+
73
+ [yield(k), v]
74
+ end]
75
+ when 2
76
+
77
+ h =
78
+ Hash[h.map do |k, v|
79
+
80
+ k = k.deep_transform &block if ::Hash === k
81
+ v = v.deep_transform &block if ::Hash === v
82
+
83
+ yield(k, v)
84
+ end]
85
+ else
86
+
87
+ raise ArgumentError, "block arity must be 1 or 2"
88
+ end
89
+
90
+ h
91
+ end
92
+
93
+ def do_deep_transform_on_self_ &block
94
+
95
+ ::Xqsr3::Quality::ParameterChecking.check_parameter h, 'h', responds_to: [ :[]=, :delete, :keys ]
96
+
97
+ case block.arity
98
+ when 1
99
+
100
+ self.keys.each do |k|
101
+
102
+ v = self.delete k
103
+
104
+ k = k.deep_transform &block if ::Hash === k
105
+ v = v.deep_transform &block if ::Hash === v
106
+
107
+ self[yield(k)] = v
108
+ end
109
+ when 2
110
+
111
+ self.keys.each do |k|
112
+
113
+ v = self.delete k
114
+
115
+ k = k.deep_transform &block if ::Hash === k
116
+ v = v.deep_transform &block if ::Hash === v
117
+
118
+ k, v = yield(k, v)
119
+ end
120
+ else
121
+
122
+ raise ArgumentError, "block arity must be 1 or 2"
123
+ end
124
+ end
125
+ public
126
+
127
+ # Executes the given mandatory 1- or 2-parameter block on the receiving
128
+ # instance, which must be a Hash or a type that responds to the +map+
129
+ # message, returning a copy of the instance in which keys (1-parameter
130
+ # block) or keys and values (2-parameter block) are transformed.
131
+ def deep_transform &block
132
+
133
+ DeepTransform.do_deep_transform_on_hashlike_ self, &block
134
+ end
135
+
136
+ # 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 +[]+,
138
+ # +delete+, and +keys+ messages, changing the keys (1-parameter block)
139
+ # or keys and values (2-parameter block).
140
+ #
141
+ # @note This method is not strongly exception-safe - failure during
142
+ # transformation can result in a partially transformed instance
143
+ def deep_transform! &block
144
+
145
+ do_deep_transform_on_self_ &block
146
+ end
147
+
148
+ end # module DeepTransform
149
+
150
+ end # module HashUtilities
151
+ end # module Xqsr3
152
+
153
+ # ############################## end of file ############################# #
154
+
155
+
@@ -84,6 +84,8 @@ module ParameterChecking
84
84
  # of types, in which case +value+ may be an array that must
85
85
  # consist wholly of those types
86
86
  # @option +:values+ an array of values one of which +value+ must be
87
+ # @option +:responds_to+ an array of symbols specifying all messages to
88
+ # which the parameter will respond
87
89
  # @option +:reject_empty+ requires value to respond to +empty?+
88
90
  # message and to do so with false, unless +nil+
89
91
  # @option +:require_empty+ requires value to respond to +empty?+
@@ -135,6 +137,8 @@ module ParameterChecking
135
137
 
136
138
  unless value.nil?
137
139
 
140
+ # types
141
+
138
142
  types = options[:types] || []
139
143
  types = [value.class] if types.empty?
140
144
  type_found = false
@@ -192,6 +196,25 @@ module ParameterChecking
192
196
  raise TypeError, message
193
197
  end
194
198
  end
199
+
200
+
201
+ # messages
202
+
203
+ messages = options[:responds_to] || []
204
+
205
+ warn "#{self}::check_parameter: options[:responds_to] of type #{messages.class} - should be #{::Array}" unless messages.is_a?(Array)
206
+ warn "#{self}::check_parameter: options[:responds_to] should contain only symbols or strings" if messages.is_a?(::Array) && !messages.all? { |m| ::Symbol === m || ::String === m }
207
+
208
+ messages.each do |m|
209
+
210
+ unless value.respond_to? m
211
+
212
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
213
+
214
+ raise TypeError, "#{param_s} #{s_name}(#{value.class}) must respond to the '#{m}' message"
215
+ end
216
+ end
217
+
195
218
  end
196
219
 
197
220
  # reject/require empty?
@@ -0,0 +1,132 @@
1
+
2
+ # ######################################################################## #
3
+ # File: lib/xqsr3/string_utilities/quote_if.rb
4
+ #
5
+ # Purpose: Definition of the ::Xqsr3::StringUtilities::QuoteIf
6
+ # module
7
+ #
8
+ # Created: 3rd June 2017
9
+ # Updated: 7th June 2017
10
+ #
11
+ # Home: http://github.com/synesissoftware/xqsr3
12
+ #
13
+ # Author: Matthew Wilson
14
+ #
15
+ # Copyright (c) 2017, Matthew Wilson and Synesis Software
16
+ # All rights reserved.
17
+ #
18
+ # Redistribution and use in source and binary forms, with or without
19
+ # modification, are permitted provided that the following conditions are
20
+ # met:
21
+ #
22
+ # * Redistributions of source code must retain the above copyright notice,
23
+ # this list of conditions and the following disclaimer.
24
+ #
25
+ # * Redistributions in binary form must reproduce the above copyright
26
+ # notice, this list of conditions and the following disclaimer in the
27
+ # documentation and/or other materials provided with the distribution.
28
+ #
29
+ # * Neither the names of the copyright holder nor the names of its
30
+ # contributors may be used to endorse or promote products derived from
31
+ # this software without specific prior written permission.
32
+ #
33
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
34
+ # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
35
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
37
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
39
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
40
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
+ #
45
+ # ######################################################################## #
46
+
47
+
48
+ # ##########################################################
49
+ # ::Xqsr3::StringUtilities::QuoteIf
50
+
51
+ =begin
52
+ =end
53
+
54
+ module Xqsr3
55
+ module StringUtilities
56
+
57
+ module QuoteIf
58
+
59
+ private
60
+ module QuoteIf_Helper_ #:nodoc:
61
+
62
+ def self.string_quote_if_array_ s, options
63
+
64
+ #$stderr.puts "#{self}#{__method__}(s (#{s.class})='#{s}', options (#{options.class})='#{options}'"
65
+
66
+ s = s.to_s unless String === s
67
+
68
+ quotes = options[:quotes] || [ '"', '"' ]
69
+ quotes = [ quotes, quotes ] if String === quotes
70
+
71
+ quotables = options[:quotables] || /\s/
72
+
73
+ #$stderr.puts "quotables (#{quotables.class}): [#{quotables}]"
74
+
75
+ case quotables
76
+ when ::String
77
+
78
+ return s unless s.include? quotables
79
+ when ::Array
80
+
81
+ return s unless quotables.any? { |quotable| s.include? quotable }
82
+ when ::Regexp
83
+
84
+ return s unless s =~ quotables
85
+ else
86
+
87
+ raise ArgumentError, "Invalid type (#{quotables.class}) specified for quotables parameter"
88
+ end
89
+
90
+ return quotes[0] + s + quotes[1]
91
+ end
92
+ end
93
+ public
94
+
95
+ # Converts a string to a quoted form if necessary
96
+ #
97
+ # === *Parameters*
98
+ #
99
+ # * *Required parameters*:
100
+ # - +s+:: [String] The string to be evaluated
101
+ #
102
+ # * *Options parameters*:
103
+ # - +options+:: [Hash] Options that control the behaviour of the
104
+ # method
105
+ #
106
+ # * *Options*:
107
+ #
108
+ # - +:quotes+:: [String, Array] A string that is used as the opening
109
+ # and closing quotes, or an array whose first two elements are
110
+ # used as the opening and closing quotes. Defaults to '"'
111
+ # - +:quotables+:: [String, Array, Regexp] A string representing the
112
+ # quotable character, or an array containing the quotable
113
+ # characters, or a regular expression that determines by match
114
+ # whether the string should be quoted. Defaults to the regular
115
+ # expression /\s/
116
+ def self.quote_if s, **options
117
+
118
+ QuoteIf_Helper_.string_quote_if_array_ s, options
119
+ end
120
+
121
+ def quote_if **options
122
+
123
+ QuoteIf_Helper_.string_quote_if_array_ self, options
124
+ end
125
+ end # module QuoteIf
126
+
127
+ end # module StringUtilities
128
+ end # module Xqsr3
129
+
130
+ # ############################## end of file ############################# #
131
+
132
+
@@ -5,7 +5,7 @@
5
5
  # Purpose: Version for Xqsr3 library
6
6
  #
7
7
  # Created: 3rd April 2016
8
- # Updated: 26th February 2017
8
+ # Updated: 7th June 2017
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
@@ -50,7 +50,7 @@
50
50
  module Xqsr3
51
51
 
52
52
  # Current version of the Xqsr3 library
53
- VERSION = '0.10.2'
53
+ VERSION = '0.11.1'
54
54
 
55
55
  private
56
56
  VERSION_PARTS_ = VERSION.split(/[.]/).collect { |n| n.to_i } # :nodoc:
@@ -0,0 +1,49 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), '../../../../lib')
4
+
5
+ require 'xqsr3/extensions/hash/deep_transform'
6
+
7
+ require 'xqsr3/extensions/test/unit'
8
+ require 'test/unit'
9
+
10
+ require 'stringio'
11
+
12
+ class Test_Hash_deep_transform < Test::Unit::TestCase
13
+
14
+ def test_Hash_has_method
15
+
16
+ assert Hash.new.respond_to? :deep_transform
17
+ end
18
+
19
+ def test_with_empty
20
+
21
+ assert_equal Hash.new, Hash.new.deep_transform { |k| k }
22
+ assert_equal Hash.new, Hash.new.deep_transform { |k, v| [ k, v ] }
23
+ end
24
+
25
+ def test_transform_to_same
26
+
27
+ jkl = 12
28
+ h = { 'abc' => 'def', ghi: jkl, mno: { p: 'q', 'r' => 'st' } }
29
+
30
+ assert_equal h, h.deep_transform { |k| k }
31
+ assert_equal h, h.deep_transform { |k, v| [ k, v ] }
32
+ end
33
+
34
+ def test_transform_to_symbolise_keys
35
+
36
+ jkl = 12
37
+ h = { 'abc' => 'def', ghi: jkl, mno: { p: 'q', 'r' => 'st' } }
38
+
39
+ h_1 = { abc: 'def', ghi: jkl, mno: { p: 'q', r: 'st' } }
40
+ h_2 = { abc: :def, ghi: jkl, mno: { p: :q, r: :st } }
41
+
42
+ assert_equal h_1, h.deep_transform { |k| k.respond_to?(:to_sym) ? k.to_sym : k }
43
+ assert_equal h_1, h.deep_transform { |k, v| [ k.respond_to?(:to_sym) ? k.to_sym : k, v ] }
44
+ 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 ] }
45
+ end
46
+ end
47
+
48
+
49
+
@@ -0,0 +1,13 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # executes all other tests
4
+
5
+ this_file = File.expand_path(__FILE__)
6
+ this_dir = File.expand_path(File.dirname(__FILE__))
7
+
8
+ # all tc_*rb in current directory
9
+ Dir[File.join(this_dir, 'tc_*rb')].each { |file| require file }
10
+
11
+ # all ts_*rb in immediate sub-directories
12
+ Dir[File.join(this_dir, '*', 'ts_*rb')].each { |file| require file }
13
+
@@ -0,0 +1,42 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), '../../../../lib')
4
+
5
+ require 'xqsr3/extensions/string/quote_if'
6
+
7
+ require 'xqsr3/extensions/test/unit'
8
+ require 'test/unit'
9
+
10
+ require 'stringio'
11
+
12
+ class Test_String_quote_if < Test::Unit::TestCase
13
+
14
+ def test_String_has_method
15
+
16
+ assert ''.respond_to? :quote_if
17
+ end
18
+
19
+ def test_with_no_options
20
+
21
+ assert_equal '', ''.quote_if
22
+ assert_equal 'a', 'a'.quote_if
23
+ assert_equal 'ab', 'ab'.quote_if
24
+ assert_equal '"a b"', 'a b'.quote_if
25
+ end
26
+
27
+ def test_with_quotables
28
+
29
+ assert_equal 'a b', 'a b'.quote_if(quotables: '-')
30
+ assert_equal '"a-b"', 'a-b'.quote_if(quotables: '-')
31
+ end
32
+
33
+ def test_with_quotes
34
+
35
+ assert_equal '"a b"', 'a b'.quote_if
36
+ assert_equal '|a b|', 'a b'.quote_if(quotes: '|')
37
+ assert_equal '[a b]', 'a b'.quote_if(quotes: [ '[', ']' ])
38
+ end
39
+ end
40
+
41
+
42
+
@@ -221,7 +221,23 @@ end
221
221
 
222
222
  assert(false, "wrong exception type #{x.class}) (with message '#{x.message}'")
223
223
  end
224
+ end
225
+
226
+
227
+ # responds_to
224
228
 
229
+ def check_responds_to a, messages, options = {}, &block
230
+
231
+ self.class.check_param a, 'a', options.merge({ responds_to: messages }), &block
232
+ end
233
+
234
+ def test_responds_to
235
+
236
+ assert check_responds_to Hash.new, [ :[], :map, :to_s ]
237
+ assert_raise ::TypeError do
238
+
239
+ check_responds_to Hash.new, [ :this_is_not_a_Hash_method ]
240
+ end
225
241
  end
226
242
  end
227
243
 
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.10.2
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Wilson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-27 00:00:00.000000000 Z
11
+ date: 2017-06-07 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
@@ -29,6 +29,7 @@ files:
29
29
  - lib/xqsr3/extensions/enumerable.rb
30
30
  - lib/xqsr3/extensions/enumerable/collect_with_index.rb
31
31
  - lib/xqsr3/extensions/enumerable/unique.rb
32
+ - lib/xqsr3/extensions/hash/deep_transform.rb
32
33
  - lib/xqsr3/extensions/io.rb
33
34
  - lib/xqsr3/extensions/io/writelines.rb
34
35
  - lib/xqsr3/extensions/kernel.rb
@@ -36,16 +37,19 @@ files:
36
37
  - lib/xqsr3/extensions/string.rb
37
38
  - lib/xqsr3/extensions/string/ends_with.rb
38
39
  - lib/xqsr3/extensions/string/map_option_string.rb
40
+ - lib/xqsr3/extensions/string/quote_if.rb
39
41
  - lib/xqsr3/extensions/string/starts_with.rb
40
42
  - lib/xqsr3/extensions/string/to_symbol.rb
41
43
  - lib/xqsr3/extensions/test/unit.rb
42
44
  - lib/xqsr3/extensions/test/unit/assert_eql.rb
43
45
  - lib/xqsr3/extensions/test/unit/assert_not.rb
44
46
  - lib/xqsr3/extensions/test/unit/assert_not_eql.rb
47
+ - lib/xqsr3/hash_utilities/deep_transform.rb
45
48
  - lib/xqsr3/io/writelines.rb
46
49
  - lib/xqsr3/quality.rb
47
50
  - lib/xqsr3/quality/parameter_checking.rb
48
51
  - lib/xqsr3/string_utilities/ends_with.rb
52
+ - lib/xqsr3/string_utilities/quote_if.rb
49
53
  - lib/xqsr3/string_utilities/starts_with.rb
50
54
  - lib/xqsr3/string_utilities/to_symbol.rb
51
55
  - lib/xqsr3/version.rb
@@ -59,12 +63,15 @@ files:
59
63
  - test/unit/extensions/enumerable/tc_collect_with_index.rb
60
64
  - test/unit/extensions/enumerable/tc_unique.rb
61
65
  - test/unit/extensions/enumerable/ts_all.rb
66
+ - test/unit/extensions/hash/tc_deep_transform.rb
67
+ - test/unit/extensions/hash/ts_all.rb
62
68
  - test/unit/extensions/io/tc_writelines.rb
63
69
  - test/unit/extensions/io/ts_all.rb
64
70
  - test/unit/extensions/kernel/tc_raise_with_options.rb
65
71
  - test/unit/extensions/kernel/ts_all.rb
66
72
  - test/unit/extensions/string/tc_ends_with.rb
67
73
  - test/unit/extensions/string/tc_map_option_string.rb
74
+ - test/unit/extensions/string/tc_quote_if.rb
68
75
  - test/unit/extensions/string/tc_starts_with.rb
69
76
  - test/unit/extensions/string/tc_to_symbol.rb
70
77
  - test/unit/extensions/string/ts_all.rb