semantic_attributes 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +99 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README +54 -0
  6. data/Rakefile +37 -0
  7. data/gist.rdoc +208 -0
  8. data/lib/active_record/validation_recursion_control.rb +33 -0
  9. data/lib/core_ext/class.rb +14 -0
  10. data/lib/predicates/aliased.rb +22 -0
  11. data/lib/predicates/association.rb +43 -0
  12. data/lib/predicates/base.rb +93 -0
  13. data/lib/predicates/blacklisted.rb +23 -0
  14. data/lib/predicates/domain.rb +31 -0
  15. data/lib/predicates/email.rb +42 -0
  16. data/lib/predicates/enumerated.rb +23 -0
  17. data/lib/predicates/hex_color.rb +24 -0
  18. data/lib/predicates/length.rb +71 -0
  19. data/lib/predicates/number.rb +104 -0
  20. data/lib/predicates/pattern.rb +22 -0
  21. data/lib/predicates/phone_number.rb +62 -0
  22. data/lib/predicates/required.rb +22 -0
  23. data/lib/predicates/same_as.rb +17 -0
  24. data/lib/predicates/size.rb +2 -0
  25. data/lib/predicates/time.rb +43 -0
  26. data/lib/predicates/unique.rb +71 -0
  27. data/lib/predicates/url.rb +62 -0
  28. data/lib/predicates/usa_state.rb +87 -0
  29. data/lib/predicates/usa_zip_code.rb +25 -0
  30. data/lib/predicates/whitelisted.rb +2 -0
  31. data/lib/predicates.rb +3 -0
  32. data/lib/semantic_attributes/attribute.rb +46 -0
  33. data/lib/semantic_attributes/attribute_formats.rb +67 -0
  34. data/lib/semantic_attributes/locale/en.yml +31 -0
  35. data/lib/semantic_attributes/predicates.rb +170 -0
  36. data/lib/semantic_attributes/set.rb +40 -0
  37. data/lib/semantic_attributes/version.rb +3 -0
  38. data/lib/semantic_attributes.rb +37 -0
  39. data/semantic_attributes.gemspec +29 -0
  40. data/test/db/database.yml +3 -0
  41. data/test/db/models.rb +38 -0
  42. data/test/db/schema.rb +33 -0
  43. data/test/fixtures/addresses.yml +15 -0
  44. data/test/fixtures/roles.yml +4 -0
  45. data/test/fixtures/roles_users.yml +6 -0
  46. data/test/fixtures/services.yml +6 -0
  47. data/test/fixtures/subscriptions.yml +16 -0
  48. data/test/fixtures/users.yml +20 -0
  49. data/test/test_helper.rb +67 -0
  50. data/test/unit/active_record_predicates_test.rb +88 -0
  51. data/test/unit/attribute_formats_test.rb +40 -0
  52. data/test/unit/inheritance_test.rb +23 -0
  53. data/test/unit/predicates/aliased_test.rb +17 -0
  54. data/test/unit/predicates/association_predicate_test.rb +51 -0
  55. data/test/unit/predicates/base_test.rb +53 -0
  56. data/test/unit/predicates/blacklisted_predicate_test.rb +28 -0
  57. data/test/unit/predicates/domain_predicate_test.rb +27 -0
  58. data/test/unit/predicates/email_test.rb +82 -0
  59. data/test/unit/predicates/enumerated_predicate_test.rb +22 -0
  60. data/test/unit/predicates/hex_color_predicate_test.rb +29 -0
  61. data/test/unit/predicates/length_predicate_test.rb +85 -0
  62. data/test/unit/predicates/number_test.rb +109 -0
  63. data/test/unit/predicates/pattern_predicate_test.rb +29 -0
  64. data/test/unit/predicates/phone_number_predicate_test.rb +41 -0
  65. data/test/unit/predicates/required_predicate_test.rb +13 -0
  66. data/test/unit/predicates/same_as_predicate_test.rb +19 -0
  67. data/test/unit/predicates/time_test.rb +49 -0
  68. data/test/unit/predicates/unique_test.rb +58 -0
  69. data/test/unit/predicates/url_test.rb +86 -0
  70. data/test/unit/predicates/usa_state_test.rb +31 -0
  71. data/test/unit/predicates/usa_zip_code_test.rb +42 -0
  72. data/test/unit/semantic_attribute_test.rb +18 -0
  73. data/test/unit/semantic_attributes_test.rb +29 -0
  74. data/test/unit/validations_test.rb +121 -0
  75. 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