dm-validations 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/History.txt +15 -0
  2. data/Manifest.txt +21 -2
  3. data/lib/dm-validations.rb +14 -14
  4. data/lib/dm-validations/absent_field_validator.rb +3 -4
  5. data/lib/dm-validations/acceptance_validator.rb +6 -10
  6. data/lib/dm-validations/confirmation_validator.rb +5 -5
  7. data/lib/dm-validations/contextual_validators.rb +1 -1
  8. data/lib/dm-validations/custom_validator.rb +1 -1
  9. data/lib/dm-validations/format_validator.rb +6 -5
  10. data/lib/dm-validations/generic_validator.rb +7 -10
  11. data/lib/dm-validations/length_validator.rb +7 -7
  12. data/lib/dm-validations/method_validator.rb +2 -2
  13. data/lib/dm-validations/numeric_validator.rb +4 -4
  14. data/lib/dm-validations/primitive_validator.rb +4 -4
  15. data/lib/dm-validations/required_field_validator.rb +5 -5
  16. data/lib/dm-validations/uniqueness_validator.rb +2 -2
  17. data/lib/dm-validations/validation_errors.rb +34 -2
  18. data/lib/dm-validations/version.rb +1 -1
  19. data/lib/dm-validations/within_validator.rb +15 -13
  20. data/spec/integration/absent_field_validator_spec.rb +4 -2
  21. data/spec/integration/acceptance_validator_spec.rb +3 -3
  22. data/spec/integration/auto_validate_spec.rb +16 -9
  23. data/spec/integration/block_validator_spec.rb +2 -8
  24. data/spec/integration/confirmation_validator_spec.rb +11 -8
  25. data/spec/integration/contextual_validators_spec.rb +2 -1
  26. data/spec/integration/format_validator_spec.rb +1 -1
  27. data/spec/integration/length_validator/error_message_spec.rb +23 -0
  28. data/spec/integration/length_validator/maximum_spec.rb +31 -0
  29. data/spec/integration/length_validator/minimum_spec.rb +31 -0
  30. data/spec/integration/length_validator/range_spec.rb +95 -0
  31. data/spec/integration/length_validator/spec_helper.rb +12 -0
  32. data/spec/integration/length_validator/valid_objects_spec.rb +13 -0
  33. data/spec/integration/method_validator_spec.rb +3 -3
  34. data/spec/integration/numeric_validator/float_type_spec.rb +102 -0
  35. data/spec/integration/numeric_validator/integer_only_true_spec.rb +92 -0
  36. data/spec/integration/numeric_validator/integer_type_spec.rb +100 -0
  37. data/spec/integration/numeric_validator/spec_helper.rb +77 -0
  38. data/spec/integration/numeric_validator_spec.rb +19 -6
  39. data/spec/integration/primitive_validator_spec.rb +2 -1
  40. data/spec/integration/required_field_validator/association_spec.rb +98 -0
  41. data/spec/integration/required_field_validator/boolean_type_value_spec.rb +149 -0
  42. data/spec/integration/required_field_validator/date_type_value_spec.rb +126 -0
  43. data/spec/integration/required_field_validator/datetime_type_value_spec.rb +126 -0
  44. data/spec/integration/required_field_validator/float_type_value_spec.rb +130 -0
  45. data/spec/integration/required_field_validator/integer_type_value_spec.rb +98 -0
  46. data/spec/integration/required_field_validator/plain_old_ruby_object_spec.rb +36 -0
  47. data/spec/integration/required_field_validator/shared_examples.rb +24 -0
  48. data/spec/integration/required_field_validator/spec_helper.rb +68 -0
  49. data/spec/integration/required_field_validator/string_type_value_spec.rb +164 -0
  50. data/spec/integration/required_field_validator/text_type_value_spec.rb +46 -0
  51. data/spec/integration/uniqueness_validator_spec.rb +10 -8
  52. data/spec/integration/validation_spec.rb +25 -25
  53. data/spec/integration/within_validator_spec.rb +36 -11
  54. data/tasks/spec.rb +1 -1
  55. metadata +24 -5
  56. data/spec/integration/length_validator_spec.rb +0 -115
  57. data/spec/integration/required_field_validator_spec.rb +0 -93
