paranoid_starlight 1.4.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.
data/README.md CHANGED
@@ -1,10 +1,20 @@
1
1
  # ParanoidStarlight
2
2
 
3
- This piece of gem contains some custom validators and converters for ActiveModel.
3
+ This gem is pack of methods to convert or validate
4
+ different formats of strings and texts in model,
5
+ like telephone numbers (CZ/SK format),
6
+ email, or (european) names (currently).
7
+ Or to clean string of too much whitespaces.
4
8
 
5
- It has validations for email and name (European style).
6
- And validation and converter (to international format) of telephone number. (CZ/SK format)
7
- Few converters for texts and strings. Specs included.
9
+ It provides *convert* methods for attributes of model
10
+ (getter and setter method in object is enough).
11
+ They are used in save hooks.
12
+
13
+ There are also *validator* methods for ActiveModel
14
+ nd hook for automatic ActiveRecord integration.
15
+ Just type: (`require 'paranoid_starlight/active_record'`)
16
+
17
+ Specs included.
8
18
 
9
19
  ## Installation
10
20
 
@@ -12,7 +22,7 @@ Add this line to your application's Gemfile:
12
22
 
13
23
  gem 'paranoid_starlight'
14
24
 
15
- If you want to have methods available for ActiveRecord models, use:
25
+ If you want to have methods available for `ActiveRecord` models, use:
16
26
 
17
27
  gem 'paranoid_starlight', :require => 'paranoid_starlight/active_record'
18
28
 
@@ -28,7 +38,7 @@ Or install it yourself as:
28
38
 
29
39
  class MyModel
30
40
  include ActiveModel::Validations
31
- include ParanoidStarlight::Validations
41
+ include ParanoidStarlight::Attributes::Validations
32
42
 
33
43
  attr_accessor :email
34
44
  validates_email_format_of :email
@@ -41,6 +51,8 @@ Or install it yourself as:
41
51
 
42
52
  If you required active_record hook, you can use:
43
53
 
54
+ require 'paranoid_starlight/active_record'
55
+
44
56
  class Person < ActiveRecord::Base
45
57
  attr_accessible :name, :telephone, :mobile, :email
46
58
  attr_accessible :address, :zip
@@ -63,23 +75,27 @@ If you required active_record hook, you can use:
63
75
  end
64
76
 
65
77
  def process_fields
66
- clean_text([:address, :zip])
78
+ process_string([:address, :zip])
67
79
  end
68
80
  end
69
81
 
70
82
  Currently there are these possibilities:
83
+
84
+ *Validations for ActiveModel*
85
+
71
86
  - validates_email_format_of
72
87
  - validates_name_format_of
73
88
  - validates_telephone_number_of
74
89
 
75
- - clean_text
76
- - clean_whitespaces
90
+ *Converters for attributes* (getter and setter methods in object are enough)
91
+
92
+ - process_string (substitutes one or more whitespaces with space)
77
93
  - convert_telephone_number
78
94
 
79
95
  It is easy to create own converter, just do:
80
96
 
81
97
  class Kiddie
82
- include ::ParanoidStarlight::Converters
98
+ include ::ParanoidStarlight::Attributes::Converters
83
99
  attr_accessor :name
84
100
 
85
101
  def l33t
@@ -98,8 +114,12 @@ It is easy to create own converter, just do:
98
114
  4. Push to the branch (`git push origin my-new-feature`)
99
115
  5. Create new Pull Request
100
116
 
117
+ ## TODO
118
+
119
+ Separate email and name validators to own functions, to be independent from ActiveModel validators.
120
+
101
121
  ## Author
102
- Created by Ivan Stana
103
- License: MIT
122
+ Programmed in 2012
123
+ by Ivan Stana
124
+ License: MIT
104
125
 
105
- I encourage to write me something
@@ -1,180 +1,29 @@
1
1
  # -*- coding: UTF-8 -*-
2
2
 
3
+ # This gem is pack of methods to convert or validate
4
+ # different formats of strings and texts in model,
5
+ # like telephone numbers (CZ/SK format),
6
+ # email, or (european) names (currently).
7
+ # Or to clean string of too much whitespaces.
8
+ #
9
+ # It provides *convert* methods for attributes of model
10
+ # (getter and setter method in object is enough).
11
+ # They are used in save hooks.
12
+ #
13
+ # There are also *validator* methods for ActiveModel
14
+ # and hook for automatic ActiveRecord integration.
15
+ # Just type: (require 'paranoid_starlight/active_record')
16
+ #
17
+
3
18
  require "paranoid_starlight/version"
4
19
  require 'active_model'
5
20
  require 'twitter_cldr'
6
21
  require 'fast_gettext'
7
22
 
8
23
  module ParanoidStarlight
