normalizy 0.1.0 → 0.2.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +379 -32
  4. data/lib/normalizy/config.rb +7 -3
  5. data/lib/normalizy/extensions.rb +11 -7
  6. data/lib/normalizy/filters/date.rb +44 -0
  7. data/lib/normalizy/filters/money.rb +38 -0
  8. data/lib/normalizy/filters/number.rb +4 -3
  9. data/lib/normalizy/filters/percent.rb +38 -0
  10. data/lib/normalizy/rspec/matcher.rb +2 -0
  11. data/lib/normalizy/version.rb +1 -1
  12. data/spec/normalizy/config/add_spec.rb +3 -0
  13. data/spec/normalizy/config/alias_spec.rb +7 -13
  14. data/spec/normalizy/config/initialize_spec.rb +5 -2
  15. data/spec/normalizy/config/normalizy_raws_spec.rb +1 -1
  16. data/spec/normalizy/extensions/{apply_normalizations_spec.rb → apply_normalizy_spec.rb} +36 -28
  17. data/spec/normalizy/extensions/filters/date_spec.rb +34 -0
  18. data/spec/normalizy/extensions/filters/money_spec.rb +40 -0
  19. data/spec/normalizy/extensions/filters/number_spec.rb +13 -0
  20. data/spec/normalizy/extensions/filters/percent_spec.rb +40 -0
  21. data/spec/normalizy/extensions/filters/strip_spec.rb +21 -0
  22. data/spec/normalizy/extensions/normalizy_rules_spec.rb +1 -1
  23. data/spec/normalizy/filters/date_spec.rb +56 -0
  24. data/spec/normalizy/filters/money_spec.rb +155 -0
  25. data/spec/normalizy/filters/number_spec.rb +25 -9
  26. data/spec/normalizy/filters/percent_spec.rb +155 -0
  27. data/spec/rails_helper.rb +4 -0
  28. data/spec/support/db/schema.rb +8 -3
  29. data/spec/support/filters/blacklist_1.rb +11 -0
  30. data/spec/support/filters/blacklist_2.rb +13 -0
  31. data/spec/support/filters/blacklist_block.rb +11 -0
  32. data/spec/support/models/user.rb +1 -1
  33. metadata +29 -8
  34. data/spec/normalizy/extensions/normalizy_spec.rb +0 -11
  35. data/spec/support/filters/blacklist_filter.rb +0 -15
@@ -3,14 +3,15 @@
3
3
  module Normalizy
4
4
  module Filters
5
5
  module Number
6
- def self.call(input)
6
+ def self.call(input, options = {})
7
7
  return input unless input.is_a?(String)
8
8
 
9
9
  value = input.gsub(/\D/, '')
10
10
 
11
- return nil if value.blank?
11
+ return nil if value.blank?
12
+ return value.send(options[:cast]) if options[:cast]
12
13
 
13
- value.to_i
14
+ value
14
15
  end
15
16
  end