@@ -43,8 +43,8 @@ module DataMapper
43
43
  # is target and found resource identic? same instance... but not ==
44
44
  return true if !target.new_record? && resource.repository.name == repository_name && resource.model == target.model && resource.key == target.key
45
45
 
46
- error_message = @options[:message] || "%s is already taken".t(Extlib::Inflection.humanize(field_name))
47
- add_error(target, error_message , field_name)
46
+ error_message = @options[:message] || ValidationErrors.default_error_message(:taken, field_name)
47
+ add_error(target, error_message, field_name)
48
48
 
49
49
  return false
50
50
  end
@@ -9,6 +9,38 @@ module DataMapper
9
9
 
10
10
  include Enumerable
11
11
 
12
+ @@default_error_messages = {
13
+ :absent => '%s must be absent',
14
+ :inclusion => '%s must be one of [%s]',
15
+ :invalid => '%s has an invalid format',
16
+ :confirmation => '%s does not match the confirmation',
17
+ :accepted => "%s is not accepted",
18
+ :nil => '%s must not be nil',
19
+ :blank => '%s must not be blank',
20
+ :length_between => '%s must be between %s and %s characters long',
21
+ :too_long => '%s must be less than %s characters long',
22
+ :too_short => '%s must be more than %s characters long',
23
+ :wrong_length => '%s must be %s characters long',
24
+ :taken => '%s is already taken',
25
+ :not_a_number => '%s must be a number',
26
+ :not_an_integer => '%s must be an integer',
27
+ :greater_than => '%s must be greater than %s',
28
+ :greater_than_or_equal_to => "%s must be greater than or equal to %s",
29
+ :equal_to => "%s must be equal to %s",
30
+ :less_than => '%s must be less than %s',
31
+ :less_than_or_equal_to => "%s must be less than or equal to %s",
32
+ :value_between => '%s must be between %s and %s',
33
+ :primitive => '%s must be of type %s'
34
+ }
35
+
36
+ # Holds a hash with all the default error messages that can be replaced by your own copy or localizations.
37
+ cattr_writer :default_error_messages
38
+
39
+ def self.default_error_message(key, field, *values)
40
+ field = Extlib::Inflection.humanize(field)
41
+ @@default_error_messages[key] % [field, *values].flatten
42
+ end
43
+
12
44
  # Clear existing validation errors.
13
45
  def clear!
14
46
  errors.clear
@@ -25,7 +57,7 @@ module DataMapper
25
57
 
26
58
  # Collect all errors into a single list.
27
59
  def full_messages
28
- errors.inject([]) do |list,pair|
60
+ errors.inject([]) do |list, pair|
29
61
  list += pair.last
30
62
  end
31
63
  end
@@ -39,7 +71,7 @@ module DataMapper
39
71
  end
40
72
 
41
73
  def each
42
- errors.map.each do |k,v|
74
+ errors.map.each do |k, v|
43
75
  next if v.blank?
44
76
  yield(v)
45
77
  end
@@ -1,5 +1,5 @@
1
1
  module DataMapper
2
2
  module Validations
3
- VERSION = '0.9.9'
3
+ VERSION = '0.9.10'
4
4
  end
5
5
  end
@@ -14,23 +14,25 @@ module DataMapper
14
14
  end
15
15
 
16
16
  def call(target)
17
- includes = @options[:set].include?(target.send(field_name))
18
- return true if includes
19
-
20
- field_name = Extlib::Inflection.humanize(@field_name)
21
- if @options[:set].is_a?(Range)
22
- if @options[:set].first != -n && @options[:set].last != n
23
- error_message = @options[:message] || "%s must be between %s and %s".t(field_name, @options[:set].first, @options[:set].last)
24
- elsif @options[:set].first == -n
25
- error_message = @options[:message] || "%s must be less than %s".t(field_name, @options[:set].last)
26
- elsif @options[:set].last == n
27
- error_message = @options[:message] || "%s must be greater than %s".t(field_name, @options[:set].first)
17
+ value = target.send(field_name)
18
+ return true if @options[:allow_nil] && value.nil?
19
+ return true if @options[:set].include?(value)
20
+
21
+ set = @options[:set]
22
+ msg = @options[:message]
23
+ if set.is_a?(Range)
24
+ if set.first != -n && set.last != n
25
+ error_message = msg || ValidationErrors.default_error_message(:value_between, field_name, set.first, set.last)
26
+ elsif set.first == -n
27
+ error_message = msg || ValidationErrors.default_error_message(:less_than_or_equal_to, field_name, set.last)
28
+ elsif set.last == n
29
+ error_message = msg || ValidationErrors.default_error_message(:greater_than_or_equal_to, field_name, set.first)
28
30
  end
