ruby-rails-extensions 2.1.0.pre.rc.13 → 2.1.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: fd0dcbe64c80a08c831af260bb6def15e0a56cb1643b02e9fde7f5904b3b4c37
4
- data.tar.gz: 37ea13e2a243425c5e5a224005d0c41434532c45ab68b65e6ce4d8f6e7dcea2a
3
+ metadata.gz: 3445f7f15fe0a736b52ccbaa2f176fd017b2b5fe0b58e42115a9a4d003599b32
4
+ data.tar.gz: 66ea1200362e7c25c1cb88496ac0273ba960a4ed3ed24d6ab8027fe867b0e014
5
5
  SHA512:
6
- metadata.gz: b2c96c470d791ac8f4ea2dc3b6154a40e24c5bbd56a88375b2f905a5b5803d7bc96601c50e59ad94062c3b54d79d185c45e135b5e3e490230ef342eaa02eda40
7
- data.tar.gz: '09edbe71001ebad9138c4588333bad479084a96e8094170324330d4ce02fce34fa8d781da8c53877906b3701c95f5afa02d59e5e95f45e9c3aace6e95544f138'
6
+ metadata.gz: 15599ad4fc3f8a9d17fa9d3ceefca301d91a257fc79763cd29a46ef52664278a8e947b4bd717b33f54fe3434a67c45c2debfaba209717bc808c4b1c4242660a6
7
+ data.tar.gz: 8a01c3eae7ecd21bc27fcfe34302a2dd33946e5b213037e4b41ce29a3c03241e2a17f058f1967b474485ef36617ccba5d01088b540487b13d4bafc8201c6c1d0
data/CHANGELOG.md CHANGED
@@ -11,6 +11,17 @@ Unreleased Changes
11
11
  * `FalseClass#to_d` and `TrueClass#to_d`
12
12
  * `Range#>`, `Range#<`, `Range#<=`, `Range#>=`
13
13
  * `Range#round`
14
+ * `Array#flatten_compact!` (`flat_pact!`)
15
+ * `Numeric#to_percentage`
16
+ * `Numeric#to_money` and `String#to_money`
17
+ * `String#to_delimited` and `Numeric#to_delimited` (alias `with_delimiter`)
18
+ * `String#utf8_encode!`, `String#utf8_encode`, and `String#safe_utf8_encode`
19
+ * `Time#quarter_str` and `DateTime#quarter_str`
20
+ * `String#to_new_date`, `String#to_new_date_safe`, and `String#to_new_date_mm_yy`
21
+ * `String#cutoff`
22
+ * Other changes:
23
+ * Initial test framework added
24
+ * Initial benchmark framework added
14
25
 
15
26
  2.0.1 (2024-07-29)
16
27
  ------------------
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  String.class_eval do
4
+ # @deprecated Use {String#utf8_encode!} instead
4
5
  # Remove all non-UTF-8 chars from a string.
5
6
  #
6
7
  # @param replace_with [String, nil] What to replace invalid chars with.
@@ -8,14 +9,20 @@ String.class_eval do
8
9
  # @return [String]
9
10
  #
10
11
  def clean!(replace_with = '')
12
+ utf8_encode_dep_warn('clean!')
13
+
11
14
  replace(encode('UTF-8', invalid: :replace, undef: :replace, replace: replace_with))
12
15
  end
13
16
 
17
+ # @deprecated Use {String#utf8_encode} instead
14
18
  # @see {#clean!}
15
19
  def clean(replace_with = '')
20
+ utf8_encode_dep_warn('clean')
21
+
16
22
  dup.clean!(replace_with)
17
23
  end
18
24
 
25
+ # @deprecated Use {String#utf8_encode!} instead
19
26
  # Remove all non-UTF-8 chars from a string and convert to binary.
20
27
  #
21
28
  # @param replace_with [String, nil] What to replace invalid chars with.
@@ -23,11 +30,32 @@ String.class_eval do
23
30
  # @return [String]
24
31
  #
25
32
  def clean_binary!(replace_with = '')
33
+ utf8_encode_dep_warn('clean_binary!')
34
+
26
35
  replace(encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: replace_with))
