sleeping_king_studios-tools 1.0.0 → 1.1.0

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
  SHA256:
3
- metadata.gz: b185f72aa8d793ad425987881f1a1df9a37f2a4d2778775258ffb01ee2ec6d20
4
- data.tar.gz: bdd496ed87a5fc539bdf25b33f7e9af22bb1f25a6f086b3fb29aad356591fb6a
3
+ metadata.gz: 1e0283e289b39463cacc292d923861867d3692aa582c11ea52e093d4a669db47
4
+ data.tar.gz: 6974c66896e0f0a0b9b464326529e8d093f1842d5242a289d559b6508b08f3b6
5
5
  SHA512:
6
- metadata.gz: e9a2cb6b86a351b4932119e60ac3f0688753183e3c6ae07ca485b105a80b0c64f7f3b75b94984b22add91b8b8ad7c1d83b4e54e57099c8f4d11d2acb1e7a2202
7
- data.tar.gz: 4e4ae31ab84ee0ad8e85d2397ec7af1085c6d2a16932ad24ca15fdbd35936f094673012672b457eeac2d76c17849a9ea19eeccb9deef58a7e86821aff9603fe0
6
+ metadata.gz: 207672541e0507cdb35887ef670cc300157c204ddf937ca21a7c1b0243cdde20d212c7daf76f2cd2c70d734f8676ef2e6c646d30f9304933be1db36126c9d2cb
7
+ data.tar.gz: 5177a4f97ffd28c60b8249f9a4c8a6eafea08dd5c8fe7833273b4274e1fbb59d48e12bcda042a40d2e7d91afb850ed9e583aeeb8f728eea64feeb30c7c9da95a
data/CHANGELOG.md CHANGED
@@ -1,15 +1,50 @@
1
1
  # Changelog
2
2
 
3
- ### 1.0.0
3
+ ## 1.1.0
4
4
 
5
- - Removed all deprecated code from pre-1.0 releases.
5
+ Files in the `Toolbox` are now autoloaded.
6
6
 
7
- #### Toolbox
7
+ ### Tools
8
+
9
+ Implemented `SleepingKingStudios::Tools::Assertions` with the following methods:
10
+
11
+ - `#assert`
12
+ - `#assert_boolean`
13
+ - `#assert_class`
14
+ - `#assert_instance_of`
15
+ - `#assert_matches`
16
+ - `#assert_name`
17
+
18
+ Each method raises an exception if its condition is not met. `Assertions` also defines equivalent `#validate` methods, which always raise an `ArgumentError`.
19
+
20
+ Added :deprecation_caller_depth option to CoreTools. When calling #deprecate with the default strategy of 'warn', will print the specified number of lines from the caller. The default value is 3.
21
+
22
+ ### Toolbelt
23
+
24
+ - Added `#assertions` to Toolbelt.
25
+
26
+ ### Toolbox
27
+
28
+ Implemented `SleepingKingStudios::Tools::Toolbox::Subclass`, which implements partial application for constructor parameters.
29
+
30
+ ## 1.0.2
31
+
32
+ Updated gem metadata.
33
+
34
+ ## 1.0.1
35
+
36
+ Added a missing `require 'set'` to Toolbox::Inflector::Rules.
37
+
38
+ ## 1.0.0
39
+
40
+ Removed all deprecated code from pre-1.0 releases.
41
+
42
+ ### Toolbox
8
43
 
9
44
  Added some Hash-like methods to ConstantMap - `#each_key`, `#each_value`,
10
45
  `#keys`, `#to_h`, and `#values`.
11
46
 
12
- ### 0.8.0
47
+ ## 0.8.0
13
48
 
14
49
  Last minor release before 1.0.0.
15
50
 
@@ -20,14 +55,14 @@ in version 1.0.0. Update dependent code accordingly.
20
55
  functionality is still available as
21
56
  SleepingKingStudios::Tools::Toolbox::SemanticVersion.
22
57
 
23
- #### Tools
58
+ ### Tools
24
59
 
25
60
  - Refactored all Tools modules to classes.
26
61
  - Removed StringTools::PluralInflector. It's functionality is now handled by
27
62
  Toolbox::Inflector.
28
63
  - Added support for deprecation strategy to CoreTools#deprecate.
29
64
 
30
- #### Toolbelt
65
+ ### Toolbelt
31
66
 
32
67
  - Refactored Toolbelt to reference Tools instances rather than classes.
33
68
  - Defined new abbreviated helpers #ary, #hsh, #int, #obj, #str.
@@ -36,36 +71,36 @@ in version 1.0.0. Update dependent code accordingly.
36
71
  - Deprecated old abbreviated helpers #array, #core, #hash, #integer, #object,
37
72
  #string.
38
73
 
39
- #### Toolbox
74
+ ### Toolbox
40
75
 
41
76
  - Deprecate Toolbox::Configuration. Use a struct instead.
42
77
  - Deprecate Toolbox::Delegator. Use the stdlib Forwardable module instead.
43
78
  - Implement Toolbox::Inflector, which serves as a delegate for StringTools.
44
79
 
45
- ### 0.7.1
80
+ ## 0.7.1
46
81
 
47
82
  - Implement CoreTools#empty_binding.
48
83
  - Implement HashTools#generate_binding.
49
84
 
50
- ### 0.7.0
85
+ ## 0.7.0
51
86
 
52
- #### Tools
87
+ ### Tools
53
88
 
54
89
  - Support symbol arguments to StringTools methods.
55
90
  - Implement StringTools#chain.
56
91
  - Implement StringTools#indent.
57
92
  - Implement StringTools#map_lines.
58
93
 
59
- #### Toolbox
94
+ ### Toolbox
60
95
 
61
96
  - Implement Toolbox::Configuration.
62
97
 
63
- #### Misc.
98
+ ### Misc.
64
99
 
65
100
  - IntegerTools#pluralize now accepts 2..3 arguments, and will automatically generate the plural string using StringTools#pluralize if an explicit plural is not given.
66
101
  - SleepingKingStudios::Tools::Toolbelt is now autoloaded from SleepingKingStudios::Tools.
67
102
 
68
- ### 0.6.0
103
+ ## 0.6.0
69
104
 
70
105
  - Implement HashTools#convert_keys_to_strings and #convert_keys_to_symbols.
71
106
  - Implement ObjectTools#dig.