29
31
  else
30
- error_message = "%s must be one of [%s]".t(field_name, @options[:set].join(', '))
32
+ error_message = ValidationErrors.default_error_message(:inclusion, field_name, set.join(', '))
31
33
  end
32
34
 
33
- add_error(target, error_message , @field_name)
35
+ add_error(target, error_message, field_name)
34
36
  return false
35
37
  end
36
38
 
@@ -3,14 +3,14 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
3
 
4
4
  describe DataMapper::Validate::AbsentFieldValidator do
5
5
  before(:all) do
6
- class Kayak
6
+ class ::Kayak
7
7
  include DataMapper::Resource
8
8
  property :id, Integer, :key => true
9
9
  property :salesman, String, :auto_validation => false
10
10
  validates_absent :salesman, :when => :sold
11
11
  end
12
12
 
13
- class Pirogue
13
+ class ::Pirogue
14
14
  include DataMapper::Resource
15
15
  property :id, Integer, :key => true
16
16
  property :salesman, String, :default => 'Layfayette'
@@ -24,11 +24,13 @@ describe DataMapper::Validate::AbsentFieldValidator do
24
24
 
25
25
  kayak.salesman = 'Joe'
26
26
  kayak.valid_for_sold?.should_not == true
27
+ kayak.errors.on(:salesman).should include('Salesman must be absent')
27
28
  end
28
29
 
29
30
  it "should validate the absence of a value and ensure defaults" do
30
31
  pirogue = Pirogue.new
31
32
  pirogue.should_not be_valid_for_sold
33
+ pirogue.errors.on(:salesman).should include('Salesman must be absent')
32
34
  end
33
35
 
34
36
  end
@@ -4,7 +4,7 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
4
4
  describe DataMapper::Validate::AcceptanceValidator do
5
5
  describe "with standard options" do
6
6
  before(:all) do
7
- class SkimBat
7
+ class ::SkimBat
8
8
  include DataMapper::Resource
9
9
  property :id, Integer, :serial => true
10
10
  property :sailyness, Boolean
@@ -31,7 +31,7 @@ describe DataMapper::Validate::AcceptanceValidator do
31
31
  it "should add the default message when invalid" do
32
32
  @s.sailyness = "0"
33
33
  @s.valid?.should == false
34
- @s.errors.full_messages.join(" ").should =~ /#{DataMapper::Validate::AcceptanceValidator.default_message_for_field("sailyness")}/
34
+ @s.errors.on(:sailyness).should include('Sailyness is not accepted')
35
35
  end
36
36
  end
37
37
  describe "with :allow_nil => false" do
@@ -81,7 +81,7 @@ describe DataMapper::Validate::AcceptanceValidator do
81
81
  it "should append the custom message when invalid" do
82
82
  @s.sailyness = "0"
83
83
  @s.valid?.should == false
84
- @s.errors.full_messages.join(" ").should =~ /hehu!/
84
+ @s.errors.on(:sailyness).should include('hehu!')
85
85
  end
86
86
  end
87
87
  end
@@ -4,7 +4,7 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
4
4
  module TypecastBypassSetter
5
5
  # Bypass typecasting so we can set values for specs
6
6
  def set(attributes)
7
- attributes.each do |k,v|
7
+ attributes.each do |k, v|
8
8
  instance_variable_set("@#{k}", v)
9
9
  end
10
10
  end
@@ -65,6 +65,7 @@ describe "Automatic Validation from Property Definition" do
65
65
 
66
66
  boat = SailBoat.new
67
67
  boat.valid_for_presence_test?.should == false
