semantic_attributes 1.0.2
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/.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
|