@@ -75,69 +110,67 @@ in version 1.0.0. Update dependent code accordingly.
75
110
  - Implement Toolbox::Mixin.
76
111
  - Add support for Ruby 2.4.0.
77
112
 
78
- ### 0.5.0
113
+ ## 0.5.0
79
114
 
80
115
  - Implement CoreTools#require_each.
81
116
  - Implement StringTools#camelize.
82
117
  - Add an optional block argument to ArrayTools#humanize_list.
83
118
 
84
- #### Toolbox
119
+ ### Toolbox
85
120
 
86
121
  - Implement Delegator#delegate, Delegator#wrap_delegate.
87
122
  - Refactor SemanticVersion to the Toolbox namespace. Accessing SemanticVersion as Tools::SemanticVersion is now deprecated, use Tools::Toolbox::SemanticVersion.
88
123
 
89
- #### Identity Methods
124
+ ### Identity Methods
90
125
 
91
126
  - Implement a set of methods to classify objects by type: ArrayTools#array?, HashTools#hash?, IntegerTools#integer?, ObjectTools#object?, and StringTools#string?.
92
127
 
93
- #### Mutability Methods
128
+ ### Mutability Methods
94
129
 
95
130
  Implement #immutable? and #mutable? for ObjectTools, ArrayTools, and HashTools, which indicate whether or not a given object is mutable.
96
131
 
97
132
  Implement #deep_freeze for ObjectTools, ArrayTools, and HashTools which recursively freezes the object and any children (array items, hash keys, and hash values).
98
133
 
99
- ## Previous Releases
100
-
101
- ### 0.4.0
134
+ ## 0.4.0
102
135
 
103
- #### CoreTools
136
+ ### CoreTools
104
137
 
105
138
  Implement CoreTools#deprecate.
106
139
 
107
- #### IntegerTools
140
+ ### IntegerTools
108
141
 
109
142
  Implement #pluralize.
110
143
 
111
- #### StringTools
144
+ ### StringTools
112
145
 
113
146
  Implement #pluralize and #singularize. The previous behavior of #pluralize is deprecated; use IntegerTools#pluralize.
114
147
 
115
- ### 0.3.0
148
+ ## 0.3.0
116
149
 
117
150
  Implement ArrayTools#bisect and ArrayTools#splice.
118
151
 
119
- #### StringTools
152
+ ### StringTools
120
153
 
121
154
  Implement #underscore.
122
155
 
123
- ### 0.2.0
156
+ ## 0.2.0
124
157
 
125
158
  Split EnumerableTools into ArrayTools and HashTools.
126
159
 
127
160
  Implement ArrayTools#deep_dup, HashTools#deep_dup and ObjectTools#deep_dup.
128
161
 
129
- ### 0.1.3
162
+ ## 0.1.3
130
163
 
131
164
  Properly support both keywords and optional arguments in ObjectTools#apply.
132
165
 
133
- ### 0.1.2
166
+ ## 0.1.2
134
167
 
135
168
  Fix loading order issues when loading SemanticVersion in isolation.
136
169
 
137
- ### 0.1.1
170
+ ## 0.1.1
138
171
 
139
172
  Add configuration options to EnumerableTools#humanize_list.
140
173
 
141
- ### 0.1.0
174
+ ## 0.1.0
142
175
 
143
176
  Initial release.
data/README.md CHANGED
@@ -4,7 +4,7 @@ A library of utility services and concerns to expand the functionality of core c
4
4
 
5
5
  ## About
6
6
 
7
- SleepingKingStudios::Tools is tested against MRI Ruby 2.5 through 3.0.
7
+ SleepingKingStudios::Tools is tested against MRI Ruby 2.6 through 3.1.
8
8
 
9
9
  ### Documentation
10
10
 