68
+ boat.errors.on(:name).should include('Name must not be blank')
68
69
  boat.name = 'Float'
69
70
  boat.valid_for_presence_test?.should == true
70
71
  end
@@ -75,6 +76,7 @@ describe "Automatic Validation from Property Definition" do
75
76
  boat.valid_for_length_test_1?.should == true #no minimum length
76
77
  boat.description = 'ABCDEFGHIJK' #11
77
78
  boat.valid_for_length_test_1?.should == false
79
+ boat.errors.on(:description).should include('Description must be less than 10 characters long')
78
80
  boat.description = 'ABCDEFGHIJ' #10
79
81
  boat.valid_for_length_test_1?.should == true
80
82
  end
@@ -88,6 +90,7 @@ describe "Automatic Validation from Property Definition" do
88
90
  boat.should be_valid_for_length_test_2
89
91
  boat.notes = 'ABCDEFGHIJK' #11
90
92
  boat.should_not be_valid_for_length_test_2
93
+ boat.errors.on(:notes).should include('Notes must be between 2 and 10 characters long')
91
94
  boat.notes = 'ABCDEFGHIJ' #10
92
95
  boat.should be_valid_for_length_test_2
93
96
  end
@@ -100,6 +103,7 @@ describe "Automatic Validation from Property Definition" do
100
103
  boat.should be_valid_for_format_test
101
104
  boat.code = 'BAD CODE'
102
105
  boat.should_not be_valid_for_format_test
106
+ boat.errors.on(:code).should include('Code has an invalid format')
103
107
  end
104
108
 
105
109
  it "should auto validate all strings for max length" do
@@ -110,9 +114,9 @@ describe "Automatic Validation from Property Definition" do
110
114
  end
111
115
  t = klass.new(:id => 1)
112
116
  t.should be_valid
113
- t.name = 'Lip­smackin­thirst­quenchin­acetastin­motivatin­good­buzzin­cool­talkin­high­walkin­fast­livin­ever­givin­cool­fizzin'
117
+ t.name = 'a' * 51
114
118
  t.should_not be_valid
115
- t.errors.full_messages.should include('Name must be less than 50 characters long')
119
+ t.errors.on(:name).should include('Name must be less than 50 characters long')
116
120
  end
117
121
 
118
122
  it "should auto validate the primitive type" do
@@ -122,6 +126,7 @@ describe "Automatic Validation from Property Definition" do
122
126
  boat.should be_valid_for_primitive_test
123
127
  boat.build_date = 'ABC'
124
128
  boat.should_not be_valid_for_primitive_test
129
+ boat.errors.on(:build_date).should include('Build date must be of type Date')
125
130
  end
126
131
 
127
132
  it "should not auto add any validators if the option :auto_validation => false was given" do
@@ -164,13 +169,13 @@ describe "Automatic Validation from Property Definition" do
164
169
  it 'should not allow floats' do
165
170
  @boat.set(:id => 1.0)
166
171
  @boat.should_not be_valid
167
- @boat.errors.on(:id).should == [ 'Id must be an integer' ]
172
+ @boat.errors.on(:id).should include('Id must be an integer')
168
173
  end
169
174
 
170
175
  it 'should not allow decimals' do
171
176
  @boat.set(:id => BigDecimal('1'))
172
177
  @boat.should_not be_valid
173
- @boat.errors.on(:id).should == [ 'Id must be an integer' ]
178
+ @boat.errors.on(:id).should include('Id must be an integer')
174
179
  end
175
180
  end
176
181
 
@@ -213,6 +218,7 @@ describe "Automatic Validation from Property Definition" do
213
218
  it 'should not allow nil' do
214
219
  @boat.set(:bool => nil)
215
220
  @boat.should_not be_valid
221
+ @boat.errors.on(:bool).should include('Bool must not be nil')
216
222
  end
217
223
  end
218
224
 
@@ -234,10 +240,11 @@ describe "Automatic Validation from Property Definition" do
234
240
  it 'should not allow nil' do
235
241
  @boat.set(:bool => nil)
236
242
  @boat.should_not be_valid
243
+ @boat.errors.on(:bool).should include('Bool must not be nil')
237
244
  end
238
245
  end
239
246
 
