dm_ruby_extensions 1.0.8 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflow/ci.yml +41 -0
- data/.gitignore +0 -3
- data/.rubocop.yml +26 -0
- data/.ruby-version +1 -0
- data/Gemfile +5 -1
- data/README.md +3 -1
- data/Rakefile +6 -4
- data/bin/console +18 -0
- data/dm_ruby_extensions.gemspec +15 -12
- data/lib/dm_ruby_extensions/extend_array.rb +9 -8
- data/lib/dm_ruby_extensions/extend_date.rb +7 -8
- data/lib/dm_ruby_extensions/extend_datetime.rb +6 -7
- data/lib/dm_ruby_extensions/extend_false.rb +2 -3
- data/lib/dm_ruby_extensions/extend_hash.rb +36 -28
- data/lib/dm_ruby_extensions/extend_integer.rb +6 -5
- data/lib/dm_ruby_extensions/extend_nil.rb +11 -11
- data/lib/dm_ruby_extensions/extend_numeric.rb +5 -5
- data/lib/dm_ruby_extensions/extend_string.rb +68 -65
- data/lib/dm_ruby_extensions/extend_time.rb +4 -5
- data/lib/dm_ruby_extensions/extend_true.rb +2 -3
- data/lib/dm_ruby_extensions/version.rb +3 -1
- data/lib/dm_ruby_extensions.rb +15 -12
- data/spec/extensions/array_spec.rb +13 -12
- data/spec/extensions/date_spec.rb +8 -7
- data/spec/extensions/datetime_spec.rb +8 -7
- data/spec/extensions/false_spec.rb +3 -4
- data/spec/extensions/hash_spec.rb +20 -17
- data/spec/extensions/integer_spec.rb +3 -3
- data/spec/extensions/nil_spec.rb +7 -7
- data/spec/extensions/numeric_spec.rb +3 -3
- data/spec/extensions/string_spec.rb +50 -39
- data/spec/extensions/time_spec.rb +4 -3
- data/spec/extensions/true_spec.rb +3 -4
- data/spec/spec_helper.rb +45 -44
- metadata +14 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a52656d8cd06524cb3619c98f8ee54221bbe7099bd8583ac3f6635a3fca73ad1
|
4
|
+
data.tar.gz: 8563dfd8ae1a2d76e5d07fbc6d4b09ce84f01f0970de0344ed6da46bb69f3819
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58dc5a359f374ca974e993472c29ea2649a0855856f03335bd276f5aed0bedb490dee6ea34309e714cbdbce9253c54fdb5ca5c02fa3115b0acf64d681b689b83
|
7
|
+
data.tar.gz: 7e9f70201a41ac2f623214e27af7cd1549984174e4f5bea5e578a8f8898a18f931a546799293feba8449918402f77ac51ea4f2e5ca100f3124fb3d5499f862dd
|
@@ -0,0 +1,41 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
rspec:
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
os:
|
12
|
+
- ubuntu-latest
|
13
|
+
- macos-latest
|
14
|
+
ruby-version: [3.0, 3.1, 3.2, 'ruby-head']
|
15
|
+
|
16
|
+
runs-on: ${{ matrix.os }}
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v4
|
20
|
+
|
21
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
22
|
+
uses: ruby/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
ruby-version: ${{ matrix.ruby-version }}
|
25
|
+
bundler-cache: true # 'bundle install' and cache
|
26
|
+
|
27
|
+
- name: Run ${{ matrix.os }} tests
|
28
|
+
run: bundle install
|
29
|
+
run: bundle exec rspec
|
30
|
+
|
31
|
+
rubocop:
|
32
|
+
runs-on: ubuntu-latest
|
33
|
+
|
34
|
+
steps:
|
35
|
+
- uses: actions/checkout@v4
|
36
|
+
|
37
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
38
|
+
uses: ruby/setup-ruby@v1
|
39
|
+
- name: Run rubocop
|
40
|
+
run: bundle install
|
41
|
+
run: bundle exec rubocop
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- '**/tmp/**/*'
|
4
|
+
CacheRootDirectory: tmp
|
5
|
+
UseCache: false
|
6
|
+
|
7
|
+
Metrics/BlockLength:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Metrics/MethodLength:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Metrics/AbcSize:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Metrics/CyclomaticComplexity:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Metrics/ClassLength:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Metrics/PerceivedComplexity:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/Documentation:
|
26
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.2.2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/dm_ruby_extensions.svg)](http://badge.fury.io/rb/dm_ruby_extensions)
|
4
4
|
[![Build Status](https://travis-ci.com/digitalmoksha/dm_ruby_extensions.svg?branch=master)](https://travis-ci.com/digitalmoksha/dm_ruby_extensions)
|
5
5
|
|
6
|
-
Adds some simple
|
6
|
+
Adds some simple convenience methods to some Ruby classes, for use in the digitalMoksha gems.
|
7
|
+
Although some of these can be found in other libraries, this includes a small handful and
|
8
|
+
removes the dependency on another large library.
|
7
9
|
|
8
10
|
## Installation
|
9
11
|
|
data/Rakefile
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
3
5
|
|
4
6
|
RSpec::Core::RakeTask.new
|
5
7
|
|
6
|
-
task :
|
7
|
-
task :
|
8
|
+
task default: :spec
|
9
|
+
task test: :spec
|
data/bin/console
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'dm_ruby_extensions'
|
6
|
+
require 'irb'
|
7
|
+
|
8
|
+
puts <<~TEXT
|
9
|
+
-------------------
|
10
|
+
Example Usage:
|
11
|
+
|
12
|
+
'1'.as_boolean
|
13
|
+
(Date.today - 12.years).to_age
|
14
|
+
-------------------
|
15
|
+
|
16
|
+
TEXT
|
17
|
+
|
18
|
+
IRB.start(__FILE__)
|
data/dm_ruby_extensions.gemspec
CHANGED
@@ -1,21 +1,24 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'dm_ruby_extensions/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |gem|
|
7
|
-
gem.name =
|
8
|
+
gem.name = 'dm_ruby_extensions'
|
8
9
|
gem.version = DmRubyExtensions::VERSION
|
9
|
-
gem.authors = [
|
10
|
-
gem.email = [
|
11
|
-
gem.description =
|
12
|
-
gem.summary =
|
13
|
-
gem.homepage =
|
10
|
+
gem.authors = ['Brett Walker']
|
11
|
+
gem.email = ['github@digitalmoksha.com']
|
12
|
+
gem.description = 'Ruby base class extensions'
|
13
|
+
gem.summary = 'Simple Ruby base class extensions'
|
14
|
+
gem.homepage = 'https://github.com/digitalmoksha/dm_ruby_extensions'
|
14
15
|
gem.licenses = ['MIT']
|
15
16
|
|
16
|
-
gem.files = `git ls-files`.split(
|
17
|
+
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
-
gem.require_paths = [
|
19
|
-
|
20
|
-
gem.
|
19
|
+
gem.require_paths = ['lib']
|
20
|
+
|
21
|
+
gem.required_ruby_version = '~> 3.0'
|
22
|
+
|
23
|
+
gem.add_dependency 'activesupport', '>= 6.0'
|
21
24
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#------------------------------------------------------------------------------
|
2
4
|
class Array
|
3
|
-
|
4
|
-
#
|
5
|
+
# Extract options from a set of arguments. Removes and returns the last element
|
6
|
+
# in the array if it's a hash, otherwise returns a blank hash.
|
5
7
|
#
|
6
8
|
# def options(*args)
|
7
9
|
# args.extract_options!
|
@@ -19,7 +21,7 @@ class Array
|
|
19
21
|
# [0,5,7,8,11,16].closest_max(7) => 7
|
20
22
|
#------------------------------------------------------------------------------
|
21
23
|
def closest_max(value)
|
22
|
-
self.select{|item| item <= value}.max
|
24
|
+
self.select { |item| item <= value }.max
|
23
25
|
end
|
24
26
|
|
25
27
|
# able to join safe and unsafe strings
|
@@ -27,7 +29,7 @@ class Array
|
|
27
29
|
def xss_aware_join(delimiter = '')
|
28
30
|
''.html_safe.tap do |str|
|
29
31
|
each_with_index do |element, i|
|
30
|
-
str << delimiter if i
|
32
|
+
str << delimiter if i.positive?
|
31
33
|
str << element
|
32
34
|
end
|
33
35
|
end
|
@@ -35,12 +37,11 @@ class Array
|
|
35
37
|
|
36
38
|
# given an array of css classes/styles, join them into one string.
|
37
39
|
# only join non-nil/non-empty strings, and return nil if the result
|
38
|
-
# is an empty string (rails tag methods will not include the
|
40
|
+
# is an empty string (rails tag methods will not include the
|
39
41
|
# attribute if it is nil, which is desirable for cleaner html)
|
40
42
|
#------------------------------------------------------------------------------
|
41
|
-
def css_join(
|
42
|
-
str =
|
43
|
+
def css_join(_delimiter = '')
|
44
|
+
str = flatten.delete_if { |x| x.nil? || x == '' }.join(' ')
|
43
45
|
str == '' ? nil : str
|
44
46
|
end
|
45
47
|
end
|
46
|
-
|
@@ -1,23 +1,22 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
class Date
|
3
4
|
# http://stackoverflow.com/questions/819263/get-persons-age-in-ruby
|
4
5
|
#------------------------------------------------------------------------------
|
5
6
|
def to_age
|
6
7
|
now = Time.now.utc.to_date
|
7
|
-
now.year -
|
8
|
+
now.year - year - (now.month > month || (now.month == month && now.day >= day) ? 0 : 1)
|
8
9
|
end
|
9
|
-
|
10
|
+
|
10
11
|
#------------------------------------------------------------------------------
|
11
12
|
def localize(options = {})
|
12
|
-
options = {:
|
13
|
-
I18n.localize(self, options)
|
13
|
+
options = { format: options } if options.instance_of?(String)
|
14
|
+
I18n.localize(self, **options)
|
14
15
|
end
|
15
16
|
|
16
17
|
# Create a unique sortable index for this date
|
17
18
|
#------------------------------------------------------------------------------
|
18
19
|
def to_index
|
19
|
-
yday + (year-2000) * 1000
|
20
|
+
yday + (year - 2000) * 1000
|
20
21
|
end
|
21
|
-
|
22
22
|
end
|
23
|
-
|
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#------------------------------------------------------------------------------
|
2
4
|
class DateTime
|
3
|
-
|
4
5
|
#------------------------------------------------------------------------------
|
5
6
|
def to_age
|
6
7
|
(DateTime.now - self).to_i / 365
|
@@ -8,15 +9,13 @@ class DateTime
|
|
8
9
|
|
9
10
|
#------------------------------------------------------------------------------
|
10
11
|
def localize(options = {})
|
11
|
-
options = {:
|
12
|
-
I18n.localize(self, options)
|
12
|
+
options = { format: options } if options.instance_of?(String)
|
13
|
+
I18n.localize(self, **options)
|
13
14
|
end
|
14
|
-
|
15
|
+
|
15
16
|
# Create a unique sortable index for this date
|
16
17
|
#------------------------------------------------------------------------------
|
17
18
|
def to_index
|
18
|
-
yday + (year-2000) * 1000
|
19
|
+
yday + (year - 2000) * 1000
|
19
20
|
end
|
20
|
-
|
21
21
|
end
|
22
|
-
|
@@ -1,30 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#------------------------------------------------------------------------------
|
2
4
|
class Hash
|
3
|
-
|
4
|
-
# takes a Hash (like the params hash), and converts the Rails date attributes
|
5
|
+
# takes a Hash (like the params hash), and converts the Rails date attributes
|
5
6
|
# to a real Date object.
|
6
|
-
# {'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23}.convert_date(:start_date)
|
7
|
+
# {'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23}.convert_date(:start_date)
|
7
8
|
#------------------------------------------------------------------------------
|
8
9
|
def convert_date(date_symbol_or_string)
|
9
10
|
attribute = date_symbol_or_string.to_s
|
10
|
-
return nil if self[attribute
|
11
|
-
|
11
|
+
return nil if self["#{attribute}(1i)"].nil? || self["#{attribute}(2i)"].nil? || self["#{attribute}(3i)"].nil?
|
12
|
+
|
13
|
+
Date.new(self["#{attribute}(1i)"].to_i, self["#{attribute}(2i)"].to_i, self["#{attribute}(3i)"].to_i)
|
12
14
|
end
|
13
15
|
|
14
|
-
# takes a Hash (like the params hash), and converts the Rails datetime attributes
|
16
|
+
# takes a Hash (like the params hash), and converts the Rails datetime attributes
|
15
17
|
# to a real Date object.
|
16
18
|
#------------------------------------------------------------------------------
|
17
19
|
def convert_datetime(date_symbol_or_string)
|
18
20
|
attribute = date_symbol_or_string.to_s
|
19
|
-
|
20
|
-
|
21
|
+
if self["#{attribute}(1i)"].nil? || self["#{attribute}(2i)"].nil? ||
|
22
|
+
self["#{attribute}(3i)"].nil? || self["#{attribute}(4i)"].nil? ||
|
23
|
+
self["#{attribute}(5i)"].nil?
|
24
|
+
return nil
|
25
|
+
end
|
26
|
+
|
27
|
+
Time.local(self["#{attribute}(1i)"].to_i, self["#{attribute}(2i)"].to_i, self["#{attribute}(3i)"].to_i,
|
28
|
+
self["#{attribute}(4i)"].to_i, self["#{attribute}(5i)"].to_i)
|
21
29
|
end
|
22
30
|
|
23
31
|
# Convert hash of parameters to a query string
|
24
32
|
#------------------------------------------------------------------------------
|
33
|
+
# rubocop:disable Style/OptionalBooleanParameter
|
25
34
|
def url_query_string(leading_slash = true)
|
26
|
-
|
35
|
+
"#{leading_slash ? '/?' : '?'}#{to_query}"
|
27
36
|
end
|
37
|
+
# rubocop:enable Style/OptionalBooleanParameter
|
28
38
|
|
29
39
|
# Borrowed from https://github.com/rubyworks/facets
|
30
40
|
#------------------------------------------------------------------------------
|
@@ -42,7 +52,7 @@ class Hash
|
|
42
52
|
# foo.rekey(:b=>:x) #=> { :a =>1, :x=>2 }
|
43
53
|
# foo.rekey('foo'=>'bar') #=> { :a =>1, :b=>2 }
|
44
54
|
#
|
45
|
-
# If a block is given, converts all keys in the Hash
|
55
|
+
# If a block is given, converts all keys in the Hash according to the
|
46
56
|
# given block procedure.
|
47
57
|
#
|
48
58
|
# foo = { :name=>'Gavin', :wife=>:Lisa }
|
@@ -55,37 +65,36 @@ class Hash
|
|
55
65
|
# Raises an ArgumentError if both a +key_map+ and a block are given.
|
56
66
|
# If both are needed just call #rekey twice.
|
57
67
|
#
|
58
|
-
# TODO: If `nil` is returned by block should the key be set to `nil` or the
|
68
|
+
# TODO: If `nil` is returned by block should the key be set to `nil` or the original key?
|
59
69
|
#
|
60
70
|
# CREDIT: Trans, Gavin Kistner
|
71
|
+
def rekey(key_map = nil, &block)
|
72
|
+
raise ArgumentError, 'argument or block' if key_map && block
|
61
73
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
if !(key_map or block)
|
66
|
-
block = lambda{|k| k.to_sym}
|
74
|
+
unless key_map || block
|
75
|
+
block = lambda { |k| k.to_sym } # rubocop:disable Style/SymbolProc, Style/Lambda
|
67
76
|
end
|
68
77
|
|
69
78
|
if block
|
70
79
|
hash = dup.clear
|
71
80
|
if block.arity.abs == 1
|
72
81
|
each_pair do |k, v|
|
73
|
-
hash[block[k]] = v
|
82
|
+
hash[block[k]] = v # hash[block[k] || k] = v
|
74
83
|
end
|
75
84
|
else
|
76
85
|
each_pair do |k, v|
|
77
|
-
hash[block[k,v]] = v
|
86
|
+
hash[block[k, v]] = v # hash[block[k,v] || k] = v
|
78
87
|
end
|
79
88
|
end
|
80
89
|
else
|
81
|
-
#hash = dup.clear # to keep default_proc
|
82
|
-
#(keys - key_map.keys).each do |key|
|
83
|
-
#
|
84
|
-
#end
|
85
|
-
#key_map.each do |from, to|
|
86
|
-
#
|
87
|
-
#end
|
88
|
-
hash = dup
|
90
|
+
# hash = dup.clear # to keep default_proc
|
91
|
+
# (keys - key_map.keys).each do |key|
|
92
|
+
# hash[key] = self[key]
|
93
|
+
# end
|
94
|
+
# key_map.each do |from, to|
|
95
|
+
# hash[to] = self[from] if key?(from)
|
96
|
+
# end
|
97
|
+
hash = dup # to keep default_proc
|
89
98
|
key_map.each_pair do |from, to|
|
90
99
|
hash[to] = hash.delete(from) if hash.key?(from)
|
91
100
|
end
|
@@ -102,8 +111,7 @@ class Hash
|
|
102
111
|
#
|
103
112
|
# CREDIT: Trans, Gavin Kistner
|
104
113
|
|
105
|
-
def rekey!(key_map=nil, &block)
|
114
|
+
def rekey!(key_map = nil, &block)
|
106
115
|
replace(rekey(key_map, &block))
|
107
116
|
end
|
108
|
-
|
109
117
|
end
|
@@ -1,16 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
class Integer
|
3
4
|
# Factorial of number
|
4
5
|
# 5.factorial == 5 x 4 x 3 x 2 x 1 == 120
|
5
6
|
#------------------------------------------------------------------------------
|
6
7
|
def factorial
|
7
|
-
return 1 if
|
8
|
+
return 1 if zero?
|
9
|
+
|
8
10
|
(1..self).inject(:*)
|
9
11
|
end
|
10
12
|
|
11
13
|
#------------------------------------------------------------------------------
|
12
14
|
def as_boolean
|
13
|
-
|
15
|
+
positive? ? true : false
|
14
16
|
end
|
15
|
-
|
16
|
-
end
|
17
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# If nil, then return a default string
|
2
4
|
#------------------------------------------------------------------------------
|
3
|
-
class NilClass
|
4
|
-
|
5
|
+
class NilClass # :nodoc:
|
5
6
|
#------------------------------------------------------------------------------
|
6
7
|
def to_s_default(default_str = 'n/a')
|
7
8
|
default_str
|
@@ -11,7 +12,7 @@ class NilClass #:nodoc:
|
|
11
12
|
def as_boolean
|
12
13
|
false
|
13
14
|
end
|
14
|
-
|
15
|
+
|
15
16
|
#------------------------------------------------------------------------------
|
16
17
|
def to_age
|
17
18
|
0
|
@@ -19,18 +20,17 @@ class NilClass #:nodoc:
|
|
19
20
|
|
20
21
|
#------------------------------------------------------------------------------
|
21
22
|
def sql_wildcard
|
22
|
-
|
23
|
+
'%'
|
23
24
|
end
|
24
|
-
|
25
|
+
|
25
26
|
#------------------------------------------------------------------------------
|
26
27
|
def utc
|
27
|
-
|
28
|
+
''
|
28
29
|
end
|
29
|
-
|
30
|
+
|
30
31
|
# if nil + something, just return something
|
31
32
|
#------------------------------------------------------------------------------
|
32
|
-
def +(
|
33
|
-
|
33
|
+
def +(other)
|
34
|
+
other
|
34
35
|
end
|
35
|
-
|
36
|
-
end
|
36
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Numeric
|
2
|
-
|
3
4
|
#------------------------------------------------------------------------------
|
4
|
-
def percent_of(
|
5
|
-
|
5
|
+
def percent_of(num, precision = 0)
|
6
|
+
num.zero? ? 0 : (to_f / num * 100.0).round(precision)
|
6
7
|
end
|
7
|
-
|
8
|
-
end
|
8
|
+
end
|