paranoid_starlight 1.4.0 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
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