240
- { :float => Float, :big_decimal => BigDecimal }.each do |column,type|
247
+ { :float => Float, :big_decimal => BigDecimal }.each do |column, type|
241
248
  describe "for #{type} properties" do
242
249
  before do
243
250
  @boat = SailBoat.new(:id => 1)
@@ -262,7 +269,7 @@ describe "Automatic Validation from Property Definition" do
262
269
 
263
270
  describe 'for within validator' do
264
271
  before :all do
265
- class LimitedBoat
272
+ class ::LimitedBoat
266
273
  include DataMapper::Resource
267
274
  property :id, Integer, :serial => true
268
275
  property :limited, String, :set => ['foo', 'bar', 'bang'], :default => 'foo'
@@ -280,6 +287,7 @@ describe "Automatic Validation from Property Definition" do
280
287
  it 'should not accept value not in range' do
281
288
  @boat.limited = "blah"
282
289
  @boat.should_not be_valid
290
+ @boat.errors.on(:limited).should include('Limited must be one of [foo, bar, bang]')
283
291
  end
284
292
 
285
293
  end
@@ -293,8 +301,7 @@ describe "Automatic Validation from Property Definition" do
293
301
  end
294
302
  boat = custom_boat.new
295
303
  boat.should_not be_valid
296
-
297
- boat.errors.on(:name).should eql(["This boat must have name"])
304
+ boat.errors.on(:name).should include('This boat must have name')
298
305
  end
299
306
 
300
307
  it "should have correct error messages" do
@@ -3,7 +3,7 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
3
 
4
4
  describe DataMapper::Validate::ValidatesWithBlock do
5
5
  before(:all) do
6
- class Ship
6
+ class ::Ship
7
7
  include DataMapper::Resource
8
8
  property :id, Integer, :key => true
9
9
  property :name, String
@@ -20,13 +20,7 @@ describe DataMapper::Validate::ValidatesWithBlock do
20
20
  end
21
21
  end
22
22
 
23
- it "should validate via a block on the resource" do
24
- Ship.new.valid_for_testing_failure?.should == false
25
- Ship.new.valid_for_testing_success?.should == true
26
- ship = Ship.new
27
- ship.valid_for_testing_failure?.should == false
28
- ship.errors.full_messages.include?('Validation failed').should == true
29
- end
23
+ it "should validate via a block on the resource"
30
24
 
31
25
  it "should validate via a block and add error to field" do
32
26
  ship = Ship.new
@@ -3,7 +3,7 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
3
 
4
4
  describe DataMapper::Validate::ConfirmationValidator do
5
5
  before(:all) do
6
- class Canoe
6
+ class ::Canoe
7
7
  include DataMapper::Resource
8
8
 
9
9
  property :id, Integer, :serial => true
@@ -16,7 +16,7 @@ describe DataMapper::Validate::ConfirmationValidator do
16
16
  end
17
17
 
18
18
  it "should only validate if the attribute is dirty" do
19
- class Transformer
19
+ class ::Transformer
20
20
  include DataMapper::Resource
21
21
 
22
22
  property :id, Integer, :serial => true
@@ -41,6 +41,7 @@ describe DataMapper::Validate::ConfirmationValidator do
41
41
  canoe.name = 'White Water'
42
42
  canoe.name_confirmation = 'Not confirmed'
43
43
  canoe.should_not be_valid
44
+ canoe.errors.on(:name).should include('Name does not match the confirmation')
44
45
  canoe.errors.full_messages.first.should == 'Name does not match the confirmation'
45
46
 
46
47
  canoe.name_confirmation = 'White Water'
@@ -60,15 +61,17 @@ describe DataMapper::Validate::ConfirmationValidator do
60
61
  end
61
62
 
62
63
  it "should not pass validation with a nil value when specified to" do
63
- class Canoe
64
+ class ::Canoe
64
65
  validators.clear!
65
66
  validates_is_confirmed :name, :allow_nil => false
66
67
  end
67
- Canoe.new.should_not be_valid
68
+ canoe = Canoe.new
69
+ canoe.should_not be_valid
70
+ canoe.errors.on(:name).should include('Name does not match the confirmation')
68
71
  end