27
36
  end
28
37
 
38
+ # @deprecated Use {String#utf8_encode} instead
29
39
  # @see {#clean_binary!}
30
40
  def clean_binary(replace_with = '')
41
+ utf8_encode_dep_warn('clean_binary!')
42
+
31
43
  dup.clean_binary!(replace_with)
32
44
  end
45
+
46
+ private
47
+
48
+ # Triggers a deprecation warning
49
+ #
50
+ # @param method_name [String]
51
+ # @param projected_version [String] Projected version methods will
52
+ # be removed / no longer supported.
53
+ #
54
+ # @return [void]
55
+ #
56
+ def utf8_encode_dep_warn(method_name, projected_version = '3.0')
57
+ dep = ActiveSupport::Deprecation.new(projected_version, 'ruby-rails-extensions')
58
+
59
+ dep.warn("#{method_name} is deprecated and will be removed from ruby-rails-extensions #{projected_version}")
60
+ end
33
61
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'active_support/core_ext/string/filters'
5
+ require 'active_support/core_ext/string/output_safety'
6
+
7
+ String.class_eval do
8
+ # Cuts off a long string and will add an ellipsis or
9
+ # what has been entered via +:end_more+ option.
10
+ #
11
+ # @param max [Integer] Max string length in characters
12
+ # @param options [Hash]
13
+ #
14
+ # @option options [Boolean] :ending This will add the
15
+ # ellipsis in the middle of the word instead of the
16
+ # end, which will show the start and end of the string.
17
+ #
18
+ # @option options [String] :end_more Instead of showing
19
+ # and ellipsis at the end of the string, it will show
20
+ # this string. This will be counted against the max
21
+ # and will only show up once the max is hit.
22
+ # *This is ignored when +:ending+ enabled.*
23
+ #
24
+ # @return [String]
25
+ #
26
+ def cutoff(max = 60, options = {})
27
+ this = self
28
+ max_len = (max || 60).to_i
29
+ opts = { ending: false, end_more: nil }.merge(options || {})
30
+
31
+ # Return the string if it isn't over the max
32
+ return this if this.size < max_len
33
+
34
+ end_chars = opts[:end_more].present? ? opts[:end_more] : '...'
35
+
36
+ unless opts[:ending]
37
+ return this.truncate(max_len, { omission: end_chars }).html_safe
38
+ end
39
+
40
+ start_val = ((max_len - 3) / 2).round
41
+ end_val = max_len - start_val
42
+
43
+ "#{this[0, start_val]}...#{this[-end_val, this.size]}".html_safe
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/time_with_zone'
5
+
6
+ module QuarterStrMethods
7
+ # Returns the quarter and year using the following template:
8
+ # <quarter_number>Q<quarter_year(yy)>
9
+ #
10
+ # @return [String]
11
+ #
12
+ def quarter_str
13
+ "#{(month / 3.0).ceil}Q#{strftime('%y')}"
14
+ end
15
+ end
16
+
17
+ DateTime.class_eval do
18
+ include QuarterStrMethods
19
+ end
20
+
21
+ Time.class_eval do
22
+ include QuarterStrMethods
23
+ end
24
+
25
+ ActiveSupport::TimeWithZone.class_eval do
26
+ include QuarterStrMethods
27
+ end
@@ -26,7 +26,7 @@ String.class_eval do
26
26
  # @deprecated This alias is only for Atlas and will be removed in future versions
27
27
  alias_method :with_sep, :to_delimited
28
28
 
29
- deprecate :with_sep, deprecator: ActiveSupport::Deprecation.new('4.0', 'ruby-rails-extensions')
29
+ deprecate :with_sep, deprecator: ActiveSupport::Deprecation.new('3.0', 'ruby-rails-extensions')
30
30
  end
31
31
 
32
32
  Numeric.class_eval do
@@ -18,3 +18,10 @@ Numeric.class_eval do
18
18
  number_to_currency(to_d, options)
19
19
  end
20
20
  end
