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,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class PatternPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Pattern.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_regexp_pattern
|
9
|
+
@predicate.like = /bar$/
|
10
|
+
|
11
|
+
assert @predicate.validate('foobar', nil)
|
12
|
+
assert @predicate.validate(:foobar, nil)
|
13
|
+
assert !@predicate.validate('foobario', nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_string_pattern
|
17
|
+
@predicate.like = 'bar'
|
18
|
+
|
19
|
+
assert @predicate.validate('foobar', nil)
|
20
|
+
assert @predicate.validate(:bar, nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_line_breaks
|
24
|
+
@predicate.like = /^hello world$/
|
25
|
+
assert @predicate.validate("malicious\nhello world\ntext", nil)
|
26
|
+
@predicate.like = /\Ahello world\Z/
|
27
|
+
assert !@predicate.validate("malicious\nhello world\ntext", nil)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class PhoneNumberPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::PhoneNumber.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_north_american_bias
|
9
|
+
assert_equal 1, @predicate.implied_country_code, 'default implied country code is 1 (north america)'
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_to_human
|
13
|
+
assert_equal '(222) 333-4444', @predicate.to_human('+12223334444'), 'NANP human format'
|
14
|
+
assert_equal '753', @predicate.to_human('753'), 'unknown formats untouched'
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_validate_nanp
|
18
|
+
assert !@predicate.validate('12223334444', nil), 'requires country code indicator (+)'
|
19
|
+
assert @predicate.validate('+12223334444', nil), 'requires country code indicator (+)'
|
20
|
+
|
21
|
+
assert !@predicate.validate('+11223334444', nil), 'first digit of area code may not be 1'
|
22
|
+
assert !@predicate.validate('+12923334444', nil), 'second digit of area code may not be 9'
|
23
|
+
assert !@predicate.validate('+12221334444', nil), 'first digit of exchange code may not be 1'
|
24
|
+
assert !@predicate.validate('+1222333444', nil), 'must be 11 characters long'
|
25
|
+
|
26
|
+
assert !@predicate.validate('+12225550155', nil), 'restricted 555 code'
|
27
|
+
assert @predicate.validate('+12225550099', nil), 'allowed 555 code'
|
28
|
+
assert @predicate.validate('+12225550200', nil), 'allowed 555 code'
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_normalize
|
32
|
+
@predicate.implied_country_code = 99
|
33
|
+
|
34
|
+
assert_equal '+12223334444', @predicate.normalize('12223334444'), 'recognizes north american country code without +'
|
35
|
+
assert_equal '+12223334444', @predicate.normalize('+12223334444'), 'leaves country codes alone if they exist'
|
36
|
+
assert_equal '+992223334444', @predicate.normalize('2223334444'), 'adds implied country code'
|
37
|
+
assert_equal '+12223334444', @predicate.normalize('1 (222) 333.4444'), 'ignores various formatting characters'
|
38
|
+
assert_equal '+992223334444', @predicate.normalize('222typo333oops4444'), 'ignores non-numeric characters'
|
39
|
+
assert_equal '', @predicate.normalize(''), 'leaves blanks intact'
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class RequiredPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Required.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_allow_empty
|
9
|
+
assert !@predicate.allow_empty?
|
10
|
+
@predicate.or_empty = false
|
11
|
+
assert !@predicate.allow_empty?
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class SameAsPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::SameAs.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_validation
|
9
|
+
@predicate.method = :bar
|
10
|
+
|
11
|
+
record = mock()
|
12
|
+
record.stubs(:bar).returns("something")
|
13
|
+
|
14
|
+
assert @predicate.validate('something', record)
|
15
|
+
assert !@predicate.validate('something else', record)
|
16
|
+
assert !@predicate.validate(nil, record)
|
17
|
+
assert !@predicate.validate(5, record)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class TimePredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Time.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_default_validation
|
9
|
+
assert !@predicate.validate('2007-07-19 00:00:00', nil), 'value may not be a string, even if string parses'
|
10
|
+
assert !@predicate.validate(1184817600, nil), 'value must not be a timestamp'
|
11
|
+
assert @predicate.validate(Time.parse('2007-07-19 00:00:00'), nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_validation_with_before
|
15
|
+
@predicate.before = '2007-07-19 00:00:00'
|
16
|
+
assert_equal Time.parse('2007-07-19 00:00:00'), @predicate.before
|
17
|
+
|
18
|
+
assert @predicate.validate(Time.parse('2007-07-18 23:59:00'), nil), 'may be earlier'
|
19
|
+
assert !@predicate.validate(Time.parse('2007-07-19 00:00:00'), nil), 'may not be equal'
|
20
|
+
assert !@predicate.validate(Time.parse('2007-07-19 00:00:01'), nil), 'may not be after'
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_validation_with_after
|
24
|
+
@predicate.after = '2007-07-19 00:00:00'
|
25
|
+
assert_equal Time.parse('2007-07-19 00:00:00'), @predicate.after
|
26
|
+
|
27
|
+
assert !@predicate.validate(Time.parse('2007-07-18 23:59:00'), nil), 'may not be before'
|
28
|
+
assert !@predicate.validate(Time.parse('2007-07-19 00:00:00'), nil), 'may not be equal'
|
29
|
+
assert @predicate.validate(Time.parse('2007-07-19 00:00:01'), nil), 'may be afterwards'
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_validation_with_before_and_after
|
33
|
+
@predicate.before = '2007-01-01 00:00:00'
|
34
|
+
@predicate.after = '2006-01-01 00:00:00'
|
35
|
+
|
36
|
+
assert !@predicate.validate(Time.parse('2005-01-01 00:00:00'), nil), 'may not be earlier'
|
37
|
+
assert @predicate.validate(Time.parse('2006-06-01 00:00:00'), nil), 'may be inbetween'
|
38
|
+
assert !@predicate.validate(Time.parse('2008-01-01 00:00:00'), nil), 'may not be after'
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_validation_with_distance
|
42
|
+
@predicate.distance = (-1.hour)..(1.hour)
|
43
|
+
assert !@predicate.validate(61.minutes.ago, nil)
|
44
|
+
assert @predicate.validate(59.minutes.ago, nil)
|
45
|
+
assert @predicate.validate(Time.now, nil)
|
46
|
+
assert @predicate.validate(Time.now + 59.minutes, nil)
|
47
|
+
assert !@predicate.validate(Time.now + 61.minutes, nil)
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class UniquePredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
User.stub_semantics_with(:login => :unique)
|
6
|
+
@predicate = User.semantic_attributes[:login].get(:unique)
|
7
|
+
|
8
|
+
@fred = User.new(:first_name => 'fred', :last_name => 'flat')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_defaults
|
12
|
+
assert_equal false, @predicate.case_sensitive, 'case insensitive by default'
|
13
|
+
assert_equal [], @predicate.scope, 'default scope is empty array'
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_uniqueness_validation_scoping
|
17
|
+
assert !@predicate.validate(users(:bob).login, @fred)
|
18
|
+
@predicate.scope = :last_name
|
19
|
+
assert @predicate.validate(users(:bob).login, @fred), "when scoped, it becomes valid"
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_case_sensitive_uniqueness_validation
|
23
|
+
@predicate.case_sensitive = true
|
24
|
+
|
25
|
+
assert !@predicate.validate(users(:bob).login, @fred), "case match means not unique"
|
26
|
+
assert @predicate.validate(users(:bob).login.upcase, @fred), "case mismatch means unique"
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_case_insensitive_uniqueness_validation
|
30
|
+
@predicate.case_sensitive = false
|
31
|
+
|
32
|
+
assert !@predicate.validate(users(:bob).login, @fred), "case match means not unique"
|
33
|
+
assert !@predicate.validate(users(:bob).login.upcase, @fred), "case mismatch is still not unique"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_uniqueness_validation_excludes_self
|
37
|
+
@fred.update_attribute(:login, 'fred')
|
38
|
+
|
39
|
+
assert @predicate.validate(@fred.login, @fred), "still valid after being saved"
|
40
|
+
assert !@predicate.validate(users(:bob).login, @fred), "but still not valid when duplicating a *different* record"
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_uniqueness_of_numbers
|
44
|
+
Subscription.stub_semantics_with(:user_id => :unique)
|
45
|
+
|
46
|
+
bobs_second_subscription = Subscription.new(:user => users(:bob), :service => services(:premium))
|
47
|
+
assert !bobs_second_subscription.valid?
|
48
|
+
assert bobs_second_subscription.errors[:user_id]
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_case_insensitive_is_non_destructive
|
52
|
+
@predicate.case_sensitive = false
|
53
|
+
@fred.update_attribute(:login, "Fred")
|
54
|
+
|
55
|
+
@predicate.validate(@fred.login, @fred)
|
56
|
+
assert_equal "Fred", @fred.login, "attribute value was not changed by validate()"
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class UrlPredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::Url.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_ip_addresses
|
9
|
+
assert_equal true, @predicate.allow_ip_address, 'default allow_ip_address is true'
|
10
|
+
assert @predicate.validate('http://192.168.0.10', nil), 'ip address'
|
11
|
+
assert @predicate.validate('http://www.example.com', nil), 'basic url still works'
|
12
|
+
|
13
|
+
@predicate.allow_ip_address = false
|
14
|
+
assert !@predicate.validate('http://192.168.0.10', nil), 'ip address'
|
15
|
+
assert @predicate.validate('http://www.example.com', nil), 'basic url still works'
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_schemes
|
19
|
+
assert_equal ['http', 'https'], @predicate.schemes, 'default allowed schemes'
|
20
|
+
|
21
|
+
assert @predicate.validate('http://example.com/', nil)
|
22
|
+
assert !@predicate.validate('ftp://example.com/', nil)
|
23
|
+
|
24
|
+
@predicate.schemes = ['ftp']
|
25
|
+
|
26
|
+
assert !@predicate.validate('http://example.com/', nil)
|
27
|
+
assert @predicate.validate('ftp://example.com/', nil)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_domains
|
31
|
+
assert_equal nil, @predicate.domains, 'default allows any domain'
|
32
|
+
|
33
|
+
assert @predicate.validate('http://example.com', nil)
|
34
|
+
assert @predicate.validate('http://example.co.uk', nil)
|
35
|
+
assert @predicate.validate('http://example.xyz', nil)
|
36
|
+
assert !@predicate.validate('http://example', nil)
|
37
|
+
assert !@predicate.validate('http://example.', nil)
|
38
|
+
assert @predicate.validate('http://127.0.0.1', nil)
|
39
|
+
|
40
|
+
@predicate.domains = ['com', 'net', 'org']
|
41
|
+
|
42
|
+
assert @predicate.validate('http://example.com', nil)
|
43
|
+
assert !@predicate.validate('http://example.co.uk', nil)
|
44
|
+
assert !@predicate.validate('http://example.xyz', nil)
|
45
|
+
assert !@predicate.validate('http://example', nil)
|
46
|
+
assert !@predicate.validate('http://example.', nil)
|
47
|
+
assert !@predicate.validate('http://127.0.0.1', nil)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_ports
|
51
|
+
assert_equal nil, @predicate.ports, 'default allows any port'
|
52
|
+
|
53
|
+
assert @predicate.validate('http://example.com', nil)
|
54
|
+
assert @predicate.validate('http://example.com:80', nil)
|
55
|
+
assert @predicate.validate('http://example.com:443', nil)
|
56
|
+
|
57
|
+
@predicate.ports = [nil, 80]
|
58
|
+
|
59
|
+
assert @predicate.validate('http://example.com', nil)
|
60
|
+
assert @predicate.validate('http://example.com:80', nil)
|
61
|
+
assert !@predicate.validate('http://example.com:443', nil)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_bad_url
|
65
|
+
assert !@predicate.validate('http:\\\\example.com\\', nil)
|
66
|
+
assert !@predicate.validate('example.com', nil), 'human format does not validate'
|
67
|
+
|
68
|
+
assert_equal 'http:\\\\example.com\\', @predicate.normalize('http:\\\\example.com\\'), 'malformed human format is preserved'
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_implied_scheme
|
72
|
+
assert_equal 'http', @predicate.implied_scheme
|
73
|
+
|
74
|
+
assert_equal 'http://example.com/', @predicate.normalize('http://example.com/'), 'no changes'
|
75
|
+
assert_equal 'ftp://example.com/', @predicate.normalize('ftp://example.com/'), 'no changes when scheme is not default'
|
76
|
+
assert_equal 'http://example.com', @predicate.normalize('example.com'), 'basic implied scheme support'
|
77
|
+
assert_equal 'http://example.com:443', @predicate.normalize('example.com:443'), 'preserve ports'
|
78
|
+
|
79
|
+
@predicate.implied_scheme = nil
|
80
|
+
|
81
|
+
assert_equal 'http://example.com/', @predicate.normalize('http://example.com/')
|
82
|
+
assert_equal 'ftp://example.com/', @predicate.normalize('ftp://example.com/')
|
83
|
+
assert_equal 'example.com', @predicate.normalize('example.com')
|
84
|
+
assert_equal 'example.com:80', @predicate.normalize('example.com:80')
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class UsaStatePredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::UsaState.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_fixed_options
|
9
|
+
assert_raise NoMethodError do @predicate.options = {} end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_with_territories
|
13
|
+
@predicate.with_territories = true
|
14
|
+
assert_equal :us_state_or_territory, @predicate.error_message
|
15
|
+
|
16
|
+
assert @predicate.options.include?('Guam')
|
17
|
+
assert @predicate.options.include?('Minnesota')
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_without_territories
|
21
|
+
@predicate.with_territories = false
|
22
|
+
assert_equal :us_state, @predicate.error_message
|
23
|
+
|
24
|
+
assert !@predicate.options.include?('Guam')
|
25
|
+
assert @predicate.options.include?('Minnesota')
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_defaults
|
29
|
+
assert !@predicate.with_territories?
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
2
|
+
|
3
|
+
class UsaZipCodePredicateTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@predicate = Predicates::UsaZipCode.new(:foo)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_fixed_pattern
|
9
|
+
assert_raise NoMethodError do @predicate.like = nil end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_extended_allowed
|
13
|
+
@predicate.extended = :allowed
|
14
|
+
|
15
|
+
assert @predicate.validate(12345, nil)
|
16
|
+
assert @predicate.validate('12345', nil)
|
17
|
+
assert @predicate.validate('12345-4321', nil)
|
18
|
+
assert !@predicate.validate('12345-4', nil)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_extended_required
|
22
|
+
@predicate.extended = :required
|
23
|
+
|
24
|
+
assert !@predicate.validate(12345, nil)
|
25
|
+
assert !@predicate.validate('12345', nil)
|
26
|
+
assert @predicate.validate('12345-4321', nil)
|
27
|
+
assert !@predicate.validate('12345-4', nil)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_non_extended
|
31
|
+
@predicate.extended = false
|
32
|
+
|
33
|
+
assert @predicate.validate(12345, nil)
|
34
|
+
assert @predicate.validate('12345', nil)
|
35
|
+
assert !@predicate.validate('12345-4321', nil)
|
36
|
+
assert !@predicate.validate('12345-4', nil)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_defaults
|
40
|
+
assert !@predicate.extended
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class SemanticAttributeTest < SemanticAttributes::TestCase
|
4
|
+
def test_everything
|
5
|
+
@field = SemanticAttributes::Attribute.new('a')
|
6
|
+
assert_equal :a, @field.field
|
7
|
+
|
8
|
+
assert !@field.has?('required')
|
9
|
+
assert_nothing_raised do @field.add 'required' end
|
10
|
+
assert @field.has?('required')
|
11
|
+
assert @field.get('required').is_a?(Predicates::Required)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_short_names
|
15
|
+
@attribute = SemanticAttributes::Attribute.new('a')
|
16
|
+
assert_equal Predicates::PhoneNumber, @attribute.send(:class_of, 'phone_number')
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class SemanticAttributesTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
@set = SemanticAttributes::Set.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_add
|
9
|
+
assert @set.instance_variable_get('@set').empty?
|
10
|
+
assert_raises ArgumentError, "can't add by symbol" do @set.add :foo end
|
11
|
+
assert @set.instance_variable_get('@set').empty?
|
12
|
+
assert_nothing_raised "can add a SemanticAttribute instance" do @set.add SemanticAttributes::Attribute.new(:foo) end
|
13
|
+
assert @set.instance_variable_get('@set').size == 1
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_find
|
17
|
+
assert !@set.include?(:a)
|
18
|
+
|
19
|
+
# test retrieving a previously set field
|
20
|
+
a = SemanticAttributes::Attribute.new(:a)
|
21
|
+
@set.add a
|
22
|
+
assert @set.include?(:a)
|
23
|
+
assert_equal a, @set[:a], 'can find previously set fields'
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_that_find_creates_if_not_found
|
27
|
+
assert @set[:a].is_a?(SemanticAttributes::Attribute), 'can create an Attribute by requesting it from the set'
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class ValidationsTest < SemanticAttributes::TestCase
|
4
|
+
def setup
|
5
|
+
User.stub_semantics_with(:login => :required)
|
6
|
+
@record = User.new
|
7
|
+
@login_required = @record.semantic_attributes['login'].get('required')
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_validation_hook
|
11
|
+
@record.expects(:validate_predicates)
|
12
|
+
@record.valid?
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_validation_errors
|
16
|
+
assert !@record.valid?
|
17
|
+
assert @record.errors[:login]
|
18
|
+
assert_equal ['is required.'], @record.errors[:login]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_validate_on_default
|
22
|
+
assert_equal :both, @record.semantic_attributes['login'].get('required').validate_on
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
## attr_valid?
|
27
|
+
##
|
28
|
+
|
29
|
+
def test_attribute_valid?
|
30
|
+
assert !@record.login_valid?
|
31
|
+
@record.login = "foo"
|
32
|
+
assert @record.login_valid?
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_attribute_valid_with_conditional_validation
|
36
|
+
assert !@record.login_valid?
|
37
|
+
@record.stubs(:validate_predicate?).returns(false)
|
38
|
+
assert @record.login_valid?
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
## validate_predicate?
|
43
|
+
##
|
44
|
+
|
45
|
+
def test_validate_predicate_with_validate_if_symbol
|
46
|
+
@record.stubs(:no).returns(false)
|
47
|
+
@record.stubs(:yes).returns(true)
|
48
|
+
|
49
|
+
assert @record.send(:validate_predicate?, @login_required)
|
50
|
+
|
51
|
+
@record.semantic_attributes['login'].get('required').validate_if = :no
|
52
|
+
assert !@record.send(:validate_predicate?, @login_required)
|
53
|
+
|
54
|
+
@record.semantic_attributes['login'].get('required').validate_if = :yes
|
55
|
+
assert @record.send(:validate_predicate?, @login_required)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_validate_predicate_with_validate_if_proc
|
59
|
+
assert @record.send(:validate_predicate?, @login_required)
|
60
|
+
|
61
|
+
@record.semantic_attributes['login'].get('required').validate_if = proc {false}
|
62
|
+
assert !@record.send(:validate_predicate?, @login_required)
|
63
|
+
|
64
|
+
@record.semantic_attributes['login'].get('required').validate_if = proc {true}
|
65
|
+
assert @record.send(:validate_predicate?, @login_required)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_validate_predicate_with_validate_on_create
|
69
|
+
@record = users(:george)
|
70
|
+
@record.login = nil
|
71
|
+
|
72
|
+
# test assumptions
|
73
|
+
assert !@record.new_record?
|
74
|
+
assert @record.send(:validate_predicate?, @login_required)
|
75
|
+
|
76
|
+
# the test
|
77
|
+
@record.semantic_attributes['login'].get('required').validate_on = :create
|
78
|
+
assert !@record.send(:validate_predicate?, @login_required)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_validate_predicate_with_validate_on_update
|
82
|
+
# test assumptions
|
83
|
+
assert @record.new_record?
|
84
|
+
assert @record.send(:validate_predicate?, @login_required)
|
85
|
+
|
86
|
+
# the test
|
87
|
+
@record.semantic_attributes['login'].get('required').validate_on = :update
|
88
|
+
assert !@record.send(:validate_predicate?, @login_required)
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
## :or_empty
|
93
|
+
##
|
94
|
+
|
95
|
+
def test_allow_empty
|
96
|
+
User.stub_semantics_with(:login => {:number => {:or_empty => true}})
|
97
|
+
|
98
|
+
# empty values should skip the validate method
|
99
|
+
predicate = @record.semantic_attributes['login'].get('number')
|
100
|
+
predicate.expects(:validate).never
|
101
|
+
|
102
|
+
[nil, '', []].each do |empty_value|
|
103
|
+
@record.login = empty_value
|
104
|
+
assert @record.valid?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_disallow_empty
|
109
|
+
User.stub_semantics_with(:login => {:number => {:or_empty => false}})
|
110
|
+
|
111
|
+
# empty values should skip the validate method
|
112
|
+
predicate = @record.semantic_attributes['login'].get('number')
|
113
|
+
predicate.expects(:validate).never
|
114
|
+
|
115
|
+
[nil, '', []].each do |empty_value|
|
116
|
+
@record.login = empty_value
|
117
|
+
assert !@record.valid?
|
118
|
+
assert @record.errors[:login]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|