9
-
10
- module Validators
11
- class EmailValidator < ::ActiveModel::EachValidator
12
- def validate_each(record, attribute, value)
13
- # username in email may have @ in string
14
- # username should be case sensitive, domain is not
15
- unless value =~ %r{\A([^\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})\z}
16
- record.errors[attribute] << (options[:message] || 'is not an email')
17
- end
18
- end
19
- end
20
-
21
- class NameValidator < ::ActiveModel::EachValidator
22
- def validate_each(record, attribute, value)
23
- fullname = '\p{Letter}+(-\p{Letter}+)*'
24
- surname = fullname
25
- short = '\p{Letter}\.'
26
- unless value =~ /\A(?:#{fullname} ((#{fullname}|#{short}) )*#{surname})\z/
27
- record.errors[attribute] << (options[:message] || 'is not a name')
28
- end
29
- end
30
- end
31
-
32
- class TelephoneValidator < ::ActiveModel::EachValidator
33
- def validate_each(record, attribute, value)
34
- # SK/CZ format
35
- valid = ::ParanoidStarlight::Converters.convert_telephone(value) rescue nil
36
- unless valid
37
- record.errors[attribute] << (options[:message] || 'is not a telephone number')
38
- end
39
- end
40
- end
41
- end # end validators
42
-
43
- module Validations
44
- def self.included(base)
45
- base.send(:extend, self)
46
- end
47
-
48
- def validates_email_format_of(*attr_names)
49
- # _merge_attributes extracts options and flatten attrs
50
- # :attributes => {attr_names} is lightweight option
51
- validates_with ::ParanoidStarlight::Validators::EmailValidator, _merge_attributes(attr_names)
52
- end
53
-
54
- def validates_name_format_of(*attr_names)
55
- validates_with ::ParanoidStarlight::Validators::NameValidator, _merge_attributes(attr_names)
56
- end
57
-
58
- def validates_telephone_number_of(*attr_names)
59
- validates_with ::ParanoidStarlight::Validators::TelephoneValidator, _merge_attributes(attr_names)
60
- end
61
- end # end validations
62
-
63
-
64
- module Converters
65
- def self.convert_telephone(num, prefixcc = 421)
66
- telephone = num.to_s
67
- prefixcc = prefixcc.to_s
68
-
69
- # convert logic
70
- # possible formats, with or without spaces
71
-
72
- # mobile (CZ/SK)
73
- # CZ/SK have always 9 numbers
74
- # (1) +421 949 123 456
75
- # (2) 00421 949 123 456
76
- # (3) 0949 123 456 (10 with leading zero, only SK)
77
- # (4) 949 123 456
78
-
79
- # landline always 9 numbers
80
- # other regions - 04x
81
- # (3) 045 / 6893121
82
- # bratislava - 02
83
- # (3) 02 / 44250320
84
- # (1) 421-2-44250320
85
- # (1) +421 (2) 44250320
86
- # (x) ()44 250 320 (no chance to guess NDC (geographic prefix here))
87
- # and other formats from above
88
-
89
-
90
- # output is integer
91
- # 421949123456
92
-
93
- # remove all non-number characters
94
- telephone.gsub!(/\D/, '')
95
-
96
- cc = '420|421'
97
-
98
- # + is stripped
99
- if match = /\A((?:#{cc})\d{9})\z/.match(telephone)
100
- return match[1]
101
- elsif match = /\A00((?:#{cc})\d{9})\z/.match(telephone)
102
- return match[1]
103
- elsif match = /\A0(\d{9})\z/.match(telephone)
104
- return prefixcc + match[1]
105
- # number cannot begin with 0, when has 9 numbers
106
- elsif match = /\A([1-9]\d{8})\z/.match(telephone)
107
- return prefixcc + match[1]
108
-
109
- else
110
- raise("Number is invalid")
111
- end
112
- end
113
-
114
- def convert_telephone_number(inattr, outattr = '')
115
- basic_converter(self, inattr, outattr) do |telephone|
116
- ::ParanoidStarlight::Converters.convert_telephone(
117
- telephone,
118
- TwitterCldr::Shared::PhoneCodes.code_for_territory(
119
- FastGettext.locale.to_sym
120
- )
121
- ) rescue nil
122
- end
123
- end
124
-
125
- def clean_string(inattr, outattr = '')
126
- basic_converter(self, inattr, outattr) do |text|
127
- text.to_s.strip.gsub(/\n/, ' ').gsub(/\s+/, ' ')
128
- end
129
- end
130
-
131
- def remove_whitespaces(inattr, outattr = '')
132
- basic_converter(self, inattr, outattr) do |text|
133
- array = text.to_s.strip.split("\n")
134
- array.map {|line| line.gsub(/\s/, '')}.join("\n")
135
- end
136
- end
137
-
138
- private
139
- def basic_converter(obj, inattr, outattr, &code)
140
- attributes = []
141
-
142
- # May be only one value, ideally string or symbol
143
- outattr = outattr.to_sym
144
-
145
-
146
- if inattr.is_a? Array
147
- attributes = inattr
148
- elsif obj.respond_to? inattr.to_sym
149
- attributes << inattr
150
- # hash, array and like haven't got to_sym defined
151
- outattr = inattr if outattr.to_s == ''
152
- else
153
- raise("Attribute #{inattr} does not exist.")
154
- end
155
-
156
- if attributes.size > 1 && outattr.to_s != ''
157
- raise("Multiple attributes can be used only without output attribute")
158
- end
159
-
160
- attributes.each do |attribute|
161
- outattr = attribute if attributes.size > 1
162
-
163
- unless obj.respond_to? outattr
164
- raise("Attribute #{outattr} does not exist.")
165
- end
166
-
167
- setter = "#{outattr}=".to_sym
168
- unless obj.respond_to? setter
169
- raise("Setter #{setter} does not exist.")
170
- end
171
-
172
- to_convert = obj.send(attribute.to_sym)
173
- unless to_convert.nil?
174
- obj.send(setter, code.call(to_convert))
175
- end
176
- end
177
- end
178
-
179
- end # end converters
24
+ [
25
+ 'converters', 'validators',
26
+ 'attributes/converters', 'attributes/validations'].each do |req|
27
+ require_relative File.join('.', 'paranoid_starlight', req + '.rb')
28
+ end
180
29
  end
@@ -3,6 +3,6 @@
3
3
  require_relative "../paranoid_starlight.rb"
4
4
 
5
5
  require 'active_record'
6
- ::ActiveRecord::Base.send(:include, ParanoidStarlight::Validators)
7
- ::ActiveRecord::Base.send(:include, ParanoidStarlight::Converters)
6
+ ::ActiveRecord::Base.send(:include, ::ParanoidStarlight::Attributes::Validations)
7
+ ::ActiveRecord::Base.send(:include, ::ParanoidStarlight::Attributes::Converters)
8
8
 
@@ -0,0 +1,73 @@
1
+ module ParanoidStarlight
2
+ module Attributes
3
+ module Converters
4
+
5
+ def convert_telephone_number(inattr, outattr = '')
6
+ basic_converter(self, inattr, outattr) do |telephone|
7
+ ::ParanoidStarlight::Converters.convert_telephone(
8
+ telephone,
9
+ TwitterCldr::Shared::PhoneCodes.code_for_territory(
10
+ FastGettext.locale.to_sym
11
+ )
12
+ ) rescue nil
13
+ end
14
+ end
15
+
16
+ # currently it only processes whitespaces
17
+ def process_string(inattr, outattr = '')
18
+ basic_converter(self, inattr, outattr) do |text|
19
+ ::ParanoidStarlight::Converters.one_liner(text)
20
+ end
21
+ end
22
+ =begin
23
+ no purpose, needs improvement
24
+ def remove_whitespaces(inattr, outattr = '')
25
+ basic_converter(self, inattr, outattr) do |text|
26
+ array = text.to_s.strip.split("\n")
27
+ array.map {|line| line.gsub(/\s/, '')}.join("\n")
28
+ end
29
+ end
30
+ =end
31
+
32
+ def basic_converter(obj, inattr, outattr, &code)
33
+ attributes = []
34
+
35
+ # May be only one value, ideally string or symbol
36
+ outattr = outattr.to_sym
37
+
38
+ if inattr.is_a? Array
39
+ attributes = inattr
40
+ elsif obj.respond_to? inattr.to_sym
41
+ attributes << inattr
42
+ # hash, array and like haven't got to_sym defined
43
+ outattr = inattr if outattr.to_s == ''
44
+ else
45
+ raise("Attribute #{inattr} does not exist.")
46
+ end
47
+
48
+ if attributes.size > 1 && outattr.to_s != ''
49
+ raise("Multiple attributes can be used only without output attribute")
50
+ end
51
+
52
+ attributes.each do |attribute|
53
+ outattr = attribute if attributes.size > 1
54
+
55
+ unless obj.respond_to? outattr
56
+ raise("Attribute #{outattr} does not exist.")
57
+ end
58
+
59
+ setter = "#{outattr}=".to_sym
60
+ unless obj.respond_to? setter
61
+ raise("Setter #{setter} does not exist.")
62
+ end
63
+
64
+ to_convert = obj.send(attribute.to_sym)
65
+ unless to_convert.nil?
66
+ obj.send(setter, code.call(to_convert))
67
+ end
68
+ end
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,23 @@
1
+ module ParanoidStarlight
2
+ module Attributes
3
+ module Validations
4
+ def self.included(base)
5
+ base.send(:extend, self)
6
+ end
7
+
8
+ def validates_email_format_of(*attr_names)
9
+ # _merge_attributes extracts options and flatten attrs
10
+ # :attributes => {attr_names} is lightweight option
11
+ validates_with ::ParanoidStarlight::Validators::EmailValidator, _merge_attributes(attr_names)
12
+ end
13
+
14
+ def validates_name_format_of(*attr_names)
15
+ validates_with ::ParanoidStarlight::Validators::NameValidator, _merge_attributes(attr_names)
16
+ end
17
+
18
+ def validates_telephone_number_of(*attr_names)
19
+ validates_with ::ParanoidStarlight::Validators::TelephoneValidator, _merge_attributes(attr_names)
20
+ end
21
+ end # end validations
22
+ end
23
+ end
@@ -0,0 +1,79 @@
1
+ module ParanoidStarlight
2
+ module Converters
3
+ def convert_telephone(num, prefixcc = 421)
4
+ telephone = num.to_s
5
+ prefixcc = prefixcc.to_s
6
+
7
+ # convert logic
8
+ # possible formats, with or without spaces
9
+
10
+ # mobile (CZ/SK)
11
+ # CZ/SK have always 9 numbers
12
+ # (1) +421 949 123 456
13
+ # (2) 00421 949 123 456
14
+ # (3) 0949 123 456 (10 with leading zero, only SK)
15
+ # (4) 949 123 456
16
+
17
+ # landline always 9 numbers
18
+ # other regions - 04x
19
+ # (3) 045 / 6893121
20
+ # bratislava - 02
21
+ # (3) 02 / 44250320
22
+ # (1) 421-2-44250320
23
+ # (1) +421 (2) 44250320
24
+ # (x) ()44 250 320 (no chance to guess NDC (geographic prefix here))
25
+ # and other formats from above
26
+
27
+
28
+ # output is string
29
+ # +421949123456
30
+ # make integer from it call with to_i
31
+
32
+ # remove all non-number characters
33
+ # I don't care for alphabetic or special characters
34
+ # in number
35
+ telephone.gsub!(/\D/, '')
36
+
37
+ cc = '420|421'
38
+
39
+ # + is stripped in all numbers
40
+ if match = /\A((?:#{cc})\d{9})\z/.match(telephone)
41
+ number = match[1]
42
+ elsif match = /\A00((?:#{cc})\d{9})\z/.match(telephone)
43
+ number = match[1]
44
+ elsif match = /\A0(\d{9})\z/.match(telephone)
45
+ number = prefixcc + match[1]
46
+ # number cannot begin with 0, when has 9 numbers
47
+ elsif match = /\A([1-9]\d{8})\z/.match(telephone)
48
+ number = prefixcc + match[1]
49
+
50
+ else
51
+ raise("Number is invalid")
52
+ end
53
+
54
+ '+' + number
55
+ end
56
+
57
+ # There will be no .valid? function
58
+ # because it would need to handle number separators
59
+ # and other characters in harder way.
60
+ #
61
+ # This number needs to be converted to international format
62
+ # before using it!
63
+
64
+ def telephone_will_convert?(telephone)
65
+ valid = convert_telephone(telephone) rescue nil
66
+ valid.nil? ? false : true
67
+ end
68
+
69
+ def one_liner(input)
70
+ input.to_s.strip.gsub(/\s+/m, ' ')
71
+ end
72
+
73
+ # make methods also acessible with direct call
74
+ module_function :convert_telephone, :telephone_will_convert?, :one_liner
75
+ public :convert_telephone, :telephone_will_convert?, :one_liner
76
+
77
+ end # end converters
78
+
79
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ module ParanoidStarlight
4
+
5
+ module Validators
6
+ class EmailValidator < ::ActiveModel::EachValidator
7
+ def validate_each(record, attribute, value)
8
+ # username in email may have @ in string
9
+ # username should be case sensitive, domain is not
10
+ unless value =~ %r{\A([^\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})\z}
11
+ record.errors[attribute] << (options[:message] || 'is not an email')
12
+ end
13
+ end
14
+ end
15
+
16
+ class NameValidator < ::ActiveModel::EachValidator
17
+ def validate_each(record, attribute, value)
18
+ fullname = '\p{Letter}+(-\p{Letter}+)*'
19
+ surname = fullname
20
+ short = '\p{Letter}\.'
21
+ unless value =~ /\A(?:#{fullname} ((#{fullname}|#{short}) )*#{surname})\z/
22
+ record.errors[attribute] << (options[:message] || 'is not a name')
23
+ end
24
+ end
25
+ end
26
+
27
+ class TelephoneValidator < ::ActiveModel::EachValidator
28
+ def validate_each(record, attribute, value)
29
+ # SK/CZ format
30
+ valid = ::ParanoidStarlight::Converters.telephone_will_convert?(value)
31
+ unless valid
32
+ record.errors[attribute] << (options[:message] || 'is not a telephone number')
33
+ end
34
+ end
35
+ end
36
+ end # end validators
37
+
38
+ end
@@ -1,3 +1,3 @@
1
1
  module ParanoidStarlight
2
- VERSION = "1.4.0"
2
+ VERSION = "2.0"
3
3
  end
@@ -8,12 +8,23 @@ Gem::Specification.new do |gem|
8
8
  gem.version = ParanoidStarlight::VERSION
9
9
  gem.author = 'Ivan Stana'
10
10
  gem.email = 'stiipa@centrum.sk'
11
- gem.summary = "Pack of custom validations and converters for ActiveModel. Or standalone."
11
+ gem.summary = "Pack of custom validations and converters for ActiveModel. Also in standalone version."
12
12
  gem.description = <<-EOF
13
- It has validations for email and name (European style).
14
- And validation and converter (to international format)
15
- of telephone number. (CZ/SK format)
16
- Few converters for texts and strings. Specs included.
13
+ This gem is pack of methods to convert or validate
14
+ different formats of strings and texts in model,
15
+ like telephone numbers (CZ/SK format),
16
+ email, or (european) names (currently).
17
+ Or to clean string of too much whitespaces.
18
+
19
+ It provides *convert* methods for attributes of model
20
+ (getter and setter method in object is enough).
21
+ They are used in save hooks.
22
+
23
+ There are also *validator* methods for ActiveModel
24
+ nd hook for automatic ActiveRecord integration.
25
+ Just type: (`require 'paranoid_starlight/active_record'`)
26
+
27
+ Specs included.
17
28
  EOF
18
29
 
19
30
  gem.homepage = "http://github.com/istana/paranoid_starlight"
@@ -0,0 +1,100 @@
1
+ require_relative '../spec_helper.rb'
2
+
3
+ class Fangirl
4
+ include ::ParanoidStarlight::Attributes::Converters
5
+ attr_accessor :telephone
6
+ attr_accessor :text
7
+ attr_accessor :basic_field, :basic_field2, :basic_field_out
8
+ end
9
+
10
+ describe ParanoidStarlight::Attributes::Converters do
11
+
12
+ describe 'convert_telephone_number' do
13
+ before :each do
14
+ FastGettext.locale = 'sk'
15
+ @test = Fangirl.new
16
+ @test.telephone = '+421 123 456 789'
17
+ end
18
+
19
+ it 'should convert telephone number into international format' do
20
+ @test.convert_telephone_number(:telephone)
21
+
22
+ @test.telephone.should == '+421123456789'
23
+ end
24
+ end
25
+
26
+ describe 'process_string' do
27
+ before { @test = Fangirl.new; @test.text = " Some \t\ntext.\n \t" }
28
+ it 'should get string in one line separated with spaces' do
29
+ @test.process_string(:text)
30
+ @test.text.should == "Some text."
31
+ end
32
+ end
33
+
34
+ describe 'template of converter' do
35
+ before do
36
+ @test = Fangirl.new
37
+ @test.basic_field = "Hello world!"
38
+ @test.basic_field2 = "World sends love to you!"
39
+
40
+ def @test.upcase(input, output = '')
41
+ basic_converter(self, input, output) do |text|
42
+ text.upcase
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'supplies parameters in different format' do
48
+ it 'should accept anything in input with to_s' do
49
+ @test.upcase(:basic_field)
50
+ @test.basic_field.should == "HELLO WORLD!"
51
+
52
+ @test.upcase('basic_field2')
53
+ @test.basic_field2.should == "WORLD SENDS LOVE TO YOU!"
54
+ end
55
+
56
+ it 'should accept anything with to_s as output' do
57
+ @test.upcase(:basic_field, :basic_field_out)
58
+ @test.basic_field_out.should == "HELLO WORLD!"
59
+
60
+ @test.upcase('basic_field2', 'basic_field_out')
61
+ @test.basic_field_out.should == "WORLD SENDS LOVE TO YOU!"
62
+ end
63
+ end
64
+
65
+ context 'had one attribute supplied' do
66
+ it 'should overwrite attribute' do
67
+ @test.upcase(:basic_field)
68
+
69
+ @test.basic_field.should == "HELLO WORLD!"
70
+ end
71
+ end
72
+
73
+ context 'had two attributes supplied' do
74
+ it 'should put result to second attribute' do
75
+ @test.upcase(:basic_field, :basic_field_out)
76
+
77
+ @test.basic_field.should == "Hello world!"
78
+ @test.basic_field_out.should == "HELLO WORLD!"
79
+ end
80
+ end
81
+
82
+ context 'had array of attributes supplied' do
83
+ it 'should convert all attributes of array' do
84
+ @test.upcase([:basic_field, :basic_field2])
85
+
86
+ @test.basic_field.should == "HELLO WORLD!"
87
+ @test.basic_field2.should == "WORLD SENDS LOVE TO YOU!"
88
+ end
89
+ end
90
+
91
+ context 'had array of attributes and output supplied' do
92
+ it 'should raise error' do
93
+ expect {@test.upcase([:basic_field, :basic_field2],
94
+ :basic_field_out) }.to raise_error(/Multiple attributes can/)
95
+ end
96
+ end
97
+
98
+ end # end template of converter
99
+
100
+ end
@@ -0,0 +1,77 @@
1
+ require_relative '../spec_helper.rb'
2
+
3
+ class WithValidations
4
+ include ActiveModel::Validations
5
+ include ParanoidStarlight::Attributes::Validations
6
+ end
7
+
8
+ class TestEmail < WithValidations
9
+ attr_accessor :email_field
10
+ validates_email_format_of :email_field
11
+ end
12
+
13
+ class TestName < WithValidations
14
+ attr_accessor :name_field
15
+ validates_name_format_of :name_field
16
+ end
17
+
18
+ class TestName < WithValidations
19
+ attr_accessor :name_field
20
+ validates_name_format_of :name_field
21
+ end
22
+
23
+ class TestTelephone < WithValidations
24
+ attr_accessor :telephone
25
+ validates_telephone_number_of :telephone
26
+ end
27
+
28
+ describe ParanoidStarlight::Attributes::Validations do
29
+ # I won't test multiple attributes as argument
30
+ # it works, because it is copied from rails
31
+
32
+ describe 'validates_email_format_of' do
33
+ subject { TestEmail.new() }
34
+ before { subject.email_field = email_value }
35
+
36
+ context 'is valid' do
37
+ let(:email_value) {'example@my.example.org'}
38
+ it {should be_valid }
39
+ end
40
+
41
+ context 'is invalid' do
42
+ let(:email_value) {'example'}
43
+ it { should be_invalid }
44
+ end
45
+ end
46
+
47
+ describe 'validates_name_format_of' do
48
+ subject { TestName.new() }
49
+ before { subject.name_field = name }
50
+
51
+ context 'is valid' do
52
+ let(:name) {'Geralt of Rivia'}
53
+ it { should be_valid }
54
+ end
55
+
56
+ context 'is invalid' do
57
+ let(:name) {'Shakespeare'}
58
+ it { should be_invalid }
59
+ end
60
+ end
61
+
62
+ describe 'validates_telephone_number_of' do
63
+ subject { TestTelephone.new() }
64
+ before { subject.telephone = telephone }
65
+
66
+ context 'is valid' do
67
+ let(:telephone) {'+421123456789'}
68
+ it { should be_valid }
69
+ end
70
+
71
+ context 'is invalid' do
72
+ let(:telephone) {'1111'}
73
+ it { should be_invalid }
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,77 @@
1
+ require_relative '../spec_helper.rb'
2
+
3
+ describe ParanoidStarlight::Converters do
4
+ before :all do
5
+ @p = ParanoidStarlight::Converters
6
+ end
7
+
8
+ describe 'convert_telephone' do
9
+
10
+ it 'accepts all objects, which have to_s method' do
11
+ ['421123456789',
12
+ 421123456789,
13
+ :"421123456789"].each do |num|
14
+ @p.convert_telephone(num).should == '+421123456789'
15
+ end
16
+ end
17
+
18
+ it 'removes non-numeric characters' do
19
+ @p.convert_telephone(' +421 123 / 456789A').should == '+421123456789'
20
+ end
21
+
22
+ it 'tests valid formats' do
23
+ ['+421 123 456 789',
24
+ '00421 123 456 789',
25
+ '123 456 789',
26
+ '0123 456 789'].each { |num|
27
+ @p.convert_telephone(num).should == '+421123456789'
28
+ }
29
+ @p.convert_telephone('043/5867890').should == '+421435867890'
30
+ end
31
+
32
+ it 'tests some of invalid formats' do
33
+ ['043/586789',
34
+ '123',
35
+ # 10 digits
36
+ '4211234567890'
37
+ ].each { |num|
38
+ expect {@p.convert_telephone(num)}.to raise_error('Number is invalid')
39
+ }
40
+ end
41
+
42
+ it 'tests with custom country code prefix' do
43
+ @p.convert_telephone('+421 123 456 789', 410).should == '+421123456789'
44
+ @p.convert_telephone('123 456 789', 410).should == '+410123456789'
45
+ @p.convert_telephone('0123 456 789', 410).should == '+410123456789'
46
+ end
47
+
48
+ it 'to_i returns number as integer' do
49
+ @p.convert_telephone('+421 123 456 789').to_i.should == 421123456789
50
+ end
51
+
52
+ end
53
+
54
+ describe 'telephone_will_convert?' do
55
+ subject {@p.telephone_will_convert?(telephone)}
56
+
57
+ context 'valid number' do
58
+ let(:telephone) {'+421 123 456 789'}
59
+ it {should be_true}
60
+ end
61
+
62
+ context 'inconvertible (not invalid by notation!) number' do
63
+ let(:telephone) {'123'}
64
+ it {should be_false}
65
+ end
66
+ end
67
+
68
+ describe 'one_liner' do
69
+ it 'converts succeeding whitespace(s) to space' do
70
+ @p.one_liner(
71
+ " Some \ttext. \t\n\n\n Hello\t\t\nworld."
72
+ ).should == 'Some text. Hello world.'
73
+ end
74
+ end
75
+
76
+ end
77
+
@@ -0,0 +1,78 @@
1
+ require_relative '../spec_helper.rb'
2
+
3
+ describe ParanoidStarlight::Validators do
4
+ before :all do
5
+ @validators = ParanoidStarlight::Validators
6
+ end
7
+
8
+ before :each do
9
+ @mock = mock('model')
10
+ @mock.stub("errors").and_return([])
11
+ @mock.errors.stub('[]').and_return({})
12
+ @mock.errors[].stub('<<')
13
+ end
14
+
15
+ describe 'EmailValidator' do
16
+ before :each do
17
+ @email = @validators::EmailValidator.new({:attributes => {}})
18
+ end
19
+
20
+ it "shouldn't add message to errors when valid email address" do
21
+ @mock.should_not_receive('errors')
22
+ @email.validate_each(@mock, "email", "example@example.org")
23
+ @email.validate_each(@mock, "email", "example@@example.org")
24
+ @email.validate_each(@mock, "email", "l0~gin@sub.examp-le.org")
25
+ end
26
+
27
+ it "should add message to errors when invalid email address" do
28
+ @mock.errors[].should_receive('<<')
29
+ @email.validate_each(@mock, "email", "notvalid")
30
+ @email.validate_each(@mock, "email", "x@exa$mple.org")
31
+ end
32
+ end
33
+
34
+ describe 'NameValidator' do
35
+ before :each do
36
+ @name = @validators::NameValidator.new({:attributes => {}})
37
+ end
38
+
39
+ it "shouldn't add message to errors when valid name" do
40
+ @mock.should_not_receive('errors')
41
+ [
42
+ 'Ivan Stana', 'Ivan R. Stana', 'Ivan Ronon Stana',
43
+ 'Jean Claude Van Damme', 'Jean-Pierre Cassel',
44
+ 'Tatyana Sukhotina-Tolstaya',
45
+ 'John R. R. Tolkien', 'I S'
46
+ ].each {
47
+ |name| @name.validate_each(@mock, "name", name)
48
+ }
49
+ end
50
+
51
+ it "should add message to errors when invalid name" do
52
+ @mock.errors[].should_receive('<<')
53
+ [
54
+ 'J. R. R. Tolkien', 'J.R.R. Tolkien', 'Tolkien', ''
55
+ ].each {
56
+ |name| @name.validate_each(@mock, "name", name)
57
+ }
58
+ end
59
+ end
60
+
61
+ describe 'TelephoneValidator' do
62
+ before :each do
63
+ @telephone = @validators::TelephoneValidator.new({:attributes => {}})
64
+ end
65
+
66
+ it "shouldn't add message to errors when valid telephone" do
67
+ @mock.should_not_receive('errors')
68
+ @telephone.validate_each(@mock, "telephone", '+421123456789')
69
+ end
70
+
71
+ it "should add message to errors when invalid telephone" do
72
+ @mock.errors[].should_receive('<<')
73
+ @telephone.validate_each(@mock, "telephone", '123')
74
+ end
75
+ end
76
+
77
+ end
78
+
@@ -0,0 +1,2 @@
1
+ require "rspec"
2
+ require_relative File.join('..', 'lib', 'paranoid_starlight.rb')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paranoid_starlight
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: '2.0'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-23 00:00:00.000000000 Z
12
+ date: 2012-12-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -75,9 +75,14 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
- description: ! " It has validations for email and name (European style).\n And
79
- validation and converter (to international format)\n of telephone number. (CZ/SK
80
- format)\n Few converters for texts and strings. Specs included.\n"
78
+ description: ! " This gem is pack of methods to convert or validate\n different
79
+ formats of strings and texts in model,\n like telephone numbers (CZ/SK format),\n
80
+ \ email, or (european) names (currently).\n Or to clean string of too much
81
+ whitespaces.\n\n It provides *convert* methods for attributes of model\n (getter
82
+ and setter method in object is enough).\n They are used in save hooks.\n\n There
83
+ are also *validator* methods for ActiveModel\n nd hook for automatic ActiveRecord
84
+ integration.\n Just type: (`require 'paranoid_starlight/active_record'`)\n\n
85
+ \ Specs included.\n"
81
86
  email: stiipa@centrum.sk
82
87
  executables: []
83
88
  extensions: []
@@ -89,9 +94,17 @@ files:
89
94
  - README.md
90
95
  - lib/paranoid_starlight.rb
91
96
  - lib/paranoid_starlight/active_record.rb
97
+ - lib/paranoid_starlight/attributes/converters.rb
98
+ - lib/paranoid_starlight/attributes/validations.rb
99
+ - lib/paranoid_starlight/converters.rb
100
+ - lib/paranoid_starlight/validators.rb
92
101
  - lib/paranoid_starlight/version.rb
93
102
  - paranoid_starlight.gemspec
94
- - specs/paranoid_starlight_spec.rb
103
+ - specs/paranoid_starlight/attributes_converters_spec.rb
104
+ - specs/paranoid_starlight/attributes_validations_spec.rb
105
+ - specs/paranoid_starlight/converters_spec.rb
106
+ - specs/paranoid_starlight/validators_spec.rb
107
+ - specs/spec_helper.rb
95
108
  homepage: http://github.com/istana/paranoid_starlight
96
109
  licenses: []
97
110
  post_install_message:
@@ -115,5 +128,6 @@ rubyforge_project:
115
128
  rubygems_version: 1.8.24
116
129
  signing_key:
117
130
  specification_version: 3
118
- summary: Pack of custom validations and converters for ActiveModel. Or standalone.
131
+ summary: Pack of custom validations and converters for ActiveModel. Also in standalone
132
+ version.
119
133
  test_files: []
@@ -1,315 +0,0 @@
1
- require_relative '../lib/paranoid_starlight'
2
- require 'rspec'
3
-
4
- #ActiveRecord::Base.send(:include, ParanoidStarlight::Validators)
5
- #ActiveRecord::Base.send(:include, ParanoidStarlight::Converters)
6
-
7
- class Fangirl
8
- include ::ParanoidStarlight::Converters
9
- attr_accessor :telephone
10
- attr_accessor :text
11
- attr_accessor :basic_field, :basic_field2, :basic_field_out
12
- end
13
-
14
- describe ParanoidStarlight::Converters do
15
- before :all do
16
- @p = ParanoidStarlight::Converters
17
- end
18
-
19
- describe 'convert_telephone' do
20
-
21
- it 'accepts all objects, which have to_s' do
22
- ['421123456789',
23
- 421123456789,
24
- :"421123456789"].each do |num|
25
- @p.convert_telephone(num).should == '421123456789'
26
- end
27
- end
28
-
29
- it 'removes non-numeric characters' do
30
- @p.convert_telephone(' +421 123 / 456789A').should == '421123456789'
31
- end
32
-
33
- it 'tests (un)polished valid formats' do
34
- ['+421 123 456 789',
35
- '00421 123 456 789',
36
- '123 456 789',
37
- '0123 456 789'].each { |num|
38
- @p.convert_telephone(num).should == '421123456789'
39
- }
40
- @p.convert_telephone('043/5867890').should == '421435867890'
41
- end
42
-
43
- it 'tests some of invalid formats' do
44
- ['043/586789',
45
- '123',
46
- '4211234567890'
47
- ].each { |num|
48
- expect {@p.convert_telephone(num)}.to raise_error('Number is invalid')
49
- }
50
- end
51
-
52
- it 'tests with custom country code prefix' do
53
- @p.convert_telephone('+421 123 456 789', 410).should == '421123456789'
54
- @p.convert_telephone('123 456 789', 410).should == '410123456789'
55
- @p.convert_telephone('0123 456 789', 410).should == '410123456789'
56
- end
57
-
58
- end
59
-
60
- describe 'template of converter' do
61
- before do
62
- @test = Fangirl.new
63
- @test.basic_field = "Hello world!"
64
- @test.basic_field2 = "World sends love to you!"
65
-
66
- def @test.upcase(input, output = '')
67
- basic_converter(self, input, output) do |text|
68
- text.upcase
69
- end
70
- end
71
- end
72
-
73
- context 'supplies parameters in different format' do
74
- it 'should accept anything in input with to_s' do
75
- @test.upcase(:basic_field)
76
- @test.basic_field.should == "HELLO WORLD!"
77
- @test.upcase('basic_field2')
78
- @test.basic_field2.should == "WORLD SENDS LOVE TO YOU!"
79
- end
80
-
81
- it 'should accept anything with to_s as output' do
82
- @test.upcase(:basic_field, :basic_field_out)
83
- @test.basic_field_out.should == "HELLO WORLD!"
84
- @test.upcase('basic_field2', 'basic_field_out')
85
- @test.basic_field_out.should == "WORLD SENDS LOVE TO YOU!"
86
- end
87
- end
88
-
89
- context 'had one attribute supplied' do
90
- it 'should overwrite attribute' do
91
- @test.upcase(:basic_field)
92
- @test.basic_field.should == "HELLO WORLD!"
93
- end
94
- end
95
-
96
- context 'had two attributes supplied' do
97
- it 'should put result to second attribute' do
98
- @test.upcase(:basic_field, :basic_field_out)
99
- @test.basic_field.should == "Hello world!"
100
- @test.basic_field_out.should == "HELLO WORLD!"
101
- end
102
- end
103
-
104
- context 'had array of attributes supplied' do
105
- it 'should convert all attributes of array' do
106
- @test.upcase([:basic_field, :basic_field2])
107
- @test.basic_field.should == "HELLO WORLD!"
108
- @test.basic_field2.should == "WORLD SENDS LOVE TO YOU!"
109
- end
110
- end
111
-
112
- context 'had array of attributes and output supplied' do
113
- it 'should raise error' do
114
- expect {@test.upcase([:basic_field, :basic_field2],
115
- :basic_field_out) }.to raise_error(/Multiple attributes can/)
116
- end
117
- end
118
-
119
- end
120
-
121
-
122
- describe 'convert_telephone_number (for attributes)' do
123
- before :each do
124
- FastGettext.locale = 'sk'
125
- @test = Fangirl.new
126
- @test.telephone = '+421 123 456 789'
127
- end
128
-
129
- it 'should convert telephone number into international format' do
130
- @test.convert_telephone_number(:telephone)
131
- @test.telephone.should == '421123456789'
132
- end
133
- end
134
-
135
- describe 'clean_string (for attributes)' do
136
- before { @test = Fangirl.new; @test.text = " Some \t\ntext.\n \t" }
137
- it 'should get words with spaces' do
138
- @test.clean_string(:text)
139
- @test.text.should == "Some text."
140
- end
141
- end
142
-
143
- describe 'remove_whitespaces (for attributes)' do
144
- before do
145
- @test = Fangirl.new;
146
- @test.text = " Some \ttext. \t\n\n\n Hello\t\tworld."
147
- end
148
-
149
- it 'should clean text of unwanted characters' do
150
- @test.remove_whitespaces(:text)
151
- @test.text.should == "Sometext.\n\n\nHelloworld."
152
- end
153
- end
154
-
155
- end
156
-
157
- describe 'ParanoidStarlight::Validations' do
158
- before(:each) do
159
- @validators = ParanoidStarlight::Validators
160
-
161
- @mock = mock('model')
162
- @mock.stub("errors").and_return([])
163
- @mock.errors.stub('[]').and_return({})
164
- @mock.errors[].stub('<<')
165
- end
166
-
167
- describe 'EmailValidator' do
168
- before :each do
169
- @email = @validators::EmailValidator.new({:attributes => {}})
170
- end
171
-
172
- it "should validate valid email address" do
173
- @mock.should_not_receive('errors')
174
- @email.validate_each(@mock, "email", "example@example.org")
175
- @email.validate_each(@mock, "email", "example@@example.org")
176
- @email.validate_each(@mock, "email", "l0~gin@sub.examp-le.org")
177
- end
178
-
179
- it "should validate invalid email address" do
180
- @mock.errors[].should_receive('<<')
181
- @email.validate_each(@mock, "email", "notvalid")
182
- @email.validate_each(@mock, "email", "x@exa$mple.org")
183
- end
184
- end
185
-
186
- describe 'NameValidator' do
187
- before :each do
188
- @name = @validators::NameValidator.new({:attributes => {}})
189
- end
190
-
191
- it "should validate valid name" do
192
- @mock.should_not_receive('errors')
193
- [
194
- 'Ivan Stana', 'Ivan R. Stana', 'Ivan Ronon Stana',
195
- 'Jean Claude Van Damme', 'Jean-Pierre Cassel',
196
- 'Tatyana Sukhotina-Tolstaya',
197
- 'John R. R. Tolkien', 'I S'
198
- ].each {
199
- |name| @name.validate_each(@mock, "name", name)
200
- }
201
- end
202
-
203
- it "should validate invalid name" do
204
- @mock.errors[].should_receive('<<')
205
- [
206
- 'J. R. R. Tolkien', 'J.R.R. Tolkien', 'Tolkien', ''
207
- ].each {
208
- |name| @name.validate_each(@mock, "name", name)
209
- }
210
- end
211
- end
212
-
213
- describe 'TelephoneValidator' do
214
- before :each do
215
- @telephone = @validators::TelephoneValidator.new({:attributes => {}})
216
- end
217
-
218
- it "should validate valid telephone" do
219
- @mock.should_not_receive('errors')
220
- @telephone.validate_each(@mock, "telephone", '+421123456789')
221
- end
222
-
223
- it "should validate invalid telephone" do
224
- @mock.errors[].should_receive('<<')
225
- @telephone.validate_each(@mock, "telephone", '123')
226
- end
227
- end
228
-
229
- describe 'model Validators of' do
230
- class TestEmail
231
- include ActiveModel::Validations
232
- include ParanoidStarlight::Validations
233
- attr_accessor :email_field
234
- validates_email_format_of :email_field
235
- end
236
-
237
- class TestName
238
- include ActiveModel::Validations
239
- include ParanoidStarlight::Validations
240
- attr_accessor :name_field
241
- validates_name_format_of :name_field
242
- end
243
-
244
- class TestName
245
- include ActiveModel::Validations
246
- include ParanoidStarlight::Validations
247
- attr_accessor :name_field
248
- validates_name_format_of :name_field
249
- end
250
-
251
- class TestTelephone
252
- include ActiveModel::Validations
253
- include ParanoidStarlight::Validations
254
- attr_accessor :telephone
255
- validates_telephone_number_of :telephone
256
- end
257
- # I don't test multiple attributes as argument
258
- # it works, because it is copied from rails
259
-
260
-
261
- describe 'Email' do
262
- subject { TestEmail.new() }
263
-
264
- before { subject.email_field = email_value }
265
-
266
- context 'is valid' do
267
- let(:email_value) {'example@my.example.org'}
268
- it {should be_valid }
269
- end
270
-
271
- context 'is invalid' do
272
- let(:email_value) {'example'}
273
- it { should be_invalid }
274
- end
275
- end
276
-
277
- describe 'Name' do
278
- subject { TestName.new() }
279
-
280
- before do
281
- subject.name_field = name
282
- end
283
-
284
- context 'is valid' do
285
- let(:name) {'Geralt of Rivia'}
286
- it { should be_valid }
287
- end
288
-
289
- context 'is invalid' do
290
- let(:name) {'Shakespeare'}
291
- it { should be_invalid }
292
- end
293
- end
294
-
295
- describe 'Telephone' do
296
- subject { TestTelephone.new() }
297
-
298
- before do
299
- subject.telephone = telephone
300
- end
301
-
302
- context 'is valid' do
303
- let(:telephone) {'+421123456789'}
304
- it { should be_valid }
305
- end
306
-
307
- context 'is invalid' do
308
- let(:telephone) {'1111'}
309
- it { should be_invalid }
310
- end
311
- end
312
-
313
- end
314
-
315
- end # end validations