21
+
22
+ String.class_eval do
23
+ # @see Numeric#to_money
24
+ def to_money(...)
25
+ to_d.to_money(...)
26
+ end
27
+ end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/core_ext/date'
5
+ require 'active_support/core_ext/time'
6
+
7
+ module StringToNewDate
8
+ NEW_DATE_REGEXES = {
9
+ # MM DD YYYY
10
+ mm_dd_yyyy: /\A\d{2}\D?\d{2}\D?\d{4}\z/,
11
+ # YYYY MM DD
12
+ yyyy_mm_dd: /\A\d{4}\D?\d{2}\D?\d{2}\z/,
13
+ # MM DD YY
14
+ mm_dd_yy: /\A\d{2}\D?\d{2}\D?\d{2}\z/,
15
+ # (M)M (D)D (YY)YY
16
+ m_d_yy: %r{\A(\d{1,2})[-|/](\d{1,2})[-|/](\d+)\z},
17
+ # M(M) YY(YY)
18
+ m_yy: %r{\A(\d{1,2})[-/](\d{2,4})\z}
19
+ }.freeze
20
+
21
+ # Converts a string to a date object when following one of the
22
+ # following patterns (no space delimiters):
23
+ # - MM-DD-YYYY
24
+ # - YYYY-MM-DD
25
+ # - MM-DD-YY
26
+ # - (M)M-(D)D-(YY)YY => "()" optional values
27
+ #
28
+ # @param options [Hash]
29
+ #
30
+ # @option options [Boolean] :return_orig If +true+, the non-converted
31
+ # string will be returned instead of +nil+. Default is to return
32
+ # +nil+ when conversion fails.
33
+ # @option options [String] :quarter If date extraction successful,
34
+ # the date will be converted to the beginning or ending of the
35
+ # quarter. Accepts: 'begin(ning)' and 'end(ing)'
36
+ #
37
+ # @return [Date, String, nil]
38
+ #
39
+ def to_new_date(options = {})
40
+ opts = {
41
+ return_orig: false,
42
+ quarter: nil
43
+ }.merge(options || {})
44
+
45
+ new_date = extract_date
46
+
47
+ if new_date.nil?
48
+ return opts[:return_orig] ? self : nil
49
+ end
50
+
51
+ if opts[:quarter].to_s.match?(/begin/i)
52
+ return new_date.beginning_of_quarter
53
+ end
54
+
55
+ if opts[:quarter].to_s.match?(/end/i)
56
+ return new_date.end_of_quarter
57
+ end
58
+
59
+ new_date
60
+ end
61
+
62
+ # Recovers from any error when calling {#to_new_date}
63
+ def to_new_date_safe(...)
64
+ to_new_date(...)
65
+ rescue
66
+ nil
67
+ end
68
+
69
+ # Converts a string to a date object. The only pattern
70
+ # accepted: 'MM YY'
71
+ #
72
+ # @see #to_new_date
73
+ #
74
+ # @return [Date, nil]
75
+ #
76
+ def to_new_date_mm_yy
77
+ return unless NEW_DATE_REGEXES[:m_yy].match?(self)
78
+
79
+ m_yy_date
80
+ end
81
+
82
+ private
83
+
84
+ # Checks the string for any supported format,
85
+ # then converts the string to a new date.
86
+ #
87
+ # @return [Date, nil]
88
+ #
89
+ def extract_date
90
+ key = NEW_DATE_REGEXES.find { |_key, value| match?(value) }&.first
91
+
92
+ return if key.nil?
93
+
94
+ __send__(:"#{key}_date")
95
+ end
96
+
97
+ # @return [Date]
98
+ def mm_dd_yyyy_date
99
+ Date.new(scan(/\d{4}/).first.to_i, scan(/\d{2}/).first.to_i, scan(/\d{2}/)[1].to_i)
100
+ end
101
+
102
+ # @return [Date]
103
+ def yyyy_mm_dd_date
104
+ Date.new(scan(/\d{4}/).first.to_i, scan(/\d{2}/)[2].to_i, scan(/\d{2}/)[3].to_i)
105
+ end
106
+
107
+ # @return [Date]
108
+ def mm_dd_yy_date
109
+ Date.new("20#{scan(/\d{2}/)[2]}".to_i, scan(/\d{2}/).first.to_i, scan(/\d{2}/)[1].to_i)
110
+ end
111
+
112
+ # @return [Date]
113
+ def m_d_yy_date
114
+ numbers = NEW_DATE_REGEXES[:m_d_yy].match(self)
115
+
116
+ year =
117
+ case numbers[3].size
118
+ when 2
119
+ "20#{numbers[3]}".to_i
120
+ when 4
121
+ numbers[3].to_i
122
+ end
123
+
124
+ return if year.nil?
125
+
126
+ Date.new(year, numbers[1].to_i, numbers[2].to_i)
127
+ end
128
+
129
+ # @return [Date]
130
+ def m_yy_date
131
+ numbers = NEW_DATE_REGEXES[:m_yy].match(self)
132
+
133
+ year =
134
+ case numbers[2].size
135
+ when 2
136
+ "20#{numbers[2]}".to_i
137
+ when 4
138
+ numbers[2].to_i
139
+ end
140
+
141
+ return if year.nil?
142
+
143
+ Date.new(year, numbers[1].to_i, 1)
144
+ end
145
+ end
146
+
147
+ String.class_eval do
148
+ include StringToNewDate
149
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/deprecation'
5
+
6
+ String.class_eval do
7
+ # Remove all non-UTF-8 chars from a string.
8
+ #
9
+ # @raise [Encoding::UndefinedConversionError] Failed to encode string
10
+ #
11
+ # @example
12
+ #
13
+ # "^\u{0000}-\u{007F}".utf8_encode
14
+ # # => "^\u0000-\u007F"
15
+ #
16
+ # @param binary [Boolean]
17
+ #
18
+ # @return [void]
19
+ #
20
+ def utf8_encode!(binary: true, **kwargs)
21
+ if binary
22
+ return replace(utf8_encode_str(self, 'binary', kwargs))
23
+ end
24
+
25
+ replace(utf8_encode_str(self, kwargs))
26
+ end
27
+
28
+ # @see #utf8_encode!
29
+ #
30
+ # @return [String]
31
+ #
32
+ def utf8_encode(**kwargs)
33
+ dup.utf8_encode!(**kwargs)
34
+ end
35
+
36
+ # Safely calls {#utf8_encode} with a rescue that will catch
37
+ # all errors.
38
+ #
39
+ # @return [String, nil]
40
+ #
41
+ def safe_utf8_encode(**kwargs)
42
+ utf8_encode(**kwargs)
43
+ rescue
44
+ nil
45
+ end
46
+
47
+ private
48
+
49
+ # Wrapper for {#Encoding.default_internal} using {#String.encode}.
50
+ #
51
+ # @see https://ruby-doc.org/core-3.0.1/String.html#method-i-encode
52
+ # @see https://ruby-doc.org/core-3.0.1/Encoding.html#method-c-default_internal
53
+ #
54
+ # @overload utf8_encode(str, src_encoding, options = {})
55
+ # @param str [String] The string to be encoded.
56
+ # @param src_encoding [String] The SRC encoding value.
57
+ # @param options [Hash]
58
+ #
59
+ # @overload utf8_encode(str, options = {})
60
+ # @param src_encoding [String] The SRC encoding value.
61
+ # @param options [Hash]
62
+ #
63
+ # @return [String]
64
+ #
65
+ def utf8_encode_str(str, src_or_options = nil, options = nil)
66
+ default_options = {
67
+ invalid: :replace,
68
+ undef: :replace,
69
+ replace: ''
70
+ }
71
+
72
+ src_encode, opts =
73
+ if src_or_options.is_a?(Hash)
74
+ [src_or_options.reverse_merge(default_options), nil]
75
+ else
76
+ [src_or_options, (options.presence || {}).reverse_merge(default_options)]
77
+ end
78
+
79
+ if opts.nil?
80
+ return str.to_s.encode(Encoding::UTF_8, **src_encode)
81
+ end
82
+
83
+ str.to_s.encode(Encoding::UTF_8, src_encode, **opts)
84
+ end
85
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyRailsExtensions
4
- VERSION = '2.1.0-rc.13'
4
+ VERSION = '2.1.0'
5
5
  end