@@ -30,18 +30,20 @@ Please note that the `SleepingKingStudios::Tools` project is released with a [Co
30
30
 
31
31
  The tools can be accessed in a convenient form using the Toolbelt class.
32
32
 
33
- require 'sleeping_king_studios/tools'
33
+ ```ruby
34
+ require 'sleeping_king_studios/tools'
34
35
 
35
- tools = ::SleepingKingStudios::Tools::Toolbelt.instance
36
+ tools = ::SleepingKingStudios::Tools::Toolbelt.instance
36
37
 
37
- tools.array.humanize_list 'one', 'two', 'three'
38
- #=> calls ArrayTools#humanize_list
38
+ tools.ary.humanize_list 'one', 'two', 'three'
39
+ #=> calls ArrayTools#humanize_list
39
40
 
40
- tools.core.deprecate 'my_method'
41
- #=> calls CoreTools#deprecate
41
+ tools.core.deprecate 'my_method'
42
+ #=> calls CoreTools#deprecate
42
43
 
43
- tools.string.underscore 'MyModuleName'
44
- #=> calls StringTools#underscore
44
+ tools.str.underscore 'MyModuleName'
45
+ #=> calls StringTools#underscore
46
+ ```
45
47
 
46
48
  ### Array Tools
47
49
 
@@ -181,6 +183,256 @@ Accepts an array, a start value, a number of items to delete, and zero or more i
181
183
  values
182
184
  #=> ['shortbow', 'longbow', 'arbalest', 'chu-ko-nu']
183
185
 
186
+ ### Assertions
187
+
188
+ Tools for validating the current application state.
189
+
190
+ #### `#assert`
191
+
192
+ Raises an exception unless the given block returns a truthy value.
193
+
194
+ ```ruby
195
+ Assertions.assert { true == false }
196
+ #=> raises an AssertionError with message 'block returned a falsy value'
197
+
198
+ Assertions.assert { true == true }
199
+ #=> does not raise an exception
200
+ ```
201
+
202
+ It accepts the following options:
203
+
204
+ - `error_class:` The class of exception to raise. Defaults to `SleepingKingStudios::Tools::Assertions::AssertionError`.
205
+ - `message`: The error message to display.
206
+
207
+ #### `#assert_boolean`
208
+
209
+ Raises an exception unless the given value is either `true` or `false`.
210
+
211
+ ```ruby
212
+ Assertions.assert_boolean(nil)
213
+ #=> raises an AssertionError with message 'value must be true or false'
214
+
215
+ Assertions.assert_boolean(Object.new)
216
+ #=> raises an AssertionError with message 'value must be true or false'
217
+
218
+ Assertions.assert_boolean(false)
219
+ #=> does not raise an exception
220
+
221
+ Assertions.assert_boolean(true)
222
+ #=> does not raise an exception
223
+ ```
224
+
225
+ It accepts the following options:
226
+
227
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
228
+ - `error_class:` The class of exception to raise. Defaults to `SleepingKingStudios::Tools::Assertions::AssertionError`.
229
+ - `message`: The error message to display.
230
+
231
+ #### `#assert_class`
232
+
233
+ Raises an exception unless the given value is a Class.
234
+
235
+ ```ruby
236
+ Assertions.assert_class(Object.new)
237
+ #=> raises an AssertionError with message 'value is not a class'
238
+
239
+ Assertions.assert_class(String)
240
+ #=> does not raise an exception
241
+ ```
242
+
243
+ It accepts the following options:
244
+
245
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
246
+ - `error_class:` The class of exception to raise. Defaults to `SleepingKingStudios::Tools::Assertions::AssertionError`.
247
+ - `message`: The error message to display.
248
+
249
+ #### `#assert_instance_of`
250
+
251
+ Raises an exception unless the given value is an instance of the expected Class or Module.
252
+
253
+ ```ruby
254
+ Assertions.assert_instance_of(:foo, expected: String)
255
+ #=> raises an AssertionError with message 'value is not an instance of String'
256
+
257
+ Assertions.assert_instance_of('foo', expected: String)
258
+ #=> does not raise an exception
259
+ ```
260
+
261
+ It accepts the following options:
262
+
263
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
264
+ - `error_class:` The class of exception to raise. Defaults to `SleepingKingStudios::Tools::Assertions::AssertionError`.
265
+ - `message`: The error message to display.
266
+ - `optional`: If true, accepts `nil` values as well as instances of the Class or Module.
267
+
268
+ #### `#assert_matches`
269
+
270
+ Raises an exception unless the given value matches the expected value using case equality (`#===`).
271
+
272
+
273
+ ```ruby
274
+ Assertions.assert_matches('bar', expected: /foo/)
275
+ #=> raises an AssertionError with message 'value does not match the pattern /foo/'
276
+
277
+ Assertions.assert_matches('foo', expected: /foo/)
278
+ #=> does not raise an exception
279
+ ```
280
+
281
+ It accepts the following options:
282
+
283
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
284
+ - `error_class:` The class of exception to raise. Defaults to `SleepingKingStudios::Tools::Assertions::AssertionError`.
285
+ - `message`: The error message to display.
286
+ - `optional`: If true, accepts `nil` values as well as matching values.
287
+
288
+ #### `#assert_name`
289
+
290
+ Raises an exception unless the given value is non-empty a String or Symbol.
291
+
292
+ ```ruby
293
+ Assertions.assert_name(nil)
294
+ #=> raises an AssertionError with message "value can't be blank"
295
+
296
+ Assertions.assert_name(Object.new)
297
+ #=> raises an AssertionError with message 'value is not a String or a Symbol'
298
+
299
+ Assertions.assert_name('')
300
+ #=> raises an AssertionError with message "value can't be blank"
301
+
302
+ Assertions.assert_name('foo')
303
+ #=> does not raise an exception
304
+
305
+ Assertions.assert_name(:bar)
306
+ #=> does not raise an exception
307
+ ```
308
+
309
+ It accepts the following options:
310
+
311
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
312
+ - `error_class:` The class of exception to raise. Defaults to `SleepingKingStudios::Tools::Assertions::AssertionError`.
313
+ - `message`: The error message to display.
314
+ - `optional`: If true, accepts `nil` values as well as valid Symbols and Strings.
315
+
316
+ #### `#validate`
317
+
318
+ Raises an `ArgumentError` unless the given block returns a truthy value.
319
+
320
+ ```ruby
321
+ Assertions.validate { true == false }
322
+ #=> raises an ArgumentError with message 'block returned a falsy value'
323
+
324
+ Assertions.validate { true == true }
325
+ #=> does not raise an exception
326
+ ```
327
+
328
+ It accepts the following options:
329
+
330
+ - `message`: The error message to display.
331
+
332
+ #### `#validate_boolean`
333
+
334
+ Raises an exception unless the given value is either `true` or `false`.
335
+
336
+ ```ruby
337
+ Assertions.validate_boolean(nil)
338
+ #=> raises an ArgumentError with message 'value must be true or false'
339
+
340
+ Assertions.validate_boolean(Object.new)
341
+ #=> raises an ArgumentError with message 'value must be true or false'
342
+
343
+ Assertions.validate_boolean(false)
344
+ #=> does not raise an exception
345
+
346
+ Assertions.validate_boolean(true)
347
+ #=> does not raise an exception
348
+ ```
349
+
350
+ It accepts the following options:
351
+
352
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
353
+ - `message`: The error message to display.
354
+
355
+ #### `#validate_class`
356
+
357
+ Raises an `ArgumentError` unless the given value is a Class.
358
+
359
+ ```ruby
360
+ Assertions.validate_class(Object.new)
361
+ #=> raises an ArgumentError with message 'value is not a class'
362
+
363
+ Assertions.validate_class(String)
364
+ #=> does not raise an exception
365
+ ```
366
+
367
+ It accepts the following options:
368
+
369
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
370
+ - `message`: The error message to display.
371
+
372
+ #### `#validate_instance_of`
373
+
374
+ Raises an `ArgumentError` unless the given value is an instance of the expected Class or Module.
375
+
376
+ ```ruby
377
+ Assertions.validate_instance_of(:foo, expected: String)
378
+ #=> raises an AssertionError with message 'value is not an instance of String'
379
+
380
+ Assertions.validate_instance_of('foo', expected: String)
381
+ #=> does not raise an exception
382
+ ```
383
+
384
+ It accepts the following options:
385
+
386
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
387
+ - `message`: The error message to display.
388
+ - `optional`: If true, accepts `nil` values as well as instances of the Class or Module.
389
+
390
+ #### `#validate_matches`
391
+
392
+ Raises an `ArgumentError` unless the given value matches the expected value using case equality (`#===`).
393
+
394
+
395
+ ```ruby
396
+ Assertions.validate_matches('bar', expected: /foo/)
397
+ #=> raises an ArgumentError with message 'value does not match the pattern /foo/'
398
+
399
+ Assertions.validate_matches('foo', expected: /foo/)
400
+ #=> does not raise an exception
401
+ ```
402
+
403
+ It accepts the following options:
404
+
405
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
406
+ - `message`: The error message to display.
407
+ - `optional`: If true, accepts `nil` values as well as matching values.
408
+
409
+ #### `#validate_name`
410
+
411
+ Raises an `ArgumentError` unless the given value is non-empty a String or Symbol.
412
+
413
+ ```ruby
414
+ Assertions.validate_name(nil)
415
+ #=> raises an ArgumentError with message "value can't be blank"
416
+
417
+ Assertions.validate_name(Object.new)
418
+ #=> raises an AssertionError with message 'value is not a String or a Symbol'
419
+
420
+ Assertions.validate_name('')
421
+ #=> raises an ArgumentError with message "value can't be blank"
422
+
423
+ Assertions.validate_name('foo')
424
+ #=> does not raise an exception
425
+
426
+ Assertions.validate_name(:bar)
427
+ #=> does not raise an exception
428
+ ```
429
+
430
+ It accepts the following options:
431
+
432
+ - `as:` A short descriptor of the given value. Defaults to `"value"`.
433
+ - `message`: The error message to display.
434
+ - `optional`: If true, accepts `nil` values as well as valid Symbols and Strings.
435
+
184
436
  ### Core Tools
185
437
 
186
438
  Tools for working with an application or working environment.
@@ -189,17 +441,40 @@ Tools for working with an application or working environment.
189
441
 
190
442
  Prints a deprecation warning.
191
443
 
192
- CoreTools.deprecate 'ObjectTools#old_method'
193
- #=> prints to stderr:
194
-
195
- [WARNING] ObjectTools#old_method is deprecated.
196
- called from /path/to/file.rb:4: in something_or_other
197
-
198
- CoreTools.deprecate 'ObjectTools#old_method', '0.1.0', :format => '%s was deprecated in version %s.'
199
- #=> prints to stderr:
200
-
201
- ObjectTools#old_method was deprecated in version 0.1.0.
202
- called from /path/to/file.rb:4: in something_or_other
444
+ ```ruby
445
+ CoreTools.deprecate 'ObjectTools#old_method'
446
+ #=> prints to stderr:
447
+ #
448
+ # [WARNING] ObjectTools#old_method is deprecated.
449
+ # called from /path/to/file.rb:4: in something_or_other
450
+ ```
451
+
452
+ You can also specify an additional message to display:
453
+
454
+ ```ruby
455
+ CoreTools.deprecate 'ObjectTools#old_method',
456
+ 'Use #new_method instead.'
457
+ #=> prints to stderr:
458
+ #
459
+ # [WARNING] ObjectTools#old_method is deprecated. Use #new_method instead.
460
+ # called from /path/to/file.rb:4: in something_or_other
461
+ ```
462
+
463
+ You can specify a custom format for the deprecation message:
464
+
465
+ ```ruby
466
+ CoreTools.deprecate 'ObjectTools#old_method',
467
+ '0.1.0',
468
+ format: '%s was deprecated in version %s.'
469
+ #=> prints to stderr:
470
+ #
471
+ # ObjectTools#old_method was deprecated in version 0.1.0.
472
+ # called from /path/to/file.rb:4: in something_or_other
473
+ ```
474
+
475
+ By default, `#deprecate` will print the last 3 lines of the caller, excluding
476
+ any lines from `Forwardable` and from `SleepingKingStudios::Tools` itself. To
477
+ print a different number of lines, pass a custom `deprecation_caller_depth` parameter to `CoreTools.new` or set the `DEPRECATION_CALLER_DEPTH` environment variable.
203
478
 
204
479
  #### `#empty_binding`
205
480
 
@@ -825,3 +1100,102 @@ Concatenates the MAJOR, MINOR, and PATCH constant values with PRERELEASE and BUI
825
1100
  #### `#to_version`
826
1101
 
827
1102
  Concatenates the MAJOR, MINOR, and PATCH constant values with PRERELEASE and BUILD (if available) to generate a semantic version string. The major, minor, and patch values are separated by dots `.`, then the prerelease (if available) preceded by a hyphen `-`, and the build (if available) preceded by a plus sign `+`.
1103
+
1104
+ ### Subclass
1105
+
1106
+ ```ruby
1107
+ require 'sleeping_king_studios/tools/toolbox/subclass'
1108
+ ```
1109
+
1110
+ The `Subclass` module provides a mechanism for performing partial application (or "currying") of constructor parameters. This is useful for defining subclasses that inject pre-defined values into the constructor.
1111
+
1112
+ Let's consider an example. We'll start by defining a base class.
1113
+
1114
+ ```ruby
1115
+ class Query
1116
+ extend SleepingKingStudios::Tools::Toolbox::Subclass
1117
+
1118
+ def initialize(entity_class, **options)
1119
+ @entity_class = entity_class
1120
+ @options = options
1121
+ end
1122
+
1123
+ attr_reader :entity_class
1124
+
1125
+ attr_reader :options
1126
+
1127
+ def call
1128
+ # Querying logic here.
1129
+ end
1130
+ end
1131
+
1132
+ query = Query.new(Book, limit: 10)
1133
+ query.entity_class
1134
+ #=> Book
1135
+ query.options
1136
+ #=> { limit: 10 }
1137
+ ```
1138
+
1139
+ Our `Query` class is used to perform queries on some data source - a relational table, an API, or some in-memory data structure. To perform a query, we need to know what data to request. This is represented by the `:entity_class` argument. Additionally, we can pass arbitrary `:options` as keywords.
1140
+
1141
+ ```ruby
1142
+ BooksQuery = Query.subclass(Book)
1143
+
1144
+ query = BooksQuery.new(order: :title)
1145
+ query.entity_class
1146
+ #=> Book
1147
+ query.options
1148
+ #=> { order: :title }
1149
+ ```
1150
+
1151
+ By calling `.subclass` on our `Query` class, we are defining a new subclass of `Query` that injects the given parameters and partially applies them to the constructor. In this case, we are injecting the `Book` class into our query.
1152
+
1153
+ We can also use `.subclass` to partially apply keywords or a block.
1154
+
1155
+ ```ruby
1156
+ RecentItemsQuery = Query.subclass(order: { created_at: :desc })
1157
+
1158
+ query = RecentItemsQuery.new(Book)
1159
+ query.entity_class
1160
+ #=> Book
1161
+ query.options
1162
+ #=> { order: { created_at: :desc } }
1163
+ ```
1164
+
1165
+ When you call the subclass's constructor with additional parameters, they are applied in addition to the configured values (if any).
1166
+
1167
+ - Any arguments passed to `.new` are added *after* the configured arguments.
1168
+ - Any keywords passed to `.new` are merged into the configured keywords, with the values passed to `.new` taking precedence.
1169
+ - A block passed to `.new` will take precedence over a configured block.
1170
+
1171
+ ```ruby
1172
+ class Character
1173
+ extend SleepingKingStudios::Tools::Toolbox::Subclass
1174
+
1175
+ def initialize(*traits, **stats, &special)
1176
+ @traits = traits
1177
+ @stats = stats
1178
+ @special = special
1179
+ end
1180
+
1181
+ attr_reader :special
1182
+
1183
+ attr_reader :stats
1184
+
1185
+ attr_reader :traits
1186
+ end
1187
+
1188
+ Bard = Character.subclass(:musical, performance: 5, persuasion: 10) do
1189
+ 'The bard sings a cheerful tune.'
1190
+ end
1191
+
1192
+ aoife = Bard.new(:sorcerous, magic: 5, performance: 10) do
1193
+ 'Aoife drops her lute!'
1194
+ end
1195
+ aoife.traits
1196
+ #=> [:musical, :sorcerous]
1197
+ aoife.stats
1198
+ #=> { magic: 5, performance: 10, persuasion: 10 }
1199
+ aoife.special.call
1200
+ #=> 'Aoife drops her lute!'
1201
+ ```
@@ -302,7 +302,7 @@ module SleepingKingStudios::Tools
302
302
  def require_array!(value)
303
303
  return if array?(value)
304
304
 
305
- raise ArgumentError, 'argument must be an array', caller[1..-1]
305
+ raise ArgumentError, 'argument must be an array', caller[1..]
306
306
  end
307
307
  end
308
308
  end
@@ -0,0 +1,322 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sleeping_king_studios/tools'
4
+
5
+ module SleepingKingStudios::Tools
6
+ # Methods for asserting on the state of a function or application.
7
+ class Assertions < Base # rubocop:disable Metrics/ClassLength
8
+ # Error class for handling a failed assertion.
9
+ class AssertionError < StandardError; end
10
+
11
+ # Asserts that the block returns a truthy value.
12
+ #
13
+ # @param error_class [Class] The exception class to raise on a failure.
14
+ # @param message [String] The exception message to raise on a failure.
15
+ #
16
+ # @yield The block to evaluate.
17
+ # @yieldreturn [Object] The returned value of the block.
18
+ #
19
+ # @raise AssertionError if the block does not return a truthy value.
20
+ def assert(error_class: AssertionError, message: nil, &block)
21
+ return if block.call
22
+
23
+ raise error_class,
24
+ message || 'block returned a falsy value',
25
+ caller(1..-1)
26
+ end
27
+
28
+ # Asserts that the value is either true or false.
29
+ #
30
+ # @param value [Object] The value to assert on.
31
+ # @param as [String] The name of the asserted value.
32
+ # @param error_class [Class] The exception class to raise on a failure.
33
+ # @param message [String] The exception message to raise on a failure.
34
+ #
35
+ # @raise AssertionError if the value is not a Class.
36
+ def assert_boolean(
37
+ value,
38
+ as: 'value',
39
+ error_class: AssertionError,
40
+ message: nil
41
+ )
42
+ return if value.equal?(true) || value.equal?(false)
43
+
44
+ raise error_class,
45
+ message || "#{as} must be true or false",
46
+ caller(1..-1)
47
+ end
48
+
49
+ # Asserts that the value is a Class.
50
+ #
51
+ # @param value [Object] The value to assert on.
52
+ # @param as [String] The name of the asserted value.
53
+ # @param error_class [Class] The exception class to raise on a failure.
54
+ # @param message [String] The exception message to raise on a failure.
55
+ #
56
+ # @raise AssertionError if the value is not a Class.
57
+ def assert_class(
58
+ value,
59
+ as: 'value',
60
+ error_class: AssertionError,
61
+ message: nil
62
+ )
63
+ return if value.is_a?(Class)
64
+
65
+ raise error_class,
66
+ message || "#{as} is not a Class",
67
+ caller(1..-1)
68
+ end
69
+
70
+ # Asserts that the value is an example of the given Class.
71
+ #
72
+ # @param value [Object] The value to assert on.
73
+ # @param as [String] The name of the asserted value.
74
+ # @param error_class [Class] The exception class to raise on a failure.
75
+ # @param expected [Class] The expected class.
76
+ # @param message [String] The exception message to raise on a failure.
77
+ # @param optional [true, false] If true, allows nil values.
78
+ #
79
+ # @raise ArgumentError if the expected class is not a Class.
80
+ # @raise AssertionError if the value is not an instance of the expected
81
+ # class.
82
+ def assert_instance_of( # rubocop:disable Metrics/ParameterLists
83
+ value,
84
+ expected:,
85
+ as: 'value',
86
+ error_class: AssertionError,
87
+ message: nil,
88
+ optional: false
89
+ )
90
+ unless expected.is_a?(Class)
91
+ raise ArgumentError, 'expected must be a Class'
92
+ end
93
+
94
+ return if optional && value.nil?
95
+ return if value.is_a?(expected)
96
+
97
+ raise error_class,
98
+ message || "#{as} is not an instance of #{class_name(expected)}",
99
+ caller(1..-1)
100
+ end
101
+
102
+ # Asserts that the value matches the expected object using #===.
103
+ #
104
+ # @param value [Object] The value to assert on.
105
+ # @param as [String] The name of the asserted value.
106
+ # @param error_class [Class] The exception class to raise on a failure.
107
+ # @param expected [#===] The expected object.
108
+ # @param message [String] The exception message to raise on a failure.
109
+ # @param optional [true, false] If true, allows nil values.
110
+ #
111
+ # @raise AssertionError if the value does not match the expected object.
112
+ def assert_matches( # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/ParameterLists
113
+ value,
114
+ expected:,
115
+ as: 'value',
116
+ error_class: AssertionError,
117
+ message: nil,
118
+ optional: false
119
+ )
120
+ return if optional && value.nil?
121
+ return if expected === value # rubocop:disable Style/CaseEquality
122
+
123
+ message ||=
124
+ case expected
125
+ when Module
126
+ "#{as} is not an instance of #{class_name(expected)}"
127
+ when Proc
128
+ "#{as} does not match the Proc"
129
+ when Regexp
130
+ "#{as} does not match the pattern #{expected.inspect}"
131
+ else
132
+ "#{as} does not match the expected value"
133
+ end
134
+
135
+ raise error_class, message, caller(1..-1)
136
+ end
137
+
138
+ # Asserts that the value is a non-empty String or Symbol.
139
+ #
140
+ # @param value [Object] The value to assert on.
141
+ # @param as [String] The name of the asserted value.
142
+ # @param error_class [Class] The exception class to raise on a failure.
143
+ # @param message [String] The exception message to raise on a failure.
144
+ # @param optional [true, false] If true, allows nil values.
145
+ #
146
+ # @raise AssertionError if the value is not a String or a Symbol, or if the
147
+ # value is empty.
148
+ def assert_name( # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
149
+ value,
150
+ as: 'value',
151
+ error_class: AssertionError,
152
+ message: nil,
153
+ optional: false
154
+ )
155
+ if value.nil?
156
+ return if optional
157
+
158
+ raise error_class, message || "#{as} can't be blank", caller(1..-1)
159
+ end
160
+
161
+ unless value.is_a?(String) || value.is_a?(Symbol)
162
+ raise error_class,
163
+ message || "#{as} is not a String or a Symbol",
164
+ caller(1..-1)
165
+ end
166
+
167
+ return unless value.empty?
168
+
169
+ raise error_class, message || "#{as} can't be blank", caller(1..-1)
170
+ end
171
+
172
+ # Asserts that the block returns a truthy value.
173
+ #
174
+ # @param message [String] The exception message to raise on a failure.
175
+ #
176
+ # @yield The block to evaluate.
177
+ # @yieldreturn [Object] The returned value of the block.
178
+ #
179
+ # @raise ArgumentError if the block does not return a truthy value.
180
+ def validate(message: nil, &block)
181
+ return if block.call
182
+
183
+ raise ArgumentError,
184
+ message || 'block returned a falsy value',
185
+ caller(1..-1)
186
+ end
187
+
188
+ # Asserts that the value is either true or false.
189
+ #
190
+ # @param value [Object] The value to assert on.
191
+ # @param as [String] The name of the asserted value.
192
+ # @param message [String] The exception message to raise on a failure.
193
+ #
194
+ # @raise AssertionError if the value is not a Class.
195
+ def validate_boolean(value, as: 'value', message: nil)
196
+ return if value.equal?(true) || value.equal?(false)
197
+
198
+ raise ArgumentError,
199
+ message || "#{as} must be true or false",
200
+ caller(1..-1)
201
+ end
202
+
203
+ # Asserts that the value is a Class.
204
+ #
205
+ # @param value [Object] The value to assert on.
206
+ # @param as [String] The name of the asserted value.
207
+ # @param message [String] The exception message to raise on a failure.
208
+ #
209
+ # @raise ArgumentError if the value is not a Class.
210
+ def validate_class(value, as: 'value', message: nil)
211
+ return if value.is_a?(Class)
212
+
213
+ raise ArgumentError,
214
+ message || "#{as} is not a Class",
215
+ caller(1..-1)
216
+ end
217
+
218
+ # Asserts that the value is an example of the given Class.
219
+ #
220
+ # @param value [Object] The value to assert on.
221
+ # @param as [String] The name of the asserted value.
222
+ # @param expected [Class] The expected class.
223
+ # @param message [String] The exception message to raise on a failure.
224
+ # @param optional [true, false] If true, allows nil values.
225
+ #
226
+ # @raise ArgumentError if the expected class is not a Class.
227
+ # @raise AssertionError if the value is not an instance of the expected
228
+ # class.
229
+ def validate_instance_of(
230
+ value,
231
+ expected:,
232
+ as: 'value',
233
+ message: nil,
234
+ optional: false
235
+ )
236
+ unless expected.is_a?(Class)
237
+ raise ArgumentError, 'expected must be a Class'
238
+ end
239
+
240
+ return if optional && value.nil?
241
+ return if value.is_a?(expected)
242
+
243
+ raise ArgumentError,
244
+ message || "#{as} is not an instance of #{class_name(expected)}",
245
+ caller(1..-1)
246
+ end
247
+
248
+ # Asserts that the value matches the expected object using #===.
249
+ #
250
+ # @param value [Object] The value to assert on.
251
+ # @param as [String] The name of the asserted value.
252
+ # @param expected [#===] The expected object.
253
+ # @param message [String] The exception message to raise on a failure.
254
+ # @param optional [true, false] If true, allows nil values.
255
+ #
256
+ # @raise ArgumentError if the value does not match the expected object.
257
+ def validate_matches( # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
258
+ value,
259
+ expected:,
260
+ as: 'value',
261
+ message: nil,
262
+ optional: false
263
+ )
264
+ return if optional && value.nil?
265
+ return if expected === value # rubocop:disable Style/CaseEquality
266
+
267
+ message ||=
268
+ case expected
269
+ when Module
270
+ "#{as} is not an instance of #{class_name(expected)}"
271
+ when Proc
272
+ "#{as} does not match the Proc"
273
+ when Regexp
274
+ "#{as} does not match the pattern #{expected.inspect}"
275
+ else
276
+ "#{as} does not match the expected value"
277
+ end
278
+
279
+ raise ArgumentError, message, caller(1..-1)
280
+ end
281
+
282
+ # Asserts that the value is a non-empty String or Symbol.
283
+ #
284
+ # @param value [Object] The value to assert on.
285
+ # @param as [String] The name of the asserted value.
286
+ # @param message [String] The exception message to raise on a failure.
287
+ # @param optional [true, false] If true, allows nil values.
288
+ #
289
+ # @raise ArgumentError if the value is not a String or a Symbol, or if the
290
+ # value is empty.
291
+ def validate_name( # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
292
+ value,
293
+ as: 'value',
294
+ message: nil,
295
+ optional: false
296
+ )
297
+ if value.nil?
298
+ return if optional
299
+
300
+ raise ArgumentError, message || "#{as} can't be blank", caller(1..-1)
301
+ end
302
+
303
+ unless value.is_a?(String) || value.is_a?(Symbol)
304
+ raise ArgumentError,
305
+ message || "#{as} is not a String or a Symbol",
306
+ caller(1..-1)
307
+ end
308
+
309
+ return unless value.empty?
310
+
311
+ raise ArgumentError, message || "#{as} can't be blank", caller(1..-1)
312
+ end
313
+
314
+ private
315
+
316
+ def class_name(expected)
317
+ return expected.name if expected.name
318
+
319
+ "#{expected.inspect} (#{expected.ancestors.find(&:name).name})"
320
+ end
321
+ end
322
+ end
@@ -16,16 +16,28 @@ module SleepingKingStudios::Tools
16
16
  :require_each
17
17
  end
18
18
 
19
+ # @param deprecation_caller_depth [Integer] The number of backtrace lines to
20
+ # display when outputting a deprecation warning.
19
21
  # @param deprecation_strategy [String] The name of the strategy used when
20
22
  # deprecated code is called. Must be 'ignore', 'raise', or 'warn'.
21
- def initialize(deprecation_strategy: nil)
23
+ def initialize(
24
+ deprecation_caller_depth: nil,
25
+ deprecation_strategy: nil
26
+ )
22
27
  super()
23
28
 
29
+ @deprecation_caller_depth =
30
+ deprecation_caller_depth ||
31
+ ENV.fetch('DEPRECATION_CALLER_DEPTH', '3').to_i
24
32
  @deprecation_strategy =
25
33
  deprecation_strategy || ENV.fetch('DEPRECATION_STRATEGY', 'warn')
26
34
  end
27
35
 
28
- # @return [String] The current deprecation strategy.
36
+ # @return [Integer] the number of backtrace lines to display when outputting
37
+ # a deprecation warning.
38
+ attr_reader :deprecation_caller_depth
39
+
40
+ # @return [String] the current deprecation strategy.
29
41
  attr_reader :deprecation_strategy
30
42
 
31
43
  # @overload deprecate(name, message: nil)
@@ -92,19 +104,21 @@ module SleepingKingStudios::Tools
92
104
 
93
105
  str = format % args
94
106
  str << ' ' << message if message
95
-
96
- str << "\n called from #{external_caller}"
107
+ str << format_caller
97
108
 
98
109
  Kernel.warn str
99
110
  end
100
111
 
101
- def external_caller
102
- caller.find do |line|
103
- !(
104
- line.include?('forwardable.rb') ||
105
- line.include?('sleeping_king_studios-tools')
106
- )
112
+ def format_caller
113
+ lines = caller
114
+ start = lines.find_index do |line|
115
+ !line.include?('forwardable.rb') &&
116
+ !line.include?('sleeping_king_studios-tools')
107
117
  end
118
+
119
+ lines[start...(start + deprecation_caller_depth)]
120
+ .map { |line| "\n called from #{line}" }
121
+ .join
108
122
  end
109
123
  end
110
124
  end
@@ -168,7 +168,7 @@ module SleepingKingStudios::Tools
168
168
  def require_hash!(value)
169
169
  return if hash?(value)
170
170
 
171
- raise ArgumentError, 'argument must be a hash', caller[1..-1]
171
+ raise ArgumentError, 'argument must be a hash', caller[1..]
172
172
  end
173
173
  end
174
174
  end
@@ -108,7 +108,7 @@ module SleepingKingStudios::Tools
108
108
  # @return [Array<String>] The digits of the decomposed integer,
109
109
  # represented as a bigendian array of strings.
110
110
  def digits(integer, base: 10)
111
- integer.to_s(base).split('')
111
+ integer.to_s(base).chars
112
112
  end
113
113
 
114
114
  # Returns true if the object is an Integer.
@@ -177,8 +177,8 @@ module SleepingKingStudios::Tools
177
177
  return if (ROMANIZE_MIN..ROMANIZE_MAX).include?(integer)
178
178
 
179
179
  error_message =
180
- "integer to romanize must be within range #{ROMANIZE_MIN} to" \
181
- " #{ROMANIZE_MAX}"
180
+ "integer to romanize must be within range #{ROMANIZE_MIN} to " \
181
+ "#{ROMANIZE_MAX}"
182
182
 
183
183
  raise RangeError, error_message, caller(1..-1)
184
184
  end
@@ -167,7 +167,7 @@ module SleepingKingStudios::Tools
167
167
 
168
168
  return value.to_s if value.is_a?(Symbol)
169
169
 
170
- raise ArgumentError, 'argument must be a string', caller[1..-1]
170
+ raise ArgumentError, 'argument must be a string', caller[1..]
171
171
  end
172
172
  end
173
173
  end
@@ -18,6 +18,7 @@ module SleepingKingStudios::Tools
18
18
  # ActiveSupport::Inflector .
19
19
  def initialize(deprecation_strategy: nil, inflector: nil)
20
20
  @array_tools = ::SleepingKingStudios::Tools::ArrayTools.new
21
+ @assertions = ::SleepingKingStudios::Tools::Assertions.new
21
22
  @core_tools = ::SleepingKingStudios::Tools::CoreTools.new(
22
23
  deprecation_strategy: deprecation_strategy
23
24
  )
@@ -30,6 +31,8 @@ module SleepingKingStudios::Tools
30
31
 
31
32
  attr_reader :array_tools
32
33
 
34
+ attr_reader :assertions
35
+
33
36
  attr_reader :core_tools
34
37
 
35
38
  attr_reader :hash_tools
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
4
+
3
5
  require 'sleeping_king_studios/tools/toolbox'
4
6
 
5
7
  class SleepingKingStudios::Tools::Toolbox::Inflector
@@ -47,7 +47,7 @@ module SleepingKingStudios::Tools::Toolbox
47
47
 
48
48
  word = word.to_s.gsub(/(\b|[_-])([a-z])/) { Regexp.last_match(2).upcase }
49
49
 
50
- (uppercase_first_letter ? word[0].upcase : word[0].downcase) + word[1..-1]
50
+ (uppercase_first_letter ? word[0].upcase : word[0].downcase) + word[1..]
51
51
  end
52
52
 
53
53
  # rubocop:disable Metrics/AbcSize
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sleeping_king_studios/tools/toolbox'
4
+
5
+ module SleepingKingStudios::Tools::Toolbox
6
+ # Mixin for partially applying constructor parameters.
7
+ #
8
+ # @example
9
+ # class Character
10
+ # extend SleepingKingStudios::Tools::Toolbox::Subclass
11
+ #
12
+ # def initialize(*traits)
13
+ # @traits = traits
14
+ # end
15
+ #
16
+ # attr_reader :traits
17
+ # end
18
+ #
19
+ # Bard = Character.subclass(:charismatic, :musical)
20
+ #
21
+ # aoife = Bard.new(:sorcerous)
22
+ # aoife.traits
23
+ # #=> [:charismatic, :musical, :sorcerous]
24
+ module Subclass
25
+ # Creates a subclass with partially applied constructor parameters.
26
+ #
27
+ # @param class_arguments [Array] The arguments, if any, to apply to the
28
+ # constructor. These arguments will be added before any args passed
29
+ # directly to the constructor.
30
+ # @param class_keywords [Hash] The keywords, if any, to apply to the
31
+ # constructor. These keywords will be added before any kwargs passed
32
+ # directly to the constructor.
33
+ #
34
+ # @yield The block, if any, to pass to the constructor. This will be
35
+ # overriden by a block passed directly to the constructor.
36
+ #
37
+ # @return [Class] the generated subclass.
38
+ def subclass(*class_arguments, **class_keywords, &class_block) # rubocop:disable Metrics/MethodLength
39
+ subclass = Class.new(self)
40
+
41
+ subclass.define_method :initialize do |*args, **kwargs, &block|
42
+ super(
43
+ *class_arguments,
44
+ *args,
45
+ **class_keywords,
46
+ **kwargs,
47
+ &(block || class_block)
48
+ )
49
+ end
50
+
51
+ subclass
52
+ end
53
+ end
54
+ end
@@ -6,5 +6,16 @@ module SleepingKingStudios::Tools
6
6
  # Namespace for common objects or patterns that are useful across projects but
7
7
  # are larger than or do not fit the functional paradigm of the tools.*
8
8
  # pattern.
9
- module Toolbox; end
9
+ module Toolbox
10
+ autoload :ConstantMap,
11
+ 'sleeping_king_studios/tools/toolbox/constant_map'
12
+ autoload :Inflector,
13
+ 'sleeping_king_studios/tools/toolbox/inflector'
14
+ autoload :Mixin,
15
+ 'sleeping_king_studios/tools/toolbox/mixin'
16
+ autoload :SemanticVersion,
17
+ 'sleeping_king_studios/tools/toolbox/semantic_version'
18
+ autoload :Subclass,
19
+ 'sleeping_king_studios/tools/toolbox/subclass'
20
+ end
10
21
  end
@@ -13,7 +13,7 @@ module SleepingKingStudios
13
13
  # Major version.
14
14
  MAJOR = 1
15
15
  # Minor version.
16
- MINOR = 0
16
+ MINOR = 1
17
17
  # Patch version.
18
18
  PATCH = 0
19
19
  # Prerelease version.
@@ -7,12 +7,14 @@ module SleepingKingStudios
7
7
  module Tools
8
8
  autoload :Base, 'sleeping_king_studios/tools/base'
9
9
  autoload :ArrayTools, 'sleeping_king_studios/tools/array_tools'
10
+ autoload :Assertions, 'sleeping_king_studios/tools/assertions'
10
11
  autoload :CoreTools, 'sleeping_king_studios/tools/core_tools'
11
12
  autoload :HashTools, 'sleeping_king_studios/tools/hash_tools'
12
13
  autoload :IntegerTools, 'sleeping_king_studios/tools/integer_tools'
13
14
  autoload :ObjectTools, 'sleeping_king_studios/tools/object_tools'
14
15
  autoload :StringTools, 'sleeping_king_studios/tools/string_tools'
15
16
  autoload :Toolbelt, 'sleeping_king_studios/tools/toolbelt'
17
+ autoload :Toolbox, 'sleeping_king_studios/tools/toolbox'
16
18
  autoload :Version, 'sleeping_king_studios/tools/version'
17
19
  end
18
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sleeping_king_studios-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob "Merlin" Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-19 00:00:00.000000000 Z
11
+ date: 2022-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -58,42 +58,42 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.6'
61
+ version: '1.35'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.6'
68
+ version: '1.35'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rubocop-rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0.5'
75
+ version: '0.6'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0.5'
82
+ version: '0.6'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop-rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '2.1'
89
+ version: '2.12'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '2.1'
96
+ version: '2.12'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -128,28 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '2.5'
131
+ version: '2.7'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '2.5'
139
- - !ruby/object:Gem::Dependency
140
- name: sleeping_king_studios-tasks
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '0.4'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '0.4'
138
+ version: '2.7'
153
139
  description: |
154
140
  A library of utility services and concerns to expand the functionality of
155
141
  core classes without polluting the global namespace.
@@ -166,6 +152,7 @@ files:
166
152
  - README.md
167
153
  - lib/sleeping_king_studios/tools.rb
168
154
  - lib/sleeping_king_studios/tools/array_tools.rb
155
+ - lib/sleeping_king_studios/tools/assertions.rb
169
156
  - lib/sleeping_king_studios/tools/base.rb
170
157
  - lib/sleeping_king_studios/tools/core_tools.rb
171
158
  - lib/sleeping_king_studios/tools/hash_tools.rb
@@ -179,11 +166,15 @@ files:
179
166
  - lib/sleeping_king_studios/tools/toolbox/inflector/rules.rb
180
167
  - lib/sleeping_king_studios/tools/toolbox/mixin.rb
181
168
  - lib/sleeping_king_studios/tools/toolbox/semantic_version.rb
169
+ - lib/sleeping_king_studios/tools/toolbox/subclass.rb
182
170
  - lib/sleeping_king_studios/tools/version.rb
183
171
  homepage: http://sleepingkingstudios.com
184
172
  licenses:
185
173
  - MIT
186
- metadata: {}
174
+ metadata:
175
+ bug_tracker_uri: https://github.com/sleepingkingstudios/sleeping_king_studios-tools/issues
176
+ source_code_uri: https://github.com/sleepingkingstudios/sleeping_king_studios-tools
177
+ rubygems_mfa_required: 'true'
187
178
  post_install_message:
188
179
  rdoc_options: []
189
180
  require_paths:
@@ -192,7 +183,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
183
  requirements:
193
184
  - - ">="
194
185
  - !ruby/object:Gem::Version
195
- version: 2.5.0
186
+ version: 2.7.0
196
187
  required_rubygems_version: !ruby/object:Gem::Requirement
197
188
  requirements:
198
189
  - - ">="