16
17
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Normalizy
4
+ module Filters
5
+ module Percent
6
+ class << self
7
+ def call(input, options = {})
8
+ return input unless input.is_a?(String)
9
+
10
+ value = input.gsub(/[^[0-9]#{separator(options)}]/, '')
11
+
12
+ return nil if value.blank?
13
+
14
+ value = "%0.#{precision(options)}f" % [value.sub(separator(options), '.')]
15
+ value = value.delete('.') if cents?(options)
16
+
17
+ return value.send(options[:cast]) if options[:cast]
18
+
19
+ value
20
+ end
21
+
22
+ private
23
+
24
+ def cents?(options)
25
+ options[:type]&.to_sym == :cents
26
+ end
27
+
28
+ def precision(options)
29
+ options.fetch :precision, I18n.t('percentage.format.precision', default: 2)
30
+ end
31
+
32
+ def separator(options)
33
+ options.fetch :separator, I18n.t('percentage.format.separator', default: '.')
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Normalizy
2
4
  module RSpec
3
5
  def normalizy(attribute)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Normalizy
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -10,7 +10,10 @@ RSpec.describe Normalizy::Config, '#add' do
10
10
 
11
11
  expect(Normalizy.config.filters).to eq(
12
12
  blacklist: :blacklist_filter,
13
+ date: Normalizy::Filters::Date,
14
+ money: Normalizy::Filters::Money,
13
15
  number: Normalizy::Filters::Number,
16
+ percent: Normalizy::Filters::Percent,
14
17
  strip: Normalizy::Filters::Strip
15
18
  )
16
19
  end
@@ -24,39 +24,33 @@ RSpec.describe Normalizy::Config, '#alias' do
24
24
  end
25
25
 
26
26
  context 'with raw type' do
27
- let!(:object) { User.new amount: 'R$ 4.200,00' }
28
-
29
- before { object.class.normalizy_rules = {} }
27
+ before { User.normalizy_rules = {} }
30
28
 
31
29
  context 'configured on setup' do
32
30
  before do
33
31
  Normalizy.configure do |config|
34
- config.alias :money, :number, raw: true
32
+ config.alias :age, :number, raw: true
35
33
  end
36
34
  end
37
35
 
38
36
  it 'alias one filter to others' do
39
- object.class.normalizy :amount, with: :money
40
-
41
- object.save
37
+ User.normalizy :age, with: :age
42
38
 
43
- expect(object.amount).to eq 420_000
39
+ expect(User.create(age: '= 42').age).to eq 42
44
40
  end
45
41
  end
46
42
 
47
43
  context 'configured on normalizy' do
48
44
  before do
49
45
  Normalizy.configure do |config|
50
- config.alias :money, :number
46
+ config.alias :age, :number
51
47
  end
52
48
  end
53
49
 
54
50
  it 'alias one filter to others' do
55
- object.class.normalizy :amount, with: :money, raw: true
56
-
57
- object.save
51
+ User.normalizy :age, with: :age, raw: true
58
52
 
59
- expect(object.amount).to eq 420_000
53
+ expect(User.create(age: '= 42').age).to eq 42
60
54
  end
61
55
  end
62
56
  end
@@ -5,8 +5,11 @@ require 'rails_helper'
5
5
  RSpec.describe Normalizy::Config, 'filters' do
6
6
  it 'loads some filters' do
7
7
  expect(subject.filters).to eq(
8
- number: Normalizy::Filters::Number,
9
- strip: Normalizy::Filters::Strip
8
+ date: Normalizy::Filters::Date,
9
+ money: Normalizy::Filters::Money,
10
+ number: Normalizy::Filters::Number,
11
+ percent: Normalizy::Filters::Percent,
12
+ strip: Normalizy::Filters::Strip
10
13
  )
11
14
  end
12
15
  end
@@ -4,6 +4,6 @@ require 'rails_helper'
4
4
 
5
5
  RSpec.describe Normalizy::Config, 'normalizy_raws' do
6
6
  it 'has the right defaults' do
7
- expect(subject.normalizy_raws).to eq [:number]
7
+ expect(subject.normalizy_raws).to eq %i[date money number percent]
8
8
  end
9
9
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'rails_helper'
4
4
 
5
- RSpec.describe '#apply_normalizations' do
5
+ RSpec.describe '#apply_normalizy' do
6
6
  context 'when object has no normalizy' do
7
7
  let!(:object) { Clean.create name: ' washington Botelho ' }
8
8
 
@@ -16,7 +16,7 @@ RSpec.describe '#apply_normalizations' do
16
16
 
17
17
  before { object.class.normalizy_rules = {} }
18
18
 
19
- context 'when a rule is not given' do
19
+ context 'when a filter is not given' do
20
20
  context 'and no block' do
21
21
  before do
22
22
  Normalizy.configure do |config|
@@ -36,12 +36,6 @@ RSpec.describe '#apply_normalizations' do
36
36
  context 'but block is' do
37
37
  let!(:block) { ->(value) { value.upcase } }
38
38
 
39
- before do
40
- Normalizy.configure do |config|
41
- config.add :blacklist, Normalizy::Filters::Blacklist
42
- end
43
- end
44
-
45
39
  it 'executes the block' do
46
40
  object.class.normalizy :name, with: block
47
41
 
@@ -52,8 +46,8 @@ RSpec.describe '#apply_normalizations' do
52
46
  end
53
47
  end
54
48
 
55
- context 'when a rule is given' do
56
- context 'as symbol format' do
49
+ context 'when a filter is given' do
50
+ context 'as a symbol' do
57
51
  before { object.class.normalizy :name, with: :squish }
58
52
 
59
53
  specify do
@@ -63,7 +57,7 @@ RSpec.describe '#apply_normalizations' do
63
57
  end
64
58
  end
65
59
 
66
- context 'as array of symbol format' do
60
+ context 'as array of symbol' do
67
61
  before { object.class.normalizy :name, with: [:squish] }
68
62
 
69
63
  specify do
@@ -73,21 +67,21 @@ RSpec.describe '#apply_normalizations' do
73
67
  end
74
68
  end
75
69
 
76
- context 'as a hash format' do
77
- context 'and filter does not receives options' do
78
- before { object.class.normalizy :name, with: { squish: :options } }
70
+ context 'as a hash' do
71
+ context 'with a filter that does not accepts options' do
72
+ before { object.class.normalizy :name, with: { squish: { ignored: true } } }
79
73
 
80
- specify do
74
+ it 'executes the filter ignoring the options' do
81
75
  object.save
82
76
 
83
77
  expect(object.name).to eq 'Washington Fuck Botelho'
84
78
  end
85
79
  end
86
80
 
87
- context 'and filter receives options' do
81
+ context 'with a filter that accepts options' do
88
82
  before { object.class.normalizy :name, with: { strip: { side: :left } } }
89
83
 
90
- specify do
84
+ it 'executes the filter with given options' do
91
85
  object.save
92
86
 
93
87
  expect(object.name).to eq 'Washington Fuck Botelho '
@@ -96,12 +90,26 @@ RSpec.describe '#apply_normalizations' do
96
90
  end
97
91
 
98
92
  context 'as a module' do
99
- before { object.class.normalizy :name, with: Normalizy::Filters::Blacklist }
93
+ context 'with just one arg (input)' do
94
+ before { object.class.normalizy :name, with: Normalizy::Filters::Blacklist1 }
100
95
 
101
- specify do
102
- object.save
96
+ it 'receives the input value' do
97
+ object.save
103
98
 
104
- expect(object.name).to eq ' Washington filtered Botelho '
99
+ expect(object.name).to eq ' Washington filtered Botelho '
100
+ end
101
+ end
102
+
103
+ context 'with two args (input, options) with' do
104
+ before do
105
+ object.class.normalizy :name, with: Normalizy::Filters::Blacklist2
106
+ end
107
+
108
+ it 'receives the input value with options' do
109
+ object.save
110
+
111
+ expect(object.name).to eq 'name: Washington Fuck Botelho '
112
+ end
105
113
  end
106
114
  end
107
115
 
@@ -110,7 +118,7 @@ RSpec.describe '#apply_normalizations' do
110
118
 
111
119
  before do
112
120
  Normalizy.configure do |config|
113
- config.add :blacklist, Normalizy::Filters::Blacklist
121
+ config.add :blacklist, Normalizy::Filters::BlacklistBlock
114
122
  end
115
123
  end
116
124
 
@@ -119,7 +127,7 @@ RSpec.describe '#apply_normalizations' do
119
127
 
120
128
  object.save
121
129
 
122
- expect(object.name).to eq ' WASHINGTON FILTERED BOTELHO '
130
+ expect(object.name).to eq ' WASHINGTON FUCK BOTELHO '
123
131
  end
124
132
  end
125
133
  end
@@ -127,22 +135,22 @@ RSpec.describe '#apply_normalizations' do
127
135
  context 'when no filter match' do
128
136
  context 'and object has a method that responds' do
129
137
  context 'with no options on rule' do
130
- it 'runs the native method with empty options' do
138
+ it 'runs the class method with self object on options' do
131
139
  object.class.normalizy :name, with: :custom_reverse
132
140
 
133
141
  object.save
134
142
 
135
- expect(object.name).to eq ' ohletoB kcuF notgnihsaW .{}.custom'
143
+ expect(object.name).to eq "' ohletoB kcuF notgnihsaW ' to ' Washington Fuck Botelho '"
136
144
  end
137
145
  end
138
146
 
139
147
  context 'with no options on rule' do
140
- it 'runs the native method with given options' do
141
- object.class.normalizy :name, with: { custom_reverse: :options }
148
+ it 'runs the class method with given options and self object on it' do
149
+ object.class.normalizy :name, with: { custom_reverse: {} }
142
150
 
143
151
  object.save
144
152
 
145
- expect(object.name).to eq ' ohletoB kcuF notgnihsaW .options.custom'
153
+ expect(object.name).to eq "' ohletoB kcuF notgnihsaW ' to ' Washington Fuck Botelho '"
146
154
  end
147
155
  end
148
156
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe User, 'filters:date' do
6
+ before do
7
+ described_class.normalizy_rules = {}
8
+ end
9
+
10
+ specify do
11
+ described_class.normalizy :birthday, with: :date
12
+
13
+ expected = Time.new(1984, 10, 23, 0, 0, 0, 0)
14
+
15
+ expect(described_class.create(birthday: '1984-10-23').birthday).to eq expected
16
+ end
17
+
18
+ specify do
19
+ described_class.normalizy :birthday, with: { date: { format: '%y/%m/%d' } }
20
+
21
+ expected = Time.new(1984, 10, 23, 0, 0, 0, 0)
22
+
23
+ expect(described_class.create(birthday: '84/10/23').birthday).to eq expected
24
+ end
25
+
26
+ specify do
27
+ described_class.normalizy :birthday, with: { date: { time_zone: 'Brasilia' } }
28
+
29
+ hours = offset_in_hours('America/Sao_Paulo')
30
+ expected = Time.new(1984, 10, 23, 0, 0, 0, 0) + (hours.hours * -1)
31
+
32
+ expect(described_class.create(birthday: '1984-10-23').birthday).to eq expected
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe User, 'filters:money' do
6
+ before do
7
+ described_class.normalizy_rules = {}
8
+ end
9
+
10
+ specify do
11
+ described_class.normalizy :amount_text, with: :money
12
+
13
+ expect(described_class.create(amount_text: '$ 42.00').amount_text).to eq '42.00'
14
+ expect(described_class.create(amount_text: '$ 42.10').amount_text).to eq '42.10'
15
+ end
16
+
17
+ specify do
18
+ described_class.normalizy :amount_cents, with: { money: { type: :cents } }
19
+
20
+ expect(described_class.create(amount_cents: '$ 42.33').amount_cents).to be 4233
21
+ end
22
+
23
+ specify do
24
+ described_class.normalizy :amount_cents, with: { money: { cast: :to_i } }
25
+
26
+ expect(described_class.create(amount_cents: '$ 42.00').amount_cents).to be 42
27
+ end
28
+
29
+ specify do
30
+ described_class.normalizy :amount, with: { money: { cast: :to_d } }
31
+
32
+ expect(described_class.create(amount: '$ 1.23').amount).to eq 1.23.to_d
33
+ end
34
+
35
+ specify do
36
+ described_class.normalizy :amount, with: { money: { cast: :to_f, type: :cents } }
37
+
38
+ expect(described_class.create(amount: '$ 42.00').amount).to eq 4200.0.to_f
39
+ end
40
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe User, 'filters:number' do
6
+ before { described_class.normalizy_rules = {} }
7
+
8
+ specify do
9
+ described_class.normalizy :name, with: :number
10
+
11
+ expect(described_class.create(name: 'Washington 32').name).to eq '32'
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe User, 'filters:percent' do
6
+ before do
7
+ described_class.normalizy_rules = {}
8
+ end
9
+
10
+ specify do
11
+ described_class.normalizy :amount_text, with: :percent
12
+
13
+ expect(described_class.create(amount_text: '42.00 %').amount_text).to eq '42.00'
14
+ expect(described_class.create(amount_text: '42.10 %').amount_text).to eq '42.10'
15
+ end
16
+
17
+ specify do
18
+ described_class.normalizy :amount_cents, with: { percent: { type: :cents } }
19
+
20
+ expect(described_class.create(amount_cents: '42.33 %').amount_cents).to be 4233
21
+ end
22
+
23
+ specify do
24
+ described_class.normalizy :amount_cents, with: { percent: { cast: :to_i } }
25
+
26
+ expect(described_class.create(amount_cents: '42.00 %').amount_cents).to be 42
27
+ end
28
+
29
+ specify do
30
+ described_class.normalizy :amount, with: { percent: { cast: :to_d } }
31
+
32
+ expect(described_class.create(amount: '1.23 %').amount).to eq 1.23.to_d
33
+ end
34
+
35
+ specify do
36
+ described_class.normalizy :amount, with: { percent: { cast: :to_f, type: :cents } }
37
+
38
+ expect(described_class.create(amount: '42.00 %').amount).to eq 4200.0.to_f
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe User, 'filters:strip' do
6
+ before do
7
+ described_class.normalizy_rules = {}
8
+ end
9
+
10
+ specify do
11
+ described_class.normalizy :name, with: :strip
12
+
13
+ expect(described_class.create(name: ' Washington ').name).to eq 'Washington'
14
+ end
15
+
16
+ specify do
17
+ described_class.normalizy :name, with: { strip: { side: :left } }
18
+
19
+ expect(described_class.create(name: ' Washington ').name).to eq 'Washington '
20
+ end
21
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'rails_helper'
4
4
 
5
- RSpec.describe Normalizy::Extension, '#normalizy_rules' do
5
+ RSpec.describe Normalizy::Extension, ':normalizy_rules' do
6
6
  let!(:model) { User }
7
7
 
8
8
  before { model.normalizy_rules = {} }
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Normalizy::Filters::Date do
6
+ it { expect(subject.call('')).to eq '' }
7
+
8
+ it { expect(subject.call('1984-10-23')).to eq Time.new(1984, 10, 23, 0, 0, 0, 0) }
9
+
10
+ it { expect(subject.call('84/10/23', format: '%y/%m/%d')).to eq Time.new(1984, 10, 23, 0, 0, 0, 0) }
11
+
12
+ it { expect(subject.call('84/10/23', format: '%y/%m/%d')).to eq Time.new(1984, 10, 23, 0, 0, 0, 0) }
13
+
14
+ it { expect(subject.call(Time.new(1984, 10, 23), adjust: :end)).to eq Time.new(1984, 10, 23).end_of_day }
15
+ it { expect(subject.call(Time.new(1984, 10, 23, 1), adjust: :begin)).to eq Time.new(1984, 10, 23).beginning_of_day }
16
+
17
+ it 'accepts time zone' do
18
+ time = subject.call('1984-10-23', time_zone: 'Tokelau Is.').utc
19
+
20
+ expect(time).to eq Time.new(1984, 10, 23, time.hour, 0, 0, 0)
21
+ end
22
+
23
+ context 'with invalid date' do
24
+ let!(:object) { User.new }
25
+ let!(:options) { { attribute: :birthday, object: object } }
26
+
27
+ context 'with i18n present' do
28
+ before do
29
+ allow(I18n).to receive(:t).with(:birthday,
30
+ scope: ['normalizy.errors.date', 'user'],
31
+ value: '1984-10-00',
32
+ default: '%{value} is an invalid date.') { 'birthday.error' }
33
+ end
34
+
35
+ it 'writes an error on object and does not set the values' do
36
+ expected = Time.new(1984, 10, 23, 0, 0, 0, 0)
37
+
38
+ subject.call '1984-10-00', options
39
+
40
+ expect(object.errors[:birthday]).to eq ['birthday.error']
41
+ expect(object.birthday).to eq nil
42
+ end
43
+ end
44
+
45
+ context 'with no I18n present' do
46
+ it 'writes a default error on object and does not set the values' do
47
+ expected = Time.new(1984, 10, 23, 0, 0, 0, 0)
48
+
49
+ subject.call '1984-10-00', options
50
+
51
+ expect(object.errors[:birthday]).to eq ['1984-10-00 is an invalid date.']
52
+ expect(object.birthday).to eq nil
53
+ end
54
+ end
55
+ end
56
+ end