@@ -19,6 +19,7 @@ module RubyRailsExtensions
19
19
  current_day
20
20
  current_month
21
21
  current_week
22
+ cutoff
22
23
  day_of_week
23
24
  display_military
24
25
  display_user
@@ -43,6 +44,7 @@ module RubyRailsExtensions
43
44
  pipe
44
45
  presence_bang
45
46
  quarter_dates
47
+ quarter_str
46
48
  range_add
47
49
  range_comparisons
48
50
  range_multiply
@@ -60,6 +62,7 @@ module RubyRailsExtensions
60
62
  to_local
61
63
  to_money
62
64
  to_negative_i
65
+ to_new_date
63
66
  to_nonzero_i
64
67
  to_or_sentence
65
68
  to_percentage
@@ -70,6 +73,7 @@ module RubyRailsExtensions
70
73
  uniq_map
71
74
  usd_to_f
72
75
  usd_to_i
76
+ utf8_encode
73
77
  weighted_sum
74
78
  yesno
75
79
  zero_range
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-rails-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0.pre.rc.13
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brands Insurance
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-08 00:00:00.000000000 Z
11
+ date: 2024-10-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -33,6 +33,7 @@ files:
33
33
  - lib/ruby-rails-extensions/extensions/current_day.rb
34
34
  - lib/ruby-rails-extensions/extensions/current_month.rb