69
72
 
70
73
  it "should allow the name of the confirmation field to be set" do
71
- class Canoe
74
+ class ::Canoe
72
75
  validators.clear!
73
76
  validates_is_confirmed :name, :confirm => :name_check
74
77
  def name_check=(value)
@@ -86,7 +89,7 @@ describe DataMapper::Validate::ConfirmationValidator do
86
89
  end
87
90
 
88
91
  it "should not require that the confirmation field be a property" do
89
- class Raft
92
+ class ::Raft
90
93
  include DataMapper::Resource
91
94
  attr_accessor :name, :name_confirmation
92
95
 
@@ -95,8 +98,8 @@ describe DataMapper::Validate::ConfirmationValidator do
95
98
  validates_is_confirmed :name
96
99
  end
97
100
 
98
- raft = Raft.new
101
+ raft = Raft.new(:id => 10)
99
102
  raft.name = 'Lifeboat'
100
- lambda { raft.should_not be_valid }.should_not raise_error
103
+ raft.should_not be_valid
101
104
  end
102
105
  end
@@ -4,7 +4,7 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
4
4
  describe DataMapper::Validate::ContextualValidators do
5
5
 
6
6
  before :all do
7
- class Kayak
7
+ class ::Kayak
8
8
  include DataMapper::Resource
9
9
  property :id, Integer, :key => true
10
10
  property :salesman, String, :auto_validation => false
@@ -17,6 +17,7 @@ describe DataMapper::Validate::ContextualValidators do
17
17
  k.valid?(:sold).should == true
18
18
  k.salesman = 'John Doe'
19
19
  k.valid?(:sold).should_not == true
20
+ k.errors.on(:salesman).should include('Salesman must be absent')
20
21
  end
21
22
 
22
23
  it "should raise an exception if you provide an invalid context to save" do
@@ -3,7 +3,7 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
3
 
4
4
  describe DataMapper::Validate::FormatValidator do
5
5
  before :all do
6
- class BillOfLading
6
+ class ::BillOfLading
7
7
  include DataMapper::Resource
8
8
 
9
9
  property :id, Serial
@@ -0,0 +1,23 @@
1
+ require 'pathname'
2
+ __dir__ = Pathname(__FILE__).dirname.expand_path
3
+
4
+ # global first, then local to length validators
5
+ require __dir__.parent.parent + "spec_helper"
6
+ require __dir__ + 'spec_helper'
7
+
8
+ describe DataMapper::Validate::LengthValidator do
9
+ it "lets user specify custom error message" do
10
+ class Jabberwock
11
+ include DataMapper::Resource
12
+ property :id, Integer, :key => true
13
+ property :snickersnack, String
14
+ validates_length :snickersnack, :within => 3..40, :message => "worble warble"
15
+ end
16
+ wock = Jabberwock.new
17
+ wock.should_not be_valid
18
+ wock.errors.on(:snickersnack).should include('worble warble')
19
+ wock.snickersnack = "hello"
20
+ wock.id = 1
21
+ wock.should be_valid
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ require 'pathname'
2
+ __dir__ = Pathname(__FILE__).dirname.expand_path
3
+
4
+ # global first, then local to length validators
5
+ require __dir__.parent.parent + "spec_helper"
6
+ require __dir__ + 'spec_helper'
7
+
8
+ describe DataMapper::Validate::LengthValidator do
9
+ it "lets user specify a maximum length of a string field" do
10
+ class ::MotorLaunch
11
+ validators.clear!
12
+ validates_length :name, :max => 5
13
+ end
14
+
15
+ launch = MotorLaunch.new
16
+ launch.name = 'a' * 6
17
+ launch.should_not be_valid
18
+ launch.errors.on(:name).should include('Name must be less than 5 characters long')
19
+ end
20
+
21
+ it "aliases :maximum for :max" do
22
+ class ::MotorLaunch
23
+ validators.clear!
24
+ validates_length :name, :maximum => 5
25
+ end
26
+ launch = MotorLaunch.new
27
+ launch.name = 'a' * 6
28
+ launch.should_not be_valid
29
+ launch.errors.on(:name).should include('Name must be less than 5 characters long')
30
+ end
31
+ end