dm_ruby_extensions 1.5.0 → 1.6.0

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: a52656d8cd06524cb3619c98f8ee54221bbe7099bd8583ac3f6635a3fca73ad1
4
- data.tar.gz: 8563dfd8ae1a2d76e5d07fbc6d4b09ce84f01f0970de0344ed6da46bb69f3819
3
+ metadata.gz: 36e22b14857c9ce862d6610260ebf28c314982649a0a69e6e04cf37bd74fad25
4
+ data.tar.gz: 1002cd447ad89971c298c3eeb3f21069302491667781546c82de05b28beb3521
5
5
  SHA512:
6
- metadata.gz: 58dc5a359f374ca974e993472c29ea2649a0855856f03335bd276f5aed0bedb490dee6ea34309e714cbdbce9253c54fdb5ca5c02fa3115b0acf64d681b689b83
7
- data.tar.gz: 7e9f70201a41ac2f623214e27af7cd1549984174e4f5bea5e578a8f8898a18f931a546799293feba8449918402f77ac51ea4f2e5ca100f3124fb3d5499f862dd
6
+ metadata.gz: 60992cd05bf21a44458666b8bdd8d6e6e91360c53f259f930421b05ed1701b0e9f6b028c28842793007be1312e9c28a6036de6b5484ccae3a967b0a692b311bf
7
+ data.tar.gz: 52bf4954ecfcd7a36f1efb02a4b5fd72e671242ce5df1c95ae96b2150915b3b61abfbd4aec5fc53df9af512ec80d4a031b6c4d6cb90168590f6dfba5c8c6886f
data/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ ## 1.6.0
4
+
5
+ - Support Ruby 4.0: `required_ruby_version` is now `>= 3.2` (was `~> 3.0`, which
6
+ excluded Ruby 4).
7
+ - Drop support for Ruby 3.0 and 3.1, which have reached end of life.
8
+ - Limit ActiveSupport to `>= 6.0, < 9`.
9
+ - Gemspec: package files with `Dir` instead of `git ls-files`, remove the
10
+ deprecated `test_files`, require MFA for publishing, and add source, changelog
11
+ and bug tracker links.
12
+ - Replace the Travis build, which no longer ran, with GitHub Actions on Ruby 3.2
13
+ through 4.0.
14
+ - Update RuboCop to 1.92 and rubocop-rspec to 3.10.
15
+ - Fix a spec for `nil + other` that didn't actually test it.
16
+
17
+ ## 1.5.0
18
+
19
+ - Drop support for Ruby 2.
data/README.md CHANGED
@@ -1,94 +1,146 @@
1
1
  # DmRubyExtensions
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/dm_ruby_extensions.svg)](http://badge.fury.io/rb/dm_ruby_extensions)
4
- [![Build Status](https://travis-ci.com/digitalmoksha/dm_ruby_extensions.svg?branch=master)](https://travis-ci.com/digitalmoksha/dm_ruby_extensions)
4
+ [![Build status](https://github.com/digitalmoksha/dm_ruby_extensions/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/digitalmoksha/dm_ruby_extensions/actions/workflows/ci.yml)
5
5
 
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.
6
+ A small set of convenience methods added to Ruby's core classes (`String`, `Hash`,
7
+ `Array`, `Date` and others). It's used by the digitalMoksha gems, such as
8
+ [moksha_cms](https://gitlab.com/moksha_cms/moksha_cms), for formatting names and
9
+ titles, building CSS and URLs, reading Rails date params, and similar everyday jobs.
9
10
 
10
- ## Installation
11
-
12
- Add this line to your application's Gemfile:
13
-
14
- gem 'dm_ruby_extensions'
15
-
16
- And then execute:
17
-
18
- $ bundle
19
-
20
- Or install it yourself as:
21
-
22
- $ gem install dm_ruby_extensions
23
-
24
- ## Usage
25
-
26
- #### Array
27
-
28
- * extract_options!
29
- * closest_max
30
- * xss_aware_join
31
- * css_join
32
-
33
- #### Date
34
-
35
- * to_age
36
- * localize
11
+ ## Requirements
37
12
 
38
- #### DateTime
13
+ - Ruby 3.2 or later (CI covers 3.2 through 4.0)
14
+ - ActiveSupport 6.0 or later
39
15
 
40
- * to_age
41
- * localize
16
+ Requiring the gem also loads `active_support/core_ext`. The `localize` methods use
17
+ `I18n`, which comes with ActiveSupport.
42
18
 
43
- #### Fixnum
44
-
45
- * factorial
46
- * as_boolean
47
-
48
- #### Hash
49
-
50
- * convert_date
51
- * convert_datetime
52
- * url_query_string
53
- * rekey
54
- * rekey!
55
-
56
- #### Nil
57
-
58
- * to_s_default
59
- * as_boolean
60
- * to_age
61
- * sql_wildcard
62
-
63
- #### Numeric
64
-
65
- * percent_of
66
-
67
- #### String
68
-
69
- * to_s_default
70
- * as_boolean
71
- * as_css_size
72
- * sql_wildcard
73
- * replace_non_alphanumeric
74
- * expand_url
75
- * absolute_url?
76
- * smart_titlecase
77
- * smart_capitalize
78
- * smart_capitalize!
79
- * smart_truncate
80
- * name_case
81
- * name_case!
19
+ ## Installation
82
20
 
83
- #### Time
21
+ Add it to your Gemfile:
22
+
23
+ ```ruby
24
+ gem 'dm_ruby_extensions'
25
+ ```
26
+
27
+ and run `bundle install`. In a Rails app it's loaded by Bundler; elsewhere, add
28
+ `require 'dm_ruby_extensions'`.
29
+
30
+ ## What it adds
31
+
32
+ ### String
33
+
34
+ | Method | Description |
35
+ |---|---|
36
+ | `to_s_default(default = 'n/a')` | The string, or `default` if it's empty or only whitespace |
37
+ | `as_boolean` | `true` for `'true'`, `'yes'` or `'1'`, otherwise `false` |
38
+ | `as_css_size` | Adds `px` unless the value already has `px`, `%` or `em`, or is `auto`/`inherit` |
39
+ | `sql_wildcard` | Wraps the string in `%` for a SQL `LIKE` |
40
+ | `replace_non_alphanumeric(replacement = '')` | Replaces everything except letters, digits, `_`, `.` and `-` |
41
+ | `sanitize_filename` | Strips any path (Unix or Windows) and replaces unsafe characters with `_` |
42
+ | `expand_url(path = '')` | Prefixes a relative URL with `path`; absolute URLs are returned unchanged |
43
+ | `absolute_url?` | `true` if the string contains `://` or starts with `/` |
44
+ | `smart_titlecase` | Title case that keeps small words lowercase (Ruby port of John Gruber's TitleCase) |
45
+ | `smart_capitalize` / `smart_capitalize!` | Capitalizes the first real letter, leaving words like `iPhone` alone |
46
+ | `smart_truncate(words: 12)` / `smart_truncate(sentences: n)` | Truncates by words or sentences and appends `...` |
47
+ | `name_case` / `name_case!` | Properly cases names, e.g. `McDonald`, `O'Brien` (port of Lingua::EN::NameCase) |
48
+
49
+ ```ruby
50
+ '300'.as_css_size #=> "300px"
51
+ 'images/logo.png'.expand_url('/assets') #=> "/assets/images/logo.png"
52
+ 'C:\docs\my report.pdf'.sanitize_filename #=> "my_report.pdf"
53
+ 'the lord of the rings'.smart_titlecase #=> "The Lord of the Rings"
54
+ 'one two three four five'.smart_truncate(words: 3) #=> "one two three..."
55
+ 'MCDONALD'.name_case #=> "McDonald"
56
+ ```
57
+
58
+ ### Hash
59
+
60
+ | Method | Description |
61
+ |---|---|
62
+ | `convert_date(attribute)` | Builds a `Date` from Rails date-select params (`attr(1i)`–`attr(3i)`), or `nil` |
63
+ | `convert_datetime(attribute)` | Builds a local `Time` from Rails datetime-select params (`attr(1i)`–`attr(5i)`), or `nil` |
64
+ | `url_query_string(leading_slash = true)` | Turns the hash into a query string, e.g. `"/?page=2&q=yoga"` |
65
+ | `rekey` / `rekey!` | Renames keys with a key map or a block; with neither, symbolizes all keys (from [Facets](https://github.com/rubyworks/facets)) |
66
+
67
+ ```ruby
68
+ params = { 'start_date(1i)' => '2026', 'start_date(2i)' => '11', 'start_date(3i)' => '8' }
69
+ params.convert_date(:start_date) #=> Sun, 08 Nov 2026
70
+ { page: 2, q: 'yoga' }.url_query_string #=> "/?page=2&q=yoga"
71
+ { a: 1, b: 2 }.rekey(a: 'x') # 'x' => 1, :b => 2
72
+ ```
73
+
74
+ ### Array
75
+
76
+ | Method | Description |
77
+ |---|---|
78
+ | `extract_options!` | Removes and returns a trailing options hash, or `{}` |
79
+ | `closest_max(value)` | The largest element that is less than or equal to `value` |
80
+ | `xss_aware_join(delimiter = '')` | Joins into an `html_safe` string, escaping elements that aren't already safe |
81
+ | `css_join` | Joins CSS class names, skipping `nil` and empty strings; returns `nil` if nothing is left, so Rails leaves the attribute out |
82
+
83
+ ```ruby
84
+ [0, 5, 7, 8, 11, 16].closest_max(6) #=> 5
85
+ ['btn', nil, '', 'btn-primary'].css_join #=> "btn btn-primary"
86
+ [nil, ''].css_join #=> nil
87
+ ```
88
+
89
+ ### Date, DateTime and Time
90
+
91
+ | Method | Description |
92
+ |---|---|
93
+ | `Date#to_age`, `DateTime#to_age` | Age in whole years, e.g. from a birth date |
94
+ | `Date#to_index`, `DateTime#to_index` | A sortable integer for the day: day of year + (year − 2000) × 1000 |
95
+ | `localize(options = {})` | `I18n.localize(self, ...)`; a string argument is taken as the `format` |
96
+
97
+ ### Numbers and booleans
98
+
99
+ | Method | Description |
100
+ |---|---|
101
+ | `Integer#factorial` | `5.factorial #=> 120` |
102
+ | `Integer#as_boolean` | `true` for positive numbers, otherwise `false` |
103
+ | `Numeric#percent_of(total, precision = 0)` | `25.percent_of(80) #=> 31`; returns `0` when `total` is zero |
104
+ | `TrueClass#as_boolean`, `FalseClass#as_boolean` | Return themselves, so `as_boolean` works on any of these values |
105
+
106
+ ### nil
107
+
108
+ `nil` gets the same helpers, so you don't have to check for it first:
109
+
110
+ | Method | Returns |
111
+ |---|---|
112
+ | `to_s_default(default = 'n/a')` | `default` |
113
+ | `as_boolean` | `false` |
114
+ | `to_age` | `0` |
115
+ | `sql_wildcard` | `'%'` (matches everything) |
116
+ | `utc` | `''` |
117
+ | `+(other)` | `other`, so `nil + 5 #=> 5` |
118
+
119
+ ## Development
120
+
121
+ ```
122
+ bundle install
123
+ bundle exec rspec
124
+ bundle exec rubocop
125
+ ```
126
+
127
+ CI runs the specs on Ruby 3.2 through 4.0 (plus ruby-head) on Linux and macOS, and
128
+ runs RuboCop, for every pull request and push to `master`.
129
+
130
+ To release a new version, update `lib/dm_ruby_extensions/version.rb` and
131
+ `CHANGELOG.md`, then:
132
+
133
+ ```
134
+ gem build dm_ruby_extensions.gemspec
135
+ gem push dm_ruby_extensions-<version>.gem
136
+ ```
84
137
 
85
- * localize
138
+ ## Contributing
86
139
 
140
+ Bug reports and pull requests are welcome at
141
+ <https://github.com/digitalmoksha/dm_ruby_extensions>. Please include specs for any
142
+ change.
87
143
 
88
- ## Contributing
144
+ ## License
89
145
 
90
- 1. Fork it
91
- 2. Create your feature branch (`git checkout -b my-new-feature`)
92
- 3. Commit your changes (`git commit -am 'Add some feature'`)
93
- 4. Push to the branch (`git push origin my-new-feature`)
94
- 5. Create new Pull Request
146
+ MIT. See [LICENSE](LICENSE).
@@ -17,6 +17,6 @@ class Date
17
17
  # Create a unique sortable index for this date
18
18
  #------------------------------------------------------------------------------
19
19
  def to_index
20
- yday + (year - 2000) * 1000
20
+ yday + ((year - 2000) * 1000)
21
21
  end
22
22
  end
@@ -16,6 +16,6 @@ class DateTime
16
16
  # Create a unique sortable index for this date
17
17
  #------------------------------------------------------------------------------
18
18
  def to_index
19
- yday + (year - 2000) * 1000
19
+ yday + ((year - 2000) * 1000)
20
20
  end
21
21
  end
@@ -30,11 +30,9 @@ class Hash
30
30
 
31
31
  # Convert hash of parameters to a query string
32
32
  #------------------------------------------------------------------------------
33
- # rubocop:disable Style/OptionalBooleanParameter
34
- def url_query_string(leading_slash = true)
33
+ def url_query_string(leading_slash = true) # rubocop:disable Style/OptionalBooleanParameter
35
34
  "#{leading_slash ? '/?' : '?'}#{to_query}"
36
35
  end
37
- # rubocop:enable Style/OptionalBooleanParameter
38
36
 
39
37
  # Borrowed from https://github.com/rubyworks/facets
40
38
  #------------------------------------------------------------------------------
@@ -111,7 +109,7 @@ class Hash
111
109
  #
112
110
  # CREDIT: Trans, Gavin Kistner
113
111
 
114
- def rekey!(key_map = nil, &block)
115
- replace(rekey(key_map, &block))
112
+ def rekey!(key_map = nil, &)
113
+ replace(rekey(key_map, &))
116
114
  end
117
115
  end
@@ -12,6 +12,6 @@ class Integer
12
12
 
13
13
  #------------------------------------------------------------------------------
14
14
  def as_boolean
15
- positive? ? true : false
15
+ positive?
16
16
  end
17
17
  end
@@ -11,7 +11,7 @@ class String # :nodoc:
11
11
 
12
12
  #------------------------------------------------------------------------------
13
13
  def as_boolean
14
- self == 'true' || self == 'yes' || self == '1' ? true : false
14
+ self == 'true' || self == 'yes' || self == '1'
15
15
  end
16
16
 
17
17
  # given a css type of size (like a width), make it into a valid css value
@@ -59,7 +59,7 @@ class String # :nodoc:
59
59
  # Test if a url is absolute
60
60
  #------------------------------------------------------------------------------
61
61
  def absolute_url?
62
- include?('://') || start_with?('/') ? true : false
62
+ include?('://') || start_with?('/')
63
63
  end
64
64
 
65
65
  #------------------------------------------------------------------------------
@@ -88,13 +88,13 @@ class String # :nodoc:
88
88
  result = dup
89
89
 
90
90
  # ignore any leading crazy characters and capitalize the first real character
91
- return result unless self =~ /^['"(\[']*([a-z])/
91
+ return result unless self =~ /^['"(\[]*([a-z])/
92
92
 
93
93
  i = index(::Regexp.last_match(1))
94
94
  x = result[i, result.length]
95
95
 
96
96
  # word with capitals and periods mid-word are left alone
97
- result[i, 1] = result[i, 1].upcase unless x =~ (/[A-Z]/) || x =~ (/\.\w+/)
97
+ result[i, 1] = result[i, 1].upcase unless x =~ /[A-Z]/ || x =~ /\.\w+/
98
98
 
99
99
  result
100
100
  end
@@ -143,7 +143,7 @@ class String # :nodoc:
143
143
  localstring.gsub!(/'\w\b/, &:downcase) # Lowercase 's
144
144
 
145
145
  if options[:irish]
146
- if localstring =~ (/\bMac[A-Za-z]{2,}[^aciozj]\b/) || localstring =~ (/\bMc/)
146
+ if localstring =~ /\bMac[A-Za-z]{2,}[^aciozj]\b/ || localstring =~ /\bMc/
147
147
  match = localstring.match(/\b(Ma?c)([A-Za-z]+)/)
148
148
  localstring.gsub!(/\bMa?c[A-Za-z]+/) { match[1] + match[2].capitalize }
149
149
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DmRubyExtensions
4
- VERSION = '1.5.0'
4
+ VERSION = '1.6.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm_ruby_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Walker
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-06-22 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -17,6 +16,9 @@ dependencies:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
18
  version: '6.0'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '9'
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +26,9 @@ dependencies:
24
26
  - - ">="
25
27
  - !ruby/object:Gem::Version
26
28
  version: '6.0'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '9'
27
32
  description: Ruby base class extensions
28
33
  email:
29
34
  - github@digitalmoksha.com
@@ -31,18 +36,9 @@ executables: []
31
36
  extensions: []
32
37
  extra_rdoc_files: []
33
38
  files:
34
- - ".github/workflow/ci.yml"
35
- - ".gitignore"
36
- - ".rspec"
37
- - ".rubocop.yml"
38
- - ".ruby-version"
39
- - ".travis.yml"
40
- - Gemfile
39
+ - CHANGELOG.md
41
40
  - LICENSE
42
41
  - README.md
43
- - Rakefile
44
- - bin/console
45
- - dm_ruby_extensions.gemspec
46
42
  - lib/dm_ruby_extensions.rb
47
43
  - lib/dm_ruby_extensions/extend_array.rb
48
44
  - lib/dm_ruby_extensions/extend_date.rb
@@ -56,51 +52,29 @@ files:
56
52
  - lib/dm_ruby_extensions/extend_time.rb
57
53
  - lib/dm_ruby_extensions/extend_true.rb
58
54
  - lib/dm_ruby_extensions/version.rb
59
- - spec/extensions/array_spec.rb
60
- - spec/extensions/date_spec.rb
61
- - spec/extensions/datetime_spec.rb
62
- - spec/extensions/false_spec.rb
63
- - spec/extensions/hash_spec.rb
64
- - spec/extensions/integer_spec.rb
65
- - spec/extensions/nil_spec.rb
66
- - spec/extensions/numeric_spec.rb
67
- - spec/extensions/string_spec.rb
68
- - spec/extensions/time_spec.rb
69
- - spec/extensions/true_spec.rb
70
- - spec/spec_helper.rb
71
55
  homepage: https://github.com/digitalmoksha/dm_ruby_extensions
72
56
  licenses:
73
57
  - MIT
74
- metadata: {}
75
- post_install_message:
58
+ metadata:
59
+ source_code_uri: https://github.com/digitalmoksha/dm_ruby_extensions
60
+ changelog_uri: https://github.com/digitalmoksha/dm_ruby_extensions/blob/master/CHANGELOG.md
61
+ bug_tracker_uri: https://github.com/digitalmoksha/dm_ruby_extensions/issues
62
+ rubygems_mfa_required: 'true'
76
63
  rdoc_options: []
77
64
  require_paths:
78
65
  - lib
79
66
  required_ruby_version: !ruby/object:Gem::Requirement
80
67
  requirements:
81
- - - "~>"
68
+ - - ">="
82
69
  - !ruby/object:Gem::Version
83
- version: '3.0'
70
+ version: '3.2'
84
71
  required_rubygems_version: !ruby/object:Gem::Requirement
85
72
  requirements:
86
73
  - - ">="
87
74
  - !ruby/object:Gem::Version
88
75
  version: '0'
89
76
  requirements: []
90
- rubygems_version: 3.4.10
91
- signing_key:
77
+ rubygems_version: 4.0.11
92
78
  specification_version: 4
93
79
  summary: Simple Ruby base class extensions
94
- test_files:
95
- - spec/extensions/array_spec.rb
96
- - spec/extensions/date_spec.rb
97
- - spec/extensions/datetime_spec.rb
98
- - spec/extensions/false_spec.rb
99
- - spec/extensions/hash_spec.rb
100
- - spec/extensions/integer_spec.rb
101
- - spec/extensions/nil_spec.rb
102
- - spec/extensions/numeric_spec.rb
103
- - spec/extensions/string_spec.rb
104
- - spec/extensions/time_spec.rb
105
- - spec/extensions/true_spec.rb
106
- - spec/spec_helper.rb
80
+ test_files: []
@@ -1,41 +0,0 @@
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 DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --color
2
- --require spec_helper
3
- --format documentation
data/.rubocop.yml DELETED
@@ -1,26 +0,0 @@
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 DELETED
@@ -1 +0,0 @@
1
- 3.2.2
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.3.7
4
- - 2.4.4
5
- script:
6
- - bundle install --jobs=3 --retry=3
7
- - bundle exec rake spec
data/Gemfile DELETED
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- gemspec
6
-
7
- gem 'pry-byebug'
8
- gem 'rake'
9
- gem 'rspec'
10
- gem 'rubocop', '~> 1.36'
11
- gem 'rubocop-rspec', '~> 2.13'
data/Rakefile DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new
7
-
8
- task default: :spec
9
- task test: :spec
data/bin/console DELETED
@@ -1,18 +0,0 @@
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__)
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path('lib', __dir__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'dm_ruby_extensions/version'
6
-
7
- Gem::Specification.new do |gem|
8
- gem.name = 'dm_ruby_extensions'
9
- gem.version = DmRubyExtensions::VERSION
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'
15
- gem.licenses = ['MIT']
16
-
17
- gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
- gem.require_paths = ['lib']
20
-
21
- gem.required_ruby_version = '~> 3.0'
22
-
23
- gem.add_dependency 'activesupport', '>= 6.0'
24
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe Array do
7
- describe 'closest_max' do
8
- #------------------------------------------------------------------------------
9
- it 'return the value that is closest to the value in the array, rounded down' do
10
- expect([0, 5, 7, 8, 11, 16].closest_max(6)).to eq 5
11
- expect([0, 5, 7, 8, 11, 16].closest_max(7)).to eq 7
12
- end
13
- end
14
-
15
- describe 'extract_options!' do
16
- #------------------------------------------------------------------------------
17
- it "Removes and returns the last element in the array if it's a hash, otherwise returns a blank hash" do
18
- args = [1, 2, { a: :b }]
19
- expect(args.extract_options!).to eq({ a: :b })
20
- expect(args).to eq [1, 2]
21
- expect(args.extract_options!).to eq({})
22
- end
23
- end
24
-
25
- describe 'xss_aware_join' do
26
- it 'safely join safe and unsafe strings' do
27
- safe = '<p>Safe</p>'.html_safe
28
- unsafe = '<script></script>'
29
- expect([safe, unsafe].xss_aware_join).to eq '<p>Safe</p>&lt;script&gt;&lt;/script&gt;'
30
- expect([safe, unsafe].xss_aware_join.class).to eq ActiveSupport::SafeBuffer
31
- end
32
- end
33
-
34
- describe 'css_join' do
35
- it 'given an array of css classes/styles, join them into one string' do
36
- classes = ['panel', '', 'panel-body', nil, 'red']
37
- expect(classes.css_join(' ')).to eq 'panel panel-body red'
38
- end
39
- end
40
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe Date do
7
- describe 'to_age' do
8
- it 'return number of years since now' do
9
- expect(Date.new(Time.now.year - 50, Time.now.month, Time.now.day).to_age).to eq 50
10
- end
11
- end
12
-
13
- describe 'localize' do
14
- it 'localize the date based on the format' do
15
- I18n.enforce_available_locales = false
16
- I18n.locale = :en
17
- date = Date.new(2012, 11, 23)
18
- expect(date.localize).to eq '2012-11-23'
19
- expect(date.localize(format: :short)).to eq 'Nov 23'
20
- expect(date.localize('%b %Y')).to eq 'Nov 2012'
21
- end
22
- end
23
-
24
- describe 'to_index' do
25
- it 'creates unique sortable index for a date' do
26
- date = Date.new(2012, 11, 23)
27
- expect(date.to_index).to eq 12_328
28
- end
29
- end
30
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe DateTime do
7
- describe 'to_age' do
8
- it 'return number of years since now' do
9
- expect(DateTime.new(Time.now.year - 50, Time.now.month, Time.now.day).to_age).to eq 50
10
- end
11
- end
12
-
13
- describe 'localize' do
14
- it 'localize the date based on the format' do
15
- I18n.enforce_available_locales = false
16
- I18n.locale = :en
17
- date = DateTime.new(2012, 11, 23, 8, 35)
18
- expect(date.localize).to eq 'Fri, 23 Nov 2012 08:35:00 +0000'
19
- expect(date.localize(format: :short)).to eq '23 Nov 08:35'
20
- expect(date.localize('%b %Y')).to eq 'Nov 2012'
21
- end
22
- end
23
-
24
- describe 'to_index' do
25
- it 'creates unique sortable index for a date' do
26
- date = Date.new(2012, 11, 23)
27
- expect(date.to_index).to eq 12_328
28
- end
29
- end
30
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe FalseClass do
7
- describe 'as_boolean' do
8
- specify { expect(false.as_boolean).to eq false }
9
- end
10
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe Hash do
7
- describe 'convert_date' do
8
- #------------------------------------------------------------------------------
9
- it 'converts a rails date hash' do
10
- datehash = { 'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23 }
11
- expect(datehash.convert_date(:start_date)).to eq Date.new(2012, 11, 23)
12
- expect(datehash.convert_date(:end_date)).to eq nil
13
- end
14
- end
15
-
16
- describe 'convert_datetime' do
17
- #------------------------------------------------------------------------------
18
- it 'converts a rails datetime hash' do
19
- datehash = { 'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23, 'start_date(4i)' => 8,
20
- 'start_date(5i)' => 35 }
21
- expect(datehash.convert_datetime(:start_date)).to eq Time.local(2012, 11, 23, 8, 35)
22
- expect(datehash.convert_datetime(:end_date)).to eq nil
23
- end
24
- end
25
-
26
- describe 'url_query_string' do
27
- #------------------------------------------------------------------------------
28
- it 'converts hash of parameters to a query string' do
29
- params = { tag: 'shoe', as_admin: '1' }
30
- expect(params.url_query_string).to eq '/?as_admin=1&tag=shoe'
31
- expect(params.url_query_string(false)).to eq '?as_admin=1&tag=shoe'
32
- end
33
- end
34
-
35
- describe 'rekey' do
36
- #------------------------------------------------------------------------------
37
- it 'if a key map is given, then the first key is changed to the second key.' do
38
- foo = { a: 1, b: 2 }
39
- expect(foo.rekey(a: 'a')).to eq({ 'a' => 1, :b => 2 })
40
- expect(foo.rekey(b: :x)).to eq({ a: 1, x: 2 })
41
- expect(foo.rekey('foo' => 'bar')).to eq({ a: 1, b: 2 })
42
- end
43
-
44
- #------------------------------------------------------------------------------
45
- # rubocop:disable Style/SymbolProc
46
- it 'converts all keys in the Hash accroding to the given block procedure' do
47
- foo = { name: 'Gavin', wife: :Lisa }
48
- expect(foo.rekey { |k| k.to_s }).to eq({ 'name' => 'Gavin', 'wife' => :Lisa })
49
- end
50
- # rubocop:enable Style/SymbolProc
51
-
52
- #------------------------------------------------------------------------------
53
- it 'converts all keys to symbols' do
54
- foo = { 'name' => 'Gavin', 'wife' => :Lisa }
55
- expect(foo.rekey).to eq({ name: 'Gavin', wife: :Lisa })
56
- end
57
- end
58
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe Integer do
7
- describe 'factorial' do
8
- #------------------------------------------------------------------------------
9
- it 'return the factorial of the number' do
10
- expect(5.factorial).to eq 120
11
- expect(1.factorial).to eq 1
12
- end
13
- end
14
-
15
- describe 'as_boolean' do
16
- specify { expect(1.as_boolean).to be_truthy }
17
- specify { expect(0.as_boolean).to be_falsey }
18
- specify { expect(20.as_boolean).to be_truthy }
19
- end
20
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe NilClass do
7
- describe 'to_s_default' do
8
- it 'returns default string' do
9
- expect(nil.to_s_default).to eq 'n/a'
10
- expect(nil.to_s_default('--')).to eq '--'
11
- end
12
- end
13
-
14
- describe 'as_boolean' do
15
- specify { expect(nil.as_boolean).to eq false }
16
- end
17
-
18
- describe 'to_age' do
19
- specify { expect(nil.to_age).to eq 0 }
20
- end
21
-
22
- describe 'sql_wildcard' do
23
- specify { expect(nil.sql_wildcard).to eq '%' }
24
- end
25
-
26
- describe 'utc' do
27
- specify { expect(nil.utc).to eq '' }
28
- end
29
-
30
- describe '+(y)' do
31
- specify { expect(nil + 12).to eq 12 }
32
- specify { expect('foo').to eq 'foo' }
33
- end
34
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe Numeric do
7
- describe 'percent_of' do
8
- it 'returns percentage of number' do
9
- expect(25.percent_of(100)).to eq 25
10
- expect(25.percent_of(80)).to eq 31
11
- expect(25.percent_of(80, 2)).to eq 31.25
12
- end
13
- end
14
- end
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe String do
7
- describe 'to_s_default' do
8
- specify { expect('foobar'.to_s_default).to eq 'foobar' }
9
- specify { expect(''.to_s_default).to eq 'n/a' }
10
- specify { expect(''.to_s_default('--')).to eq '--' }
11
- end
12
-
13
- describe 'as_boolean' do
14
- specify { expect('true'.as_boolean).to be_truthy }
15
- specify { expect('yes'.as_boolean).to be_truthy }
16
- specify { expect('1'.as_boolean).to be_truthy }
17
- specify { expect('false'.as_boolean).to be_falsey }
18
- specify { expect('foo'.as_boolean).to be_falsey }
19
- end
20
-
21
- describe 'as_css_size' do
22
- specify { expect('50'.as_css_size).to eq '50px' }
23
- specify { expect(''.as_css_size).to eq '' }
24
- specify { expect('50px'.as_css_size).to eq '50px' }
25
- specify { expect('50%'.as_css_size).to eq '50%' }
26
- specify { expect('50em'.as_css_size).to eq '50em' }
27
- specify { expect('auto'.as_css_size).to eq 'auto' }
28
- specify { expect('inherit'.as_css_size).to eq 'inherit' }
29
- end
30
-
31
- describe 'sql_wildcard' do
32
- specify { expect('foobar'.sql_wildcard).to eq '%foobar%' }
33
- end
34
-
35
- describe 'replace_non_alphanumeric' do
36
- specify { expect('fo9o^()b ar'.replace_non_alphanumeric).to eq 'fo9obar' }
37
- specify { expect('fo9o^()b ar'.replace_non_alphanumeric('*')).to eq 'fo9o***b**ar' }
38
- end
39
-
40
- describe 'sanitize_filename' do
41
- specify { expect('foobar.doc'.sanitize_filename).to eq 'foobar.doc' }
42
- specify { expect('/user/home/foobar.doc'.sanitize_filename).to eq 'foobar.doc' }
43
- specify { expect('/user/home/f9o o(b+a^r.d*c'.sanitize_filename).to eq 'f9o_o_b_a_r.d_c' }
44
- end
45
-
46
- describe 'expand_url' do
47
- specify { expect('/home/foobar.doc'.expand_url).to eq '/home/foobar.doc' }
48
- specify { expect('/foobar.doc'.expand_url('/home/')).to eq '/foobar.doc' }
49
- specify { expect('foobar.doc'.expand_url).to eq '/foobar.doc' }
50
- specify { expect('foobar.doc'.expand_url('/home/')).to eq '/home/foobar.doc' }
51
- specify { expect('foobar.doc'.expand_url('/home')).to eq '/home/foobar.doc' }
52
- end
53
-
54
- describe 'absolute_url?' do
55
- specify { expect('/home/foo'.absolute_url?).to be_truthy }
56
- specify { expect('://home/foo'.absolute_url?).to be_truthy }
57
- specify { expect('home/foo'.absolute_url?).to be_falsey }
58
- end
59
-
60
- describe 'smart_titlecase' do
61
- specify do
62
- expect('a sample title and text: a treatsie'.smart_titlecase).to eq 'A Sample Title and Text: A Treatsie'
63
- end
64
- end
65
-
66
- describe 'smart_capitalize' do
67
- specify { expect('foobar'.smart_capitalize).to eq 'Foobar' }
68
- specify { expect('fooBar'.smart_capitalize).to eq 'fooBar' }
69
- specify { expect('(foobar)'.smart_capitalize).to eq '(Foobar)' }
70
- end
71
-
72
- describe 'smart_truncate' do
73
- specify do
74
- expect('One time. Two times. 3 times. 4 times.'.smart_truncate(sentences: 3))
75
- .to eq 'One time. Two times. 3 times...'
76
- end
77
- specify do
78
- expect('one two three and four five six and seven and yet another eight'.smart_truncate(words: 6))
79
- .to eq 'one two three and four five...'
80
- end
81
- specify do
82
- expect('one two three and four five six and seven and yet another eight'.smart_truncate)
83
- .to eq 'one two three and four five six and seven and yet another...'
84
- end
85
- end
86
-
87
- describe 'name_case' do
88
- before :each do
89
- @proper_names = [
90
- 'Keith', 'Leigh-Williams', 'McCarthy',
91
- "O'Callaghan", 'St. John', 'von Streit',
92
- 'van Dyke', 'Van', 'ap Llwyd Dafydd',
93
- 'al Fahd', 'Al',
94
- 'el Grecco',
95
- 'ben Gurion', 'Ben',
96
- 'da Vinci',
97
- 'di Caprio', 'du Pont', 'de Legate',
98
- 'del Crond', 'der Sind', 'van der Post',
99
- 'von Trapp', 'la Poisson', 'le Figaro',
100
- 'Mack Knife', 'Dougal MacDonald',
101
- # Mac exceptions
102
- 'Machin', 'Machlin', 'Machar',
103
- 'Mackle', 'Macklin', 'Mackie',
104
- 'Macquarie', 'Machado', 'Macevicius',
105
- 'Maciulis', 'Macias', 'MacMurdo',
106
- # Roman numerals
107
- 'Henry VIII', 'Louis III', 'Louis XIV',
108
- 'Charles II', 'Fred XLIX'
109
- ]
110
- end
111
-
112
- it 'handles each proper name' do
113
- @proper_names.each do |name|
114
- expect(name.downcase.name_case).to eq name
115
- expect(name.name_case).to eq name
116
- # assert_equal(name, NameCase(name))
117
- end
118
- end
119
-
120
- it 'handles multibyte' do
121
- proper_cased = 'Iñtërnâtiônàlizætiøn'
122
- expect(proper_cased.downcase.name_case).to eq proper_cased
123
- end
124
- end
125
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe Time do
7
- describe 'localize' do
8
- it 'localize the date based on the format' do
9
- I18n.enforce_available_locales = false
10
- I18n.locale = :en
11
- time = Time.parse('2012-11-23 08:35 utc')
12
- expect(time.localize).to eq 'Fri, 23 Nov 2012 08:35:00 +0000'
13
- expect(time.localize(format: :short)).to eq '23 Nov 08:35'
14
- expect(time.localize('%b %Y')).to eq 'Nov 2012'
15
- end
16
- end
17
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'dm_ruby_extensions'
5
-
6
- describe TrueClass do
7
- describe 'as_boolean' do
8
- specify { expect(true.as_boolean).to eq true }
9
- end
10
- end
data/spec/spec_helper.rb DELETED
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'pry-byebug'
4
- # This file was generated by the `rails generate rspec:install` command. Conventionally, all
5
- # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
- # The generated `.rspec` file contains `--require spec_helper` which will cause this
7
- # file to always be loaded, without a need to explicitly require it in any files.
8
- #
9
- # Given that it is always loaded, you are encouraged to keep this file as
10
- # light-weight as possible. Requiring heavyweight dependencies from this file
11
- # will add to the boot time of your test suite on EVERY test run, even for an
12
- # individual file that may not need all of that loaded. Instead, consider making
13
- # a separate helper file that requires the additional dependencies and performs
14
- # the additional setup, and require it from the spec files that actually need it.
15
- #
16
- # The `.rspec` file also contains a few flags that are not defaults but that
17
- # users commonly want.
18
- #
19
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
20
- RSpec.configure do |config|
21
- # rspec-expectations config goes here. You can use an alternate
22
- # assertion/expectation library such as wrong or the stdlib/minitest
23
- # assertions if you prefer.
24
- config.expect_with :rspec do |expectations|
25
- # This option will default to `true` in RSpec 4. It makes the `description`
26
- # and `failure_message` of custom matchers include text for helper methods
27
- # defined using `chain`, e.g.:
28
- # be_bigger_than(2).and_smaller_than(4).description
29
- # # => "be bigger than 2 and smaller than 4"
30
- # ...rather than:
31
- # # => "be bigger than 2"
32
- expectations.include_chain_clauses_in_custom_matcher_descriptions = true
33
- end
34
-
35
- # rspec-mocks config goes here. You can use an alternate test double
36
- # library (such as bogus or mocha) by changing the `mock_with` option here.
37
- config.mock_with :rspec do |mocks|
38
- # Prevents you from mocking or stubbing a method that does not exist on
39
- # a real object. This is generally recommended, and will default to
40
- # `true` in RSpec 4.
41
- mocks.verify_partial_doubles = true
42
- end
43
-
44
- # The settings below are suggested to provide a good initial experience
45
- # with RSpec, but feel free to customize to your heart's content.
46
- # # These two settings work together to allow you to limit a spec run
47
- # # to individual examples or groups you care about by tagging them with
48
- # # `:focus` metadata. When nothing is tagged with `:focus`, all examples
49
- # # get run.
50
- # config.filter_run :focus
51
- # config.run_all_when_everything_filtered = true
52
- #
53
- # # Limits the available syntax to the non-monkey patched syntax that is recommended.
54
- # # For more details, see:
55
- # # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
56
- # # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
57
- # # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
58
- # config.disable_monkey_patching!
59
- #
60
- # # Many RSpec users commonly either run the entire suite or an individual
61
- # # file, and it's useful to allow more verbose output when running an
62
- # # individual spec file.
63
- # if config.files_to_run.one?
64
- # # Use the documentation formatter for detailed output,
65
- # # unless a formatter has already been configured
66
- # # (e.g. via a command-line flag).
67
- # config.default_formatter = 'doc'
68
- # end
69
- #
70
- # # Print the 10 slowest examples and example groups at the
71
- # # end of the spec run, to help surface which specs are running
72
- # # particularly slow.
73
- # config.profile_examples = 10
74
- #
75
- # # Run specs in random order to surface order dependencies. If you find an
76
- # # order dependency and want to debug it, you can fix the order by providing
77
- # # the seed, which is printed after each run.
78
- # # --seed 1234
79
- # config.order = :random
80
- #
81
- # # Seed global randomization in this process using the `--seed` CLI option.
82
- # # Setting this allows you to use `--seed` to deterministically reproduce
83
- # # test failures related to randomization by passing the same `--seed` value
84
- # # as the one that triggered the failure.
85
- # Kernel.srand config.seed
86
- end