35
35
  - lib/ruby-rails-extensions/extensions/current_week.rb
36
+ - lib/ruby-rails-extensions/extensions/cutoff.rb
36
37
  - lib/ruby-rails-extensions/extensions/day_of_week.rb
37
38
  - lib/ruby-rails-extensions/extensions/display_military.rb
38
39
  - lib/ruby-rails-extensions/extensions/display_user.rb
@@ -57,6 +58,7 @@ files:
57
58
  - lib/ruby-rails-extensions/extensions/pipe.rb
58
59
  - lib/ruby-rails-extensions/extensions/presence_bang.rb
59
60
  - lib/ruby-rails-extensions/extensions/quarter_dates.rb
61
+ - lib/ruby-rails-extensions/extensions/quarter_str.rb
60
62
  - lib/ruby-rails-extensions/extensions/range_add.rb
61
63
  - lib/ruby-rails-extensions/extensions/range_comparisons.rb
62
64
  - lib/ruby-rails-extensions/extensions/range_multiply.rb
@@ -74,6 +76,7 @@ files:
74
76
  - lib/ruby-rails-extensions/extensions/to_local.rb
75
77
  - lib/ruby-rails-extensions/extensions/to_money.rb
76
78
  - lib/ruby-rails-extensions/extensions/to_negative_i.rb
79
+ - lib/ruby-rails-extensions/extensions/to_new_date.rb
77
80
  - lib/ruby-rails-extensions/extensions/to_nonzero_i.rb
78
81
  - lib/ruby-rails-extensions/extensions/to_or_sentence.rb
79
82
  - lib/ruby-rails-extensions/extensions/to_percentage.rb
@@ -84,6 +87,7 @@ files:
84
87
  - lib/ruby-rails-extensions/extensions/uniq_map.rb
85
88
  - lib/ruby-rails-extensions/extensions/usd_to_f.rb
86
89
  - lib/ruby-rails-extensions/extensions/usd_to_i.rb
90
+ - lib/ruby-rails-extensions/extensions/utf8_encode.rb
87
91
  - lib/ruby-rails-extensions/extensions/weighted_sum.rb
88
92
  - lib/ruby-rails-extensions/extensions/yesno.rb
89
93
  - lib/ruby-rails-extensions/extensions/zero_range.rb
@@ -105,9 +109,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
109
  version: 3.0.1
106
110
  required_rubygems_version: !ruby/object:Gem::Requirement
107
111
  requirements:
108
- - - ">"
112
+ - - ">="
109
113
  - !ruby/object:Gem::Version
110
- version: 1.3.1
114
+ version: '0'
111
115
  requirements: []
112
116
  rubygems_version: 3.2.15
113
117
  signing_key: