semantic_attributes 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +99 -0
- data/MIT-LICENSE +20 -0
- data/README +54 -0
- data/Rakefile +37 -0
- data/gist.rdoc +208 -0
- data/lib/active_record/validation_recursion_control.rb +33 -0
- data/lib/core_ext/class.rb +14 -0
- data/lib/predicates/aliased.rb +22 -0
- data/lib/predicates/association.rb +43 -0
- data/lib/predicates/base.rb +93 -0
- data/lib/predicates/blacklisted.rb +23 -0
- data/lib/predicates/domain.rb +31 -0
- data/lib/predicates/email.rb +42 -0
- data/lib/predicates/enumerated.rb +23 -0
- data/lib/predicates/hex_color.rb +24 -0
- data/lib/predicates/length.rb +71 -0
- data/lib/predicates/number.rb +104 -0
- data/lib/predicates/pattern.rb +22 -0
- data/lib/predicates/phone_number.rb +62 -0
- data/lib/predicates/required.rb +22 -0
- data/lib/predicates/same_as.rb +17 -0
- data/lib/predicates/size.rb +2 -0
- data/lib/predicates/time.rb +43 -0
- data/lib/predicates/unique.rb +71 -0
- data/lib/predicates/url.rb +62 -0
- data/lib/predicates/usa_state.rb +87 -0
- data/lib/predicates/usa_zip_code.rb +25 -0
- data/lib/predicates/whitelisted.rb +2 -0
- data/lib/predicates.rb +3 -0
- data/lib/semantic_attributes/attribute.rb +46 -0
- data/lib/semantic_attributes/attribute_formats.rb +67 -0
- data/lib/semantic_attributes/locale/en.yml +31 -0
- data/lib/semantic_attributes/predicates.rb +170 -0
- data/lib/semantic_attributes/set.rb +40 -0
- data/lib/semantic_attributes/version.rb +3 -0
- data/lib/semantic_attributes.rb +37 -0
- data/semantic_attributes.gemspec +29 -0
- data/test/db/database.yml +3 -0
- data/test/db/models.rb +38 -0
- data/test/db/schema.rb +33 -0
- data/test/fixtures/addresses.yml +15 -0
- data/test/fixtures/roles.yml +4 -0
- data/test/fixtures/roles_users.yml +6 -0
- data/test/fixtures/services.yml +6 -0
- data/test/fixtures/subscriptions.yml +16 -0
- data/test/fixtures/users.yml +20 -0
- data/test/test_helper.rb +67 -0
- data/test/unit/active_record_predicates_test.rb +88 -0
- data/test/unit/attribute_formats_test.rb +40 -0
- data/test/unit/inheritance_test.rb +23 -0
- data/test/unit/predicates/aliased_test.rb +17 -0
- data/test/unit/predicates/association_predicate_test.rb +51 -0
- data/test/unit/predicates/base_test.rb +53 -0
- data/test/unit/predicates/blacklisted_predicate_test.rb +28 -0
- data/test/unit/predicates/domain_predicate_test.rb +27 -0
- data/test/unit/predicates/email_test.rb +82 -0
- data/test/unit/predicates/enumerated_predicate_test.rb +22 -0
- data/test/unit/predicates/hex_color_predicate_test.rb +29 -0
- data/test/unit/predicates/length_predicate_test.rb +85 -0
- data/test/unit/predicates/number_test.rb +109 -0
- data/test/unit/predicates/pattern_predicate_test.rb +29 -0
- data/test/unit/predicates/phone_number_predicate_test.rb +41 -0
- data/test/unit/predicates/required_predicate_test.rb +13 -0
- data/test/unit/predicates/same_as_predicate_test.rb +19 -0
- data/test/unit/predicates/time_test.rb +49 -0
- data/test/unit/predicates/unique_test.rb +58 -0
- data/test/unit/predicates/url_test.rb +86 -0
- data/test/unit/predicates/usa_state_test.rb +31 -0
- data/test/unit/predicates/usa_zip_code_test.rb +42 -0
- data/test/unit/semantic_attribute_test.rb +18 -0
- data/test/unit/semantic_attributes_test.rb +29 -0
- data/test/unit/validations_test.rb +121 -0
- metadata +235 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class ActiveRecordExtensionsTest < SemanticAttributes::TestCase
|
4
|
+
class FooUser < User
|
5
|
+
attr_accessor :foo
|
6
|
+
end
|
7
|
+
|
8
|
+
def setup
|
9
|
+
FooUser.semantic_attributes = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_module
|
13
|
+
assert ActiveRecord::Base.included_modules.include?(SemanticAttributes::Predicates)
|
14
|
+
assert ActiveRecord::Base.semantic_attributes.is_a?(SemanticAttributes::Set)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_declarative_sugar
|
18
|
+
@klass = FooUser
|
19
|
+
|
20
|
+
assert_nothing_raised 'creating predicates via method_missing sugar' do
|
21
|
+
@klass.foo_is_required
|
22
|
+
@klass.foo_has_a_length
|
23
|
+
@klass.foo_is_a_phone_number
|
24
|
+
end
|
25
|
+
|
26
|
+
assert @klass.semantic_attributes[:foo].has?(:required)
|
27
|
+
assert @klass.foo_is_required?
|
28
|
+
|
29
|
+
assert @klass.semantic_attributes[:foo].has?(:length)
|
30
|
+
assert @klass.foo_has_length?
|
31
|
+
|
32
|
+
assert @klass.semantic_attributes[:foo].has?(:phone_number)
|
33
|
+
assert @klass.foo_is_a_phone_number?
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_declarative_sugar_allows_inline_required
|
37
|
+
@klass = FooUser
|
38
|
+
|
39
|
+
@klass.foo_is_a_required_phone_number
|
40
|
+
assert !@klass.semantic_attributes[:foo].get(:phone_number).allow_empty?
|
41
|
+
assert @klass.foo_is_a_phone_number?
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_declarative_sugar_catches_unknown_attributes
|
45
|
+
@klass = FooUser
|
46
|
+
assert_raises SemanticAttributes::MissingAttribute do
|
47
|
+
@klass.unknown_is_required
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_declarative_sugar_for_mass_assignment
|
52
|
+
@klass = FooUser
|
53
|
+
assert_nothing_raised do
|
54
|
+
@klass.fields_are_required :foo
|
55
|
+
end
|
56
|
+
assert @klass.foo_is_required?
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_method_missing_still_works
|
60
|
+
assert_raise NoMethodError do User.i_do_not_exist end
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
## Want to test :expected_error_for with some common predicates.
|
65
|
+
##
|
66
|
+
|
67
|
+
class PasswordUser < PluginTestModels::User
|
68
|
+
attr_accessor :password, :password_confirmation
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_expected_error_for_with_unique_predicate
|
72
|
+
PasswordUser.stub_semantics_with(:login => :unique)
|
73
|
+
assert_not_nil PasswordUser.expected_error_for(:login, users(:bob).login)
|
74
|
+
assert_nil PasswordUser.expected_error_for(:login, "veryuniquelogin!")
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_expected_error_for_with_length_predicate
|
78
|
+
PasswordUser.stub_semantics_with(:login => {:length => {:above => 5}})
|
79
|
+
assert_not_nil PasswordUser.expected_error_for(:login, "a" * 4)
|
80
|
+
assert_nil PasswordUser.expected_error_for(:login, "a" * 6)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_expected_error_for_with_same_as_predicate
|
84
|
+
PasswordUser.stub_semantics_with(:password_confirmation => {:same_as => {:method => :password}})
|
85
|
+
assert_not_nil PasswordUser.expected_error_for(:password_confirmation, "one thing", :password => "another thing")
|
86
|
+
assert_nil PasswordUser.expected_error_for(:password_confirmation, "thing", :password => "thing")
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class AttributeFormatsTest < SemanticAttributes::TestCase
|
4
|
+
class User < User
|
5
|
+
cell_is_a_phone_number
|
6
|
+
cell_is_required
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@record = User.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_semantic_attribute_read_and_write
|
14
|
+
assert_nothing_raised do
|
15
|
+
@record.cell = '(222) 333.4444'
|
16
|
+
end
|
17
|
+
assert_equal '+12223334444', @record.attributes['cell'], 'value is stored in normalized format'
|
18
|
+
|
19
|
+
assert_equal '+12223334444', @record.cell, 'read defaults to machine format'
|
20
|
+
assert @record.respond_to?(:cell_for_human)
|
21
|
+
assert_equal '(222) 333-4444', @record.cell_for_human, 'reading in human format'
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_regular_attribute_read_and_write
|
25
|
+
assert_nothing_raised do
|
26
|
+
@record.login = 'hugo'
|
27
|
+
end
|
28
|
+
assert_equal 'hugo', @record.attributes['login']
|
29
|
+
assert !@record.respond_to?(:login_for_human)
|
30
|
+
assert_raise NoMethodError do @record.login_for_human end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_normalize
|
34
|
+
assert_equal '+12223334444', User.normalize(:cell, '(222) 333.4444')
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_humanize
|
38
|
+
assert_equal '(222) 333-4444', User.humanize(:cell, '+12223334444')
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class InheritanceTest < SemanticAttributes::TestCase
|
4
|
+
class Worker < User
|
5
|
+
attr_accessor :name_tag
|
6
|
+
name_tag_is_required
|
7
|
+
end
|
8
|
+
|
9
|
+
class Clerk < Worker
|
10
|
+
attr_accessor :pen
|
11
|
+
pen_is_required
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_parent_semantics
|
15
|
+
assert Worker.semantic_attributes[:name_tag].has?(:required)
|
16
|
+
assert !Worker.semantic_attributes[:pen].has?(:required)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_child_semantics
|
20
|
+
assert Clerk.semantic_attributes[:name_tag].has?(:required)
|
21
|
+
assert Clerk.semantic_attributes[:pen].has?(:required)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class AliasedPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Aliased.new(:foo, :options => {'10111001' => '185'})
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_formats
|
9
|
+
assert_equal '185', @predicate.to_human('10111001')
|
10
|
+
assert_equal '10111001', @predicate.normalize('185')
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_validation
|
14
|
+
assert @predicate.validate('185', nil)
|
15
|
+
assert !@predicate.validate('10111001', nil)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class AssociationPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def test_singular_associations
|
5
|
+
predicate = Predicates::Association.new(:subscription)
|
6
|
+
assert predicate.validate(users(:bob).subscription, users(:bob))
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_plural_associations
|
10
|
+
predicate = Predicates::Association.new(:subscriptions)
|
11
|
+
assert predicate.validate(services(:free).subscriptions, services(:free))
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_association_min
|
15
|
+
predicate = Predicates::Association.new(:subscriptions)
|
16
|
+
assert_equal 3, services(:free).subscriptions.size, "assuming three free subscriptions"
|
17
|
+
|
18
|
+
predicate.min = 4
|
19
|
+
predicate.max = nil
|
20
|
+
assert !predicate.validate(services(:free).subscriptions, services(:free)), "min works"
|
21
|
+
|
22
|
+
predicate.min = 3
|
23
|
+
predicate.max = nil
|
24
|
+
assert predicate.validate(services(:free).subscriptions, services(:free)), "min doesn't not work"
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_association_max
|
28
|
+
predicate = Predicates::Association.new(:subscriptions)
|
29
|
+
assert_equal 3, services(:free).subscriptions.size, "assuming three free subscriptions"
|
30
|
+
|
31
|
+
predicate.min = nil
|
32
|
+
predicate.max = 2
|
33
|
+
assert !predicate.validate(services(:free).subscriptions, services(:free)), "max works"
|
34
|
+
|
35
|
+
predicate.min = nil
|
36
|
+
predicate.max = 3
|
37
|
+
assert predicate.validate(services(:free).subscriptions, services(:free)), "max doesn't not work"
|
38
|
+
end
|
39
|
+
|
40
|
+
# def test_recursion_for_new_records
|
41
|
+
# # service has_many subscriptions
|
42
|
+
# Service.stub_semantics_with(:subscriptions => :association)
|
43
|
+
# # subscription belongs_to service
|
44
|
+
# Subscription.stub_semantics_with(:service => :association)
|
45
|
+
#
|
46
|
+
# unleaded = Service.new(:name => 'unleaded')
|
47
|
+
# unleaded.subscriptions = [Subscription.new(:service => unleaded, :user => users(:bob))]
|
48
|
+
#
|
49
|
+
# assert_nothing_raised {unleaded.valid?}
|
50
|
+
# end
|
51
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class BasePredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Base.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_unimplemented_methods
|
9
|
+
assert_equal 2, @predicate.method(:validate).arity
|
10
|
+
assert_raise NotImplementedError do @predicate.validate(nil, nil) end
|
11
|
+
assert_equal 'foo', @predicate.to_human('foo')
|
12
|
+
assert_equal 'foo', @predicate.normalize('foo')
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_initializer_assignment
|
16
|
+
predicate = Predicates::Base.new(:foo, :error_message => 'hello world')
|
17
|
+
assert_equal 'hello world', predicate.error_message
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_initializer_assignment_with_typos
|
21
|
+
assert_raises NoMethodError do
|
22
|
+
Predicates::Base.new(:foo, :unknown_option => "something")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_default_values
|
27
|
+
assert @predicate.allow_empty?, "allow empty/nil values by default"
|
28
|
+
assert_equal :both, @predicate.validate_on, "validate on create and update by default"
|
29
|
+
assert_equal :invalid, @predicate.error_message, "error message is a bland :invalid by default"
|
30
|
+
assert_equal Hash.new, @predicate.error_binds, "there are no binds by default"
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_or_empty
|
34
|
+
predicate = Predicates::Base.new(:foo, :or_empty => true)
|
35
|
+
assert predicate.allow_empty?
|
36
|
+
predicate = Predicates::Base.new(:foo, :or_empty => false)
|
37
|
+
assert !predicate.allow_empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_message_aliasing
|
41
|
+
predicate = Predicates::Base.new(:foo)
|
42
|
+
predicate.error_message = "something"
|
43
|
+
assert_equal "something", predicate.message
|
44
|
+
predicate.message = "another thing"
|
45
|
+
assert_equal "another thing", predicate.error_message
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_string_errors_are_preserved
|
49
|
+
predicate = Predicates::Base.new(:foo)
|
50
|
+
predicate.error_message = "something"
|
51
|
+
assert_equal "something", predicate.error
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class BlacklistedPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Blacklisted.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_case_insensitive_validation
|
9
|
+
@predicate.case_sensitive = false
|
10
|
+
@predicate.restricted = [1, "foo"]
|
11
|
+
assert !@predicate.validate(1, nil)
|
12
|
+
assert !@predicate.validate("1", nil)
|
13
|
+
assert !@predicate.validate("foo", nil)
|
14
|
+
assert !@predicate.validate("foO", nil)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_case_sensitive_validation
|
18
|
+
@predicate.case_sensitive = true
|
19
|
+
|
20
|
+
@predicate.restricted = [1, 2, '3']
|
21
|
+
|
22
|
+
assert !@predicate.validate(1, nil)
|
23
|
+
assert !@predicate.validate(2, nil)
|
24
|
+
assert @predicate.validate(3, nil), 'type is important'
|
25
|
+
assert !@predicate.validate('3', nil)
|
26
|
+
assert @predicate.validate(6, nil)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class DomainPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Domain.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_valid_domains
|
9
|
+
%w(example.com www.example.com).each do |domain|
|
10
|
+
assert @predicate.validate(domain, nil), "#{domain} is a valid domain"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_invalid_domains
|
15
|
+
%w(example example.com/foo http://example.com 123.45.6.78).each do |domain|
|
16
|
+
assert !@predicate.validate(domain, nil), "#{domain} is not a valid domain"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_normalize
|
21
|
+
assert_equal "example.com", @predicate.normalize("http://example.com:8080/foo")
|
22
|
+
assert_equal "example.com", @predicate.normalize("example.com/foo")
|
23
|
+
assert_equal nil, @predicate.normalize(nil)
|
24
|
+
assert_equal "", @predicate.normalize("")
|
25
|
+
assert_equal "example.com", @predicate.normalize("example.com")
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class EmailPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Email.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
##
|
9
|
+
## Test cases from Alex Dunae's validates_email_format_of
|
10
|
+
## see http://code.dunae.ca/validates_email_format_of/trunk/test/validates_email_format_of_test.rb
|
11
|
+
##
|
12
|
+
|
13
|
+
def test_should_allow_valid_email_addresses
|
14
|
+
['valid@example.com',
|
15
|
+
'Valid@test.example.com',
|
16
|
+
'valid+valid123@test.example.com',
|
17
|
+
'valid_valid123@test.example.com',
|
18
|
+
'valid-valid+123@test.example.co.uk',
|
19
|
+
'valid-valid+1.23@test.example.com.au',
|
20
|
+
'valid@example.co.uk',
|
21
|
+
'v@example.com',
|
22
|
+
'valid@example.ca',
|
23
|
+
'valid_@example.com',
|
24
|
+
'valid123.456@example.org',
|
25
|
+
'valid123.456@example.travel',
|
26
|
+
'valid123.456@example.museum',
|
27
|
+
'valid@example.mobi',
|
28
|
+
'valid@example.info',
|
29
|
+
'valid-@example.com',
|
30
|
+
# from RFC 3696, page 6
|
31
|
+
'customer/department=shipping@example.com',
|
32
|
+
'$A12345@example.com',
|
33
|
+
'!def!xyz%abc@example.com',
|
34
|
+
'_somename@example.com',
|
35
|
+
# apostrophes
|
36
|
+
"test'test@example.com",
|
37
|
+
# from http://www.rfc-editor.org/errata_search.php?rfc=3696
|
38
|
+
'"Abc\@def"@example.com',
|
39
|
+
'"Fred\ Bloggs"@example.com',
|
40
|
+
'"Joe.\\Blow"@example.com',
|
41
|
+
].each do |email|
|
42
|
+
assert @predicate.validate(email, nil), "#{email} should be valid"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_should_not_allow_invalid_email_addresses
|
47
|
+
['invalid@example-com',
|
48
|
+
# period can not start local part
|
49
|
+
'.invalid@example.com',
|
50
|
+
# period can not end local part
|
51
|
+
'invalid.@example.com',
|
52
|
+
# period can not appear twice consecutively in local part
|
53
|
+
'invali..d@example.com',
|
54
|
+
'invalid@example.com.',
|
55
|
+
'invalid@example.com_',
|
56
|
+
'invalid@example.com-',
|
57
|
+
'invalid-example.com',
|
58
|
+
'invalid@example.b#r.com',
|
59
|
+
'invalid@example.c',
|
60
|
+
'invali d@example.com',
|
61
|
+
'invalidexample.com',
|
62
|
+
'invalid@example.',
|
63
|
+
# from http://tools.ietf.org/html/rfc3696, page 5
|
64
|
+
# corrected in http://www.rfc-editor.org/errata_search.php?rfc=3696
|
65
|
+
'Fred\ Bloggs_@example.com',
|
66
|
+
'Abc\@def+@example.com',
|
67
|
+
'Joe.\\Blow@example.com',
|
68
|
+
# too lengthy
|
69
|
+
"#{"a".rjust(65, 'a')}@example.com",
|
70
|
+
"test@#{"a.com".rjust(256, 'a')}"
|
71
|
+
].each do |email|
|
72
|
+
assert !@predicate.validate(email, nil), "#{email} should not be valid"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_with_mx_record
|
77
|
+
assert @predicate.validate('test@example.com', nil), 'syntax check only'
|
78
|
+
@predicate.with_mx_record = true
|
79
|
+
assert !@predicate.validate('test@example.com', nil), 'syntax and mx check'
|
80
|
+
assert @predicate.validate('test@gmail.com', nil)
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class EnumeratedPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Enumerated.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_validation
|
9
|
+
@predicate.options = [1, 2, '3']
|
10
|
+
|
11
|
+
assert @predicate.validate(1, nil)
|
12
|
+
assert @predicate.validate(2, nil)
|
13
|
+
assert !@predicate.validate(3, nil), 'type is important'
|
14
|
+
assert @predicate.validate('3', nil)
|
15
|
+
assert !@predicate.validate(6, nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_or_empty
|
19
|
+
assert !Predicates::Enumerated.new(:foo).allow_empty?
|
20
|
+
assert Predicates::Enumerated.new(:foo, :or_empty => true).allow_empty?
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class HexColorPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::HexColor.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_normalize_conversions
|
9
|
+
assert_equal "", @predicate.normalize("")
|
10
|
+
assert_equal nil, @predicate.normalize(nil)
|
11
|
+
assert_equal "#123456", @predicate.normalize("123456"), "adds a pound sign"
|
12
|
+
assert_equal "#123456", @predicate.normalize("#123456"), "does not duplicate the pound sign"
|
13
|
+
assert_equal "#112233", @predicate.normalize("123"), "expand three-character syntax"
|
14
|
+
assert_equal "#112233", @predicate.normalize("#123"), "handles existing pound sign when expanding to six characters"
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_valid_colors
|
18
|
+
%w(#123456 #fff000).each do |color|
|
19
|
+
assert @predicate.validate(color, nil), "#{color} should be a valid hex color"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_invalid_colors
|
24
|
+
%w(1 12 123 1234 12345 abc zzz kf0f00).each do |color|
|
25
|
+
assert !@predicate.validate(color, nil), "#{color} should be a invalid hex color"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
3
|
+
|
4
|
+
class LengthPredicateTest < SemanticAttributes::TestCase
|
5
|
+
def setup
|
6
|
+
@predicate = Predicates::Length.new(:foo)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_range
|
10
|
+
@predicate.range = 1..5
|
11
|
+
assert_equal :wrong_length, @predicate.error_message
|
12
|
+
|
13
|
+
assert !@predicate.validate('', nil)
|
14
|
+
assert @predicate.validate('1', nil)
|
15
|
+
assert @predicate.validate('12345', nil)
|
16
|
+
assert !@predicate.validate('123456', nil)
|
17
|
+
|
18
|
+
@predicate.range = 1...5
|
19
|
+
assert_equal :wrong_length, @predicate.error_message, 'same message for inclusive range'
|
20
|
+
assert !@predicate.validate('12345', nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_min
|
24
|
+
@predicate.above = 5
|
25
|
+
assert_equal :too_short, @predicate.error_message
|
26
|
+
|
27
|
+
assert !@predicate.validate('', nil)
|
28
|
+
assert !@predicate.validate('12345', nil)
|
29
|
+
assert @predicate.validate('123456', nil)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_max
|
33
|
+
@predicate.below = 5
|
34
|
+
assert_equal :too_long, @predicate.error_message
|
35
|
+
|
36
|
+
assert @predicate.validate('', nil)
|
37
|
+
assert @predicate.validate('1234', nil)
|
38
|
+
assert !@predicate.validate('12345', nil)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_exact
|
42
|
+
@predicate.exactly = 5
|
43
|
+
assert_equal :inexact_length, @predicate.error_message
|
44
|
+
|
45
|
+
assert !@predicate.validate('', nil)
|
46
|
+
assert !@predicate.validate('1234', nil)
|
47
|
+
assert @predicate.validate('12345', nil)
|
48
|
+
assert !@predicate.validate('123456', nil)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_symbols
|
52
|
+
@predicate.range = 2..3
|
53
|
+
assert @predicate.validate(:abc, nil)
|
54
|
+
assert !@predicate.validate(:abcdef, nil)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_numbers
|
58
|
+
@predicate.range = 2..3
|
59
|
+
assert !@predicate.validate(3, nil)
|
60
|
+
assert @predicate.validate(123, nil)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_arrays
|
64
|
+
@predicate.range = 2..3
|
65
|
+
assert !@predicate.validate(['abc'], nil)
|
66
|
+
assert @predicate.validate(['abc', 'def', 'ghi'], nil)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_multibyte_characters
|
70
|
+
$KCODE = "UTF8" if RUBY_VERSION < "1.9" # so ActiveSupport uses the UTF8Handler for Chars
|
71
|
+
@predicate.exactly = 4
|
72
|
+
assert @predicate.validate('ægis', nil)
|
73
|
+
assert !@predicate.validate('aegis', nil)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_normalization
|
77
|
+
assert_equal "hello\nworld", @predicate.normalize("hello\r\nworld")
|
78
|
+
assert_equal ['a', 'b'], @predicate.normalize(['a', 'b'])
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_no_options
|
82
|
+
assert_raise RuntimeError do @predicate.error_message end
|
83
|
+
assert @predicate.validate(nil, nil)
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class NumberPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Number.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_basic_error_message
|
9
|
+
assert_equal :not_a_number, @predicate.error_message
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_integers
|
13
|
+
@predicate.integer = true
|
14
|
+
|
15
|
+
assert @predicate.validate(0, nil)
|
16
|
+
assert @predicate.validate(-15, nil)
|
17
|
+
assert @predicate.validate(15, nil)
|
18
|
+
assert @predicate.validate('0', nil)
|
19
|
+
assert @predicate.validate('-15', nil)
|
20
|
+
assert @predicate.validate('+15', nil)
|
21
|
+
|
22
|
+
assert !@predicate.validate('1.0', nil)
|
23
|
+
assert !@predicate.validate(1.0, nil)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_floats
|
27
|
+
assert !@predicate.integer
|
28
|
+
assert @predicate.validate(5, nil), 'still allows integers'
|
29
|
+
assert @predicate.validate(-5, nil)
|
30
|
+
assert @predicate.validate(5.2, nil)
|
31
|
+
assert @predicate.validate(-5.2, nil)
|
32
|
+
assert @predicate.validate(0.0, nil)
|
33
|
+
assert @predicate.validate(5.2e5, nil)
|
34
|
+
assert @predicate.validate(5.2e-5, nil)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_min
|
38
|
+
@predicate.above = 5
|
39
|
+
assert_equal :greater_than, @predicate.error_message
|
40
|
+
|
41
|
+
assert !@predicate.validate(-10, nil)
|
42
|
+
assert !@predicate.validate(-5, nil)
|
43
|
+
assert !@predicate.validate(0, nil)
|
44
|
+
assert !@predicate.validate(5, nil)
|
45
|
+
assert @predicate.validate(10, nil)
|
46
|
+
|
47
|
+
assert @predicate.validate(5.0001, nil)
|
48
|
+
@predicate.integer = true
|
49
|
+
assert !@predicate.validate(5.0001, nil)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_min_inclusive
|
53
|
+
@predicate.at_least = 5
|
54
|
+
assert_equal 5, @predicate.above
|
55
|
+
assert @predicate.inclusive
|
56
|
+
assert_equal :greater_than_or_equal_to, @predicate.error_message
|
57
|
+
|
58
|
+
assert !@predicate.validate(4, nil)
|
59
|
+
assert @predicate.validate(5, nil)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_max
|
63
|
+
@predicate.below = 5
|
64
|
+
assert_equal :less_than, @predicate.error_message
|
65
|
+
|
66
|
+
assert @predicate.validate(-10, nil)
|
67
|
+
assert @predicate.validate(-5, nil)
|
68
|
+
assert @predicate.validate(0, nil)
|
69
|
+
assert !@predicate.validate(5, nil)
|
70
|
+
assert !@predicate.validate(10, nil)
|
71
|
+
|
72
|
+
assert @predicate.validate(4.9999, nil)
|
73
|
+
@predicate.integer = true
|
74
|
+
assert !@predicate.validate(4.9999, nil)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_max_inclusive
|
78
|
+
@predicate.no_more_than = 5
|
79
|
+
assert_equal 5, @predicate.below
|
80
|
+
assert @predicate.inclusive
|
81
|
+
assert_equal :less_than_or_equal_to, @predicate.error_message
|
82
|
+
|
83
|
+
assert @predicate.validate(5, nil)
|
84
|
+
assert !@predicate.validate(6, nil)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_range
|
88
|
+
@predicate.range = -5...5
|
89
|
+
assert_equal :between, @predicate.error_message
|
90
|
+
|
91
|
+
assert !@predicate.validate(-10, nil)
|
92
|
+
assert @predicate.validate(-5, nil)
|
93
|
+
assert @predicate.validate(0, nil)
|
94
|
+
assert !@predicate.validate(5, nil)
|
95
|
+
assert !@predicate.validate(10, nil)
|
96
|
+
|
97
|
+
assert @predicate.validate(4.9999, nil)
|
98
|
+
@predicate.integer = true
|
99
|
+
assert !@predicate.validate(4.9999, nil)
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_range_inclusive
|
103
|
+
@predicate.range = -5..5
|
104
|
+
assert_equal :between, @predicate.error_message
|
105
|
+
|
106
|
+
assert @predicate.validate(5, nil)
|
107
|
+
assert !@predicate.validate(6, nil)
|
108
|
+
end
|
109
|
+
end
|