ruby-rails-extensions 2.1.0.pre.rc.13 → 2.1.0.pre.rc.14

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: fd0dcbe64c80a08c831af260bb6def15e0a56cb1643b02e9fde7f5904b3b4c37
4
- data.tar.gz: 37ea13e2a243425c5e5a224005d0c41434532c45ab68b65e6ce4d8f6e7dcea2a
3
+ metadata.gz: 6bb1c22291a4310b41703612c9eb72818974257e3ac06c6d76f6d8caca3d53ac
4
+ data.tar.gz: b28bc6aaf8bd702ded6500f8f828838d7a16eed7969c1c9f723a2ba69532ddd9
5
5
  SHA512:
6
- metadata.gz: b2c96c470d791ac8f4ea2dc3b6154a40e24c5bbd56a88375b2f905a5b5803d7bc96601c50e59ad94062c3b54d79d185c45e135b5e3e490230ef342eaa02eda40
7
- data.tar.gz: '09edbe71001ebad9138c4588333bad479084a96e8094170324330d4ce02fce34fa8d781da8c53877906b3701c95f5afa02d59e5e95f45e9c3aace6e95544f138'
6
+ metadata.gz: 770c01049b51f5bdc524692728d8b73fded477dbf647b7cd0a456e20545ab343d45a688e5b94d45625c5cfb17666f77dd292b5cc1685014cd117e9ddcdfd5b69
7
+ data.tar.gz: 19598110c5b11b9a85de6251fd0f5e269dd2e886695942627276de6139f363bcc498b93cc35f29691672a4fb8c00336fc2aec12ba3024e9df8f8f648499f4011
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-rc.14'
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.pre.rc.14
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