datamapper 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/example.rb +5 -5
  2. data/lib/data_mapper/adapters/abstract_adapter.rb +2 -2
  3. data/lib/data_mapper/adapters/data_object_adapter.rb +141 -147
  4. data/lib/data_mapper/adapters/mysql_adapter.rb +14 -1
  5. data/lib/data_mapper/adapters/postgresql_adapter.rb +123 -18
  6. data/lib/data_mapper/adapters/sql/coersion.rb +21 -9
  7. data/lib/data_mapper/adapters/sql/commands/load_command.rb +36 -19
  8. data/lib/data_mapper/adapters/sql/mappings/column.rb +111 -17
  9. data/lib/data_mapper/adapters/sql/mappings/schema.rb +27 -0
  10. data/lib/data_mapper/adapters/sql/mappings/table.rb +256 -29
  11. data/lib/data_mapper/adapters/sqlite3_adapter.rb +93 -8
  12. data/lib/data_mapper/associations/belongs_to_association.rb +53 -54
  13. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +157 -25
  14. data/lib/data_mapper/associations/has_many_association.rb +45 -15
  15. data/lib/data_mapper/associations/has_n_association.rb +79 -20
  16. data/lib/data_mapper/associations/has_one_association.rb +2 -2
  17. data/lib/data_mapper/associations/reference.rb +1 -1
  18. data/lib/data_mapper/auto_migrations.rb +40 -0
  19. data/lib/data_mapper/base.rb +201 -98
  20. data/lib/data_mapper/context.rb +16 -10
  21. data/lib/data_mapper/database.rb +22 -11
  22. data/lib/data_mapper/dependency_queue.rb +28 -0
  23. data/lib/data_mapper/embedded_value.rb +61 -17
  24. data/lib/data_mapper/property.rb +4 -0
  25. data/lib/data_mapper/support/active_record_impersonation.rb +13 -5
  26. data/lib/data_mapper/support/errors.rb +5 -0
  27. data/lib/data_mapper/support/serialization.rb +8 -4
  28. data/lib/data_mapper/validatable_extensions/errors.rb +12 -0
  29. data/lib/data_mapper/validatable_extensions/macros.rb +7 -0
  30. data/lib/data_mapper/validatable_extensions/validatable_instance_methods.rb +62 -0
  31. data/lib/data_mapper/validatable_extensions/validation_base.rb +18 -0
  32. data/lib/data_mapper/validatable_extensions/validations/formats/email.rb +43 -0
  33. data/lib/data_mapper/validatable_extensions/validations/validates_acceptance_of.rb +7 -0
  34. data/lib/data_mapper/validatable_extensions/validations/validates_confirmation_of.rb +7 -0
  35. data/lib/data_mapper/validatable_extensions/validations/validates_each.rb +7 -0
  36. data/lib/data_mapper/validatable_extensions/validations/validates_format_of.rb +28 -0
  37. data/lib/data_mapper/validatable_extensions/validations/validates_length_of.rb +15 -0
  38. data/lib/data_mapper/validatable_extensions/validations/validates_numericality_of.rb +7 -0
  39. data/lib/data_mapper/validatable_extensions/validations/validates_presence_of.rb +7 -0
  40. data/lib/data_mapper/validatable_extensions/validations/validates_true_for.rb +7 -0
  41. data/lib/data_mapper/validatable_extensions/validations/validates_uniqueness_of.rb +33 -0
  42. data/lib/data_mapper/validations.rb +20 -0
  43. data/lib/data_mapper.rb +39 -34
  44. data/performance.rb +24 -18
  45. data/plugins/dataobjects/do_rb +0 -0
  46. data/rakefile.rb +12 -2
  47. data/spec/active_record_impersonation_spec.rb +133 -0
  48. data/spec/acts_as_tree_spec.rb +25 -9
  49. data/spec/associations_spec.rb +124 -4
  50. data/spec/attributes_spec.rb +13 -0
  51. data/spec/auto_migrations_spec.rb +44 -0
  52. data/spec/base_spec.rb +189 -1
  53. data/spec/column_spec.rb +85 -7
  54. data/spec/conditions_spec.rb +2 -2
  55. data/spec/dependency_spec.rb +25 -0
  56. data/spec/embedded_value_spec.rb +123 -3
  57. data/spec/fixtures/animals.yaml +1 -0
  58. data/spec/fixtures/careers.yaml +5 -0
  59. data/spec/fixtures/comments.yaml +1 -0
  60. data/spec/fixtures/people.yaml +14 -9
  61. data/spec/fixtures/projects.yaml +4 -0
  62. data/spec/fixtures/sections.yaml +5 -0
  63. data/spec/fixtures/serializers.yaml +6 -0
  64. data/spec/fixtures/users.yaml +1 -0
  65. data/spec/load_command_spec.rb +5 -4
  66. data/spec/mock_adapter.rb +2 -2
  67. data/spec/models/animal.rb +2 -1
  68. data/spec/models/animals_exhibit.rb +2 -2
  69. data/spec/models/career.rb +6 -0
  70. data/spec/models/comment.rb +4 -0
  71. data/spec/models/exhibit.rb +4 -0
  72. data/spec/models/person.rb +3 -13
  73. data/spec/models/project.rb +1 -1
  74. data/spec/models/serializer.rb +3 -0
  75. data/spec/models/user.rb +4 -0
  76. data/spec/models/zoo.rb +8 -1
  77. data/spec/natural_key_spec.rb +36 -0
  78. data/spec/paranoia_spec.rb +36 -0
  79. data/spec/property_spec.rb +70 -0
  80. data/spec/schema_spec.rb +10 -2
  81. data/spec/serialization_spec.rb +6 -3
  82. data/spec/serialize_spec.rb +19 -0
  83. data/spec/single_table_inheritance_spec.rb +7 -1
  84. data/spec/spec_helper.rb +26 -8
  85. data/spec/table_spec.rb +33 -0
  86. data/spec/validates_confirmation_of_spec.rb +20 -4
  87. data/spec/validates_format_of_spec.rb +22 -8
  88. data/spec/validates_length_of_spec.rb +26 -13
  89. data/spec/validates_uniqueness_of_spec.rb +18 -5
  90. data/spec/validations_spec.rb +55 -10
  91. data/tasks/fixtures.rb +13 -7
  92. metadata +189 -153
  93. data/lib/data_mapper/validations/confirmation_validator.rb +0 -53
  94. data/lib/data_mapper/validations/contextual_validations.rb +0 -50
  95. data/lib/data_mapper/validations/format_validator.rb +0 -85
  96. data/lib/data_mapper/validations/formats/email.rb +0 -78
  97. data/lib/data_mapper/validations/generic_validator.rb +0 -22
  98. data/lib/data_mapper/validations/length_validator.rb +0 -76
  99. data/lib/data_mapper/validations/required_field_validator.rb +0 -41
  100. data/lib/data_mapper/validations/unique_validator.rb +0 -56
  101. data/lib/data_mapper/validations/validation_errors.rb +0 -37
  102. data/lib/data_mapper/validations/validation_helper.rb +0 -77
  103. data/plugins/dataobjects/REVISION +0 -1
  104. data/plugins/dataobjects/Rakefile +0 -9
  105. data/plugins/dataobjects/do.rb +0 -348
  106. data/plugins/dataobjects/do_mysql.rb +0 -212
  107. data/plugins/dataobjects/do_postgres.rb +0 -196
  108. data/plugins/dataobjects/do_sqlite3.rb +0 -157
  109. data/plugins/dataobjects/spec/do_spec.rb +0 -150
  110. data/plugins/dataobjects/spec/spec_helper.rb +0 -81
  111. data/plugins/dataobjects/swig_mysql/extconf.rb +0 -45
  112. data/plugins/dataobjects/swig_mysql/mysql_c.c +0 -16602
  113. data/plugins/dataobjects/swig_mysql/mysql_c.i +0 -67
  114. data/plugins/dataobjects/swig_mysql/mysql_supp.i +0 -46
  115. data/plugins/dataobjects/swig_postgres/extconf.rb +0 -29
  116. data/plugins/dataobjects/swig_postgres/postgres_c.c +0 -8185
  117. data/plugins/dataobjects/swig_postgres/postgres_c.i +0 -73
  118. data/plugins/dataobjects/swig_sqlite/extconf.rb +0 -9
  119. data/plugins/dataobjects/swig_sqlite/sqlite3_c.c +0 -4725
  120. data/plugins/dataobjects/swig_sqlite/sqlite_c.i +0 -168
  121. data/tasks/drivers.rb +0 -20
@@ -6,7 +6,7 @@ class Person < DataMapper::Base
6
6
  property :notes, :text
7
7
  property :date_of_birth, :date
8
8
 
9
- embed :address do
9
+ embed :address, :prefix => true do
10
10
  property :street, :string
11
11
  property :city, :string
12
12
  property :state, :string, :size => 2
@@ -18,15 +18,5 @@ class Person < DataMapper::Base
18
18
 
19
19
  end
20
20
 
21
- class Location < DataMapper::EmbeddedValue
22
- property :city, :string
23
- property :state, :string, :size => 2
24
-
25
- def to_s
26
- "#{city}, #{state}"
27
- end
28
- end
29
-
30
- embed Location
31
-
32
- end
21
+ belongs_to :career
22
+ end
@@ -14,6 +14,6 @@ class Project < DataMapper::Base
14
14
  private
15
15
 
16
16
  def create_main_section
17
- sections << Section.new(:title => "Main") if sections.empty?
17
+ sections << Section.find_or_create(:title => "Main") if sections.empty?
18
18
  end
19
19
  end
@@ -0,0 +1,3 @@
1
+ class Serializer < DataMapper::Base
2
+ property :content, :object, :lazy => false
3
+ end
@@ -0,0 +1,4 @@
1
+ class User < DataMapper::Base
2
+ property :name, :string
3
+ has_many :comments, :class => 'Comment', :foreign_key => 'user_id'
4
+ end
data/spec/models/zoo.rb CHANGED
@@ -4,6 +4,13 @@ class Zoo < DataMapper::Base
4
4
  property :updated_at, :datetime
5
5
 
6
6
  has_many :exhibits
7
-
7
+ begin
8
8
  validates_presence_of :name
9
+ rescue ArgumentError => e
10
+ throw e unless e.message =~ /specify a unique key/
11
+ end
12
+
13
+ def name=(val)
14
+ @name = (val == "Colorado Springs") ? "Cheyenne Mountain" : val
15
+ end
9
16
  end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe('A Natural Key') do
4
+
5
+ it "should cause the Table to return a default foreign key composed of it's table and key column name" do
6
+ database.table(Person).default_foreign_key.should eql('person_id')
7
+ database.table(Career).default_foreign_key.should eql('career_name')
8
+ end
9
+
10
+ it "should load the object based on it's natural key" do
11
+ programmer = Career['Programmer']
12
+ programmer.should_not be_nil
13
+ programmer.name.should eql('Programmer')
14
+ programmer.attributes.should include(:name)
15
+ end
16
+
17
+ it "should load an association based on the natural key" do
18
+ database do
19
+ programmer = Career['Programmer']
20
+ programmer.followers.should have(2).entries
21
+
22
+ sam = Person.first(:name => 'Sam')
23
+ scott = Person.first(:name => 'Scott')
24
+
25
+ programmer.followers.should include(sam)
26
+ programmer.followers.should include(scott)
27
+
28
+ peon = Career['Peon']
29
+ peon.followers.should have(1).entries
30
+
31
+ bob = Person.first(:name => 'Bob')
32
+ peon.followers.should include(bob)
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe 'Paranoia' do
4
+
5
+ before(:all) do
6
+ class Scared < DataMapper::Base
7
+ property :name, :string
8
+ property :deleted_at, :datetime
9
+ end
10
+
11
+ Scared.auto_migrate!
12
+ end
13
+
14
+ after(:all) do
15
+ database.table(Scared).drop!
16
+ end
17
+
18
+ it "should not be found" do
19
+ cat = Scared.create(:name => 'bob')
20
+
21
+ database.query('SELECT name FROM scareds').should have(1).entries
22
+
23
+ cat2 = Scared.first(:name => 'bob')
24
+ cat2.should_not be_nil
25
+ cat2.should be_a_kind_of(Scared)
26
+
27
+ cat.destroy!
28
+
29
+ Scared.first(:name => 'bob').should be_nil
30
+
31
+ Scared.first.should be_nil
32
+
33
+ database.query('SELECT name FROM scareds').should have(1).entries
34
+ end
35
+
36
+ end
@@ -0,0 +1,70 @@
1
+ describe DataMapper::Property do
2
+
3
+ before(:all) do
4
+ @property = Zoo.properties.find { |property| property.name == :notes }
5
+ end
6
+
7
+ it "should map a column" do
8
+ pending('until Property is implemented')
9
+ @property.column.should eql(database.table(Zoo)[:notes])
10
+ end
11
+
12
+ it "should determine lazyness" do
13
+ pending('until Property is implemented')
14
+ @property.should be_lazy
15
+ end
16
+
17
+ it "should determine protection level"
18
+
19
+ it "should return instance variable name"
20
+
21
+ it "should add a validates_presence_of for not-null properties"
22
+
23
+ it "should add a validates_format_of if you pass a format option"
24
+ end
25
+
26
+ describe DataMapper::Adapters::Sql::Mappings do
27
+
28
+ it "should return the same Table instance for two objects mapped to the same database table" do
29
+ # Refers to the same Table instance
30
+ database.table(Person) == database.table(SalesPerson)
31
+ end
32
+
33
+ it "should have one super-set of total mapped columns" do
34
+ # Refers to the mapped columns
35
+ database.table(Person).columns == database.table(SalesPerson).columns
36
+ end
37
+
38
+ it "should have one set of columns that represents the actual database" do
39
+ # Refers to the actual columns in the database, which may/are-likely-to-be different
40
+ # than the mapped columns, sometimes just because your models are dealing with
41
+ # a legacy database where not every column is mapped to the new model, so this
42
+ # is expected.
43
+ database.table(Person).send(:database_columns) == database.table(SalesPerson).send(:database_columns)
44
+ end
45
+
46
+ it "should have two different sets of mapped properties that point to subsets of the Table columns" do
47
+ pending('until Property is implemented')
48
+
49
+ table = database.table(Person)
50
+
51
+ # Every property's column should be represented in the Table's column mappings.
52
+ Person.properties.each do |property|
53
+ table.columns.should include(property.column)
54
+ end
55
+
56
+ # For both models in the STI setup...
57
+ SalesPerson.properties.each do |property|
58
+ table.columns.should include(property.column)
59
+ end
60
+
61
+ # Even though Person's properties are fewer than a SalesPerson's
62
+ Person.properties.size.should_not eql(SalesPerson.properties.size)
63
+
64
+ # And Person's properties should be a subset of a SalesPerson's
65
+ Person.properties.each do |property|
66
+ SalesPerson.properties.map(&:column).should include(property.column)
67
+ end
68
+ end
69
+
70
+ end
data/spec/schema_spec.rb CHANGED
@@ -1,5 +1,13 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
2
 
3
+ describe DataMapper::Adapters::Sql::Mappings::Schema do
4
+ it "should return all tables from the database schema" do
5
+ database.adapter.schema.database_tables.size.should == Dir[File.dirname(__FILE__) + '/fixtures/*'].size
6
+ database.adapter.schema.database_tables.each { |table| table.should be_a_kind_of( DataMapper::Adapters::Sql::Mappings::Table ) }
7
+ end
8
+ end
9
+
10
+
3
11
  if ENV['ADAPTER'] == 'postgresql' && false
4
12
 
5
13
  describe DataMapper::Adapters::PostgresqlAdapter::Mappings::Table do
@@ -54,8 +62,8 @@ if ENV['ADAPTER'] == 'postgresql' && false
54
62
  end
55
63
 
56
64
  def table_mapping_for(klass)
57
- session = database
58
- DataMapper::Adapters::PostgresqlAdapter::Commands::SaveCommand.new(session.adapter, session, klass)
65
+ database_context = database
66
+ DataMapper::Adapters::PostgresqlAdapter::Commands::SaveCommand.new(database_context.adapter, database_context, klass)
59
67
  end
60
68
 
61
69
  it "should create a schema if it doesn't already exist" do
@@ -4,15 +4,16 @@ describe DataMapper::Support::Serialization do
4
4
 
5
5
  before(:all) do
6
6
  fixtures(:animals)
7
+ fixtures(:zoos)
7
8
  end
8
9
 
9
10
  it "should serialize to YAML" do
10
- Animal.first(:name => 'Frog').to_yaml.should == <<-EOS.margin
11
+ Animal.first(:name => 'Frog').to_yaml.strip.should == <<-EOS.margin
11
12
  ---
12
13
  id: 1
13
14
  name: Frog
14
15
  notes: I am a Frog!
15
-
16
+ nice: false
16
17
  EOS
17
18
  end
18
19
 
@@ -21,6 +22,7 @@ describe DataMapper::Support::Serialization do
21
22
  <animal id="1">
22
23
  <name>Frog</name>
23
24
  <notes>I am a Frog!</notes>
25
+ <nice>false</nice>
24
26
  </animal>
25
27
  EOS
26
28
 
@@ -40,7 +42,8 @@ describe DataMapper::Support::Serialization do
40
42
  {
41
43
  "id": 1,
42
44
  "name": "Frog",
43
- "notes": "I am a Frog!"
45
+ "notes": "I am a Frog!",
46
+ "nice": false
44
47
  }
45
48
  EOS
46
49
 
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe('An AR serialize implementation') do
4
+
5
+ it 'should instatiate, save, (clear and load) the original objects' do
6
+ test_data = { :first => 1, :second => "dos", :third => 3.0 }
7
+
8
+ srlzr1 = Serializer.new(:content => test_data)
9
+ srlzr1.content.should == test_data
10
+
11
+ srlzr1.save
12
+ srlzr1.content.should == test_data
13
+
14
+ srlzr1 = nil
15
+ srlzr2 = Serializer.first
16
+ srlzr2.content.should == test_data
17
+ end
18
+
19
+ end
@@ -14,8 +14,14 @@ describe 'Single Table Inheritance' do
14
14
  clone = Person.first(:name => 'Ted')
15
15
  ted.should == clone
16
16
 
17
- ted.should be_a_kind_of(SalesPerson)
17
+ clone.class.should eql(SalesPerson)
18
18
  end
19
+
20
+ # Since we're not executing within the same database context
21
+ # this is not the same object instance as the previous ones.
22
+ clone2 = Person.first(:name => 'Ted')
23
+
24
+ clone2.class.should eql(SalesPerson)
19
25
  end
20
26
 
21
27
  it "secondary database should inherit the same attributes" do
data/spec/spec_helper.rb CHANGED
@@ -1,19 +1,37 @@
1
+ require 'pp'
2
+
1
3
  ENV['LOG_NAME'] = 'spec'
2
4
  require File.dirname(__FILE__) + '/../environment'
3
5
 
4
6
  # Define a fixtures helper method to load up our test data.
5
7
  def fixtures(name)
6
8
  entry = YAML::load_file(File.dirname(__FILE__) + "/fixtures/#{name}.yaml")
7
- klass = Kernel::const_get(Inflector.classify(Inflector.singularize(name)))
9
+ klass = begin
10
+ Kernel::const_get(Inflector.classify(Inflector.singularize(name)))
11
+ rescue
12
+ nil
13
+ end
8
14
 
9
- database.logger.debug { "AUTOMIGRATE: #{klass}" }
10
- klass.auto_migrate!
15
+ unless klass.nil?
16
+ database.logger.debug { "AUTOMIGRATE: #{klass}" }
17
+ klass.auto_migrate!
11
18
 
12
- (entry.kind_of?(Array) ? entry : [entry]).each do |hash|
13
- if hash['type']
14
- Object::const_get(hash['type'])::create(hash)
15
- else
16
- klass::create(hash)
19
+ (entry.kind_of?(Array) ? entry : [entry]).each do |hash|
20
+ if hash['type']
21
+ Object::const_get(hash['type'])::create(hash)
22
+ else
23
+ klass::create(hash)
24
+ end
25
+ end
26
+ else
27
+ # TODO: Get rid of the stupid AnimalsExhibit model...
28
+ table = database.table(name.to_s)
29
+ table.create! true
30
+
31
+ pp database.schema
32
+
33
+ (entry.kind_of?(Array) ? entry : [entry]).each do |hash|
34
+ table.insert(hash)
17
35
  end
18
36
  end
19
37
  end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe DataMapper::Adapters::Sql::Mappings::Table do
4
+ it "should return all columns from the database" do
5
+ table = database.adapter.schema.database_tables.detect{|table| table.name == "zoos"}
6
+ columns = table.database_columns
7
+ columns.size.should == database.schema[Zoo].columns.size
8
+ columns.each { |column| column.should be_a_kind_of( DataMapper::Adapters::Sql::Mappings::Column ) }
9
+ end
10
+
11
+ it "should return the default for a column from the database" do
12
+ table = database.adapter.schema.database_tables.detect{|table| table.name == "animals"}
13
+ columns = table.database_columns
14
+
15
+ column1 = columns.detect{|column| column.name == :name }
16
+ column1.default.should == "No Name"
17
+
18
+ column2 = columns.detect{|column| column.name == :nice }
19
+ column2.default.should == nil
20
+ end
21
+
22
+ it "should return the nullability for a column from the database" do
23
+ table = database.adapter.schema.database_tables.detect{|table| table.name == "animals"}
24
+ columns = table.database_columns
25
+
26
+ column1 = columns.detect{|column| column.name == :id }
27
+ column1.nullable?.should be_false
28
+
29
+ column2 = columns.detect{|column| column.name == :nice }
30
+ column2.nullable?.should be_true
31
+ end
32
+
33
+ end
@@ -1,12 +1,12 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
2
 
3
- describe DataMapper::Validations::ConfirmationValidator do
3
+ describe Validatable::ValidatesConfirmationOf do
4
4
 
5
5
  before(:all) do
6
6
  class Cow
7
7
 
8
8
  include DataMapper::CallbacksHelper
9
- include DataMapper::Validations::ValidationHelper
9
+ include DataMapper::Validations
10
10
 
11
11
  attr_accessor :name, :name_confirmation, :age
12
12
  end
@@ -14,8 +14,8 @@ describe DataMapper::Validations::ConfirmationValidator do
14
14
 
15
15
  it 'should pass validation' do
16
16
  class Cow
17
- validations.clear!
18
- validates_confirmation_of :name, :context => :save
17
+ validations.clear
18
+ validates_confirmation_of :name, :event => :save
19
19
  end
20
20
 
21
21
  betsy = Cow.new
@@ -36,4 +36,20 @@ describe DataMapper::Validations::ConfirmationValidator do
36
36
  betsy.valid?(:save).should == true
37
37
  end
38
38
 
39
+ it 'should allow allow a custom error message' do
40
+ class Cow
41
+ validations.clear
42
+ validates_confirmation_of :name, :event => :save, :message => 'You confirm name NOW or else.'
43
+ end
44
+
45
+ betsy = Cow.new
46
+ betsy.valid?.should == true
47
+
48
+ betsy.name = 'Betsy'
49
+ betsy.name_confirmation = ''
50
+ betsy.valid?(:save).should == false
51
+
52
+ betsy.errors.full_messages.first.should == 'You confirm name NOW or else.'
53
+ end
54
+
39
55
  end
@@ -1,12 +1,12 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
2
 
3
- context DataMapper::Validations::FormatValidator do
3
+ context Validatable::ValidatesFormatOf do
4
4
 
5
5
  before(:all) do
6
6
  class Employee
7
7
 
8
8
  include DataMapper::CallbacksHelper
9
- include DataMapper::Validations::ValidationHelper
9
+ include DataMapper::Validations
10
10
 
11
11
  attr_accessor :email
12
12
  end
@@ -14,8 +14,8 @@ context DataMapper::Validations::FormatValidator do
14
14
 
15
15
  it 'must have a valid email address' do
16
16
  class Employee
17
- validations.clear!
18
- validates_format_of :email, :as => :email_address, :on => :save
17
+ validations.clear
18
+ validates_format_of :email, :with => :email_address, :on => :save
19
19
  end
20
20
 
21
21
  e = Employee.new
@@ -26,6 +26,7 @@ context DataMapper::Validations::FormatValidator do
26
26
  'tester@exampl$.com', '[scizzle]@example.com', '.test@example.com'
27
27
  ].all? { |test_email|
28
28
  e.email = test_email
29
+ puts "Email is: #{test_email}"
29
30
  e.valid?(:save).should == false
30
31
  e.errors.full_messages.first.should == "#{test_email} is not a valid email address"
31
32
  }
@@ -36,15 +37,13 @@ context DataMapper::Validations::FormatValidator do
36
37
 
37
38
  it 'must have a valid organization code' do
38
39
  class Employee
39
- validations.clear!
40
+ validations.clear
40
41
 
41
42
  attr_accessor :organization_code
42
43
 
43
44
  # WARNING: contrived example
44
45
  # The organization code must be A#### or B######X12
45
- validates_format_of :organization_code, :on => :save, :with => lambda { |code|
46
- (code =~ /A\d{4}/) || (code =~ /[B-Z]\d{6}X12/)
47
- }
46
+ validates_format_of :organization_code, :on => :save, :with => /(A\d{4}|[B-Z]\d{6}X12)/
48
47
  end
49
48
 
50
49
  e = Employee.new
@@ -61,4 +60,19 @@ context DataMapper::Validations::FormatValidator do
61
60
  e.valid?(:save).should == true
62
61
  end
63
62
 
63
+
64
+ it 'should allow custom error messages' do
65
+ class Employee
66
+ validations.clear
67
+ validates_format_of :email, :with => :email_address, :on => :save, :message => "Me needs good email, m'kay?"
68
+ end
69
+
70
+ e = Employee.new
71
+ e.valid?.should == true
72
+
73
+ e.valid?(:save).should == false
74
+ e.errors.full_messages.first.should == "Me needs good email, m'kay?"
75
+
76
+ end
77
+
64
78
  end
@@ -1,12 +1,12 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
2
 
3
- describe DataMapper::Validations::LengthValidator do
3
+ describe Validatable::ValidatesLengthOf do
4
4
 
5
5
  before(:all) do
6
6
  class Cow
7
7
 
8
8
  include DataMapper::CallbacksHelper
9
- include DataMapper::Validations::ValidationHelper
9
+ include DataMapper::Validations
10
10
 
11
11
  attr_accessor :name, :age
12
12
  end
@@ -14,19 +14,19 @@ describe DataMapper::Validations::LengthValidator do
14
14
 
15
15
  it 'should not have a name shorter than 3 characters' do
16
16
  class Cow
17
- validations.clear!
18
- validates_length_of :name, :min => 3, :context => :save
17
+ validations.clear
18
+ validates_length_of :name, :minimum => 3, :event => :save
19
19
  end
20
20
 
21
21
  betsy = Cow.new
22
22
  betsy.valid?.should == true
23
23
 
24
24
  betsy.valid?(:save).should == false
25
- betsy.errors.full_messages.first.should == 'Name must be more than 3 characters long'
25
+ betsy.errors.full_messages.first.should == 'Name must be more than 2 characters long'
26
26
 
27
27
  betsy.name = 'Be'
28
28
  betsy.valid?(:save).should == false
29
- betsy.errors.full_messages.first.should == 'Name must be more than 3 characters long'
29
+ betsy.errors.full_messages.first.should == 'Name must be more than 2 characters long'
30
30
 
31
31
  betsy.name = 'Bet'
32
32
  betsy.valid?(:save).should == true
@@ -38,8 +38,8 @@ describe DataMapper::Validations::LengthValidator do
38
38
 
39
39
  it 'should not have a name longer than 10 characters' do
40
40
  class Cow
41
- validations.clear!
42
- validates_length_of :name, :max => 10, :context => :save
41
+ validations.clear
42
+ validates_length_of :name, :maximum => 10, :event => :save
43
43
  end
44
44
 
45
45
  betsy = Cow.new
@@ -48,7 +48,7 @@ describe DataMapper::Validations::LengthValidator do
48
48
 
49
49
  betsy.name = 'Testicular Fortitude'
50
50
  betsy.valid?(:save).should == false
51
- betsy.errors.full_messages.first.should == 'Name must be less than 10 characters long'
51
+ betsy.errors.full_messages.first.should == 'Name must be less than 11 characters long'
52
52
 
53
53
  betsy.name = 'Betsy'
54
54
  betsy.valid?(:save).should == true
@@ -56,8 +56,8 @@ describe DataMapper::Validations::LengthValidator do
56
56
 
57
57
  it 'should have a name that is 8 characters long' do
58
58
  class Cow
59
- validations.clear!
60
- validates_length_of :name, :is => 8, :context => :save
59
+ validations.clear
60
+ validates_length_of :name, :is => 8, :event => :save
61
61
  end
62
62
 
63
63
  # Context is not save
@@ -77,8 +77,8 @@ describe DataMapper::Validations::LengthValidator do
77
77
 
78
78
  it 'should have a name that is between 10 and 15 characters long' do
79
79
  class Cow
80
- validations.clear!
81
- validates_length_of :name, :in => (10..15), :context => :save
80
+ validations.clear
81
+ validates_length_of :name, :within => (10..15), :event => :save
82
82
  end
83
83
 
84
84
  # Context is not save
@@ -101,4 +101,17 @@ describe DataMapper::Validations::LengthValidator do
101
101
  betsy.name = 'Smootenstein'
102
102
  betsy.valid?(:save).should == true
103
103
  end
104
+
105
+ it 'should allow custom error messages' do
106
+ class Cow
107
+ validations.clear
108
+ validates_length_of :name, :is => 8, :event => :save, :message => '8 letters, no more, no less.'
109
+ end
110
+
111
+ betsy = Cow.new
112
+ betsy.valid?.should == true
113
+
114
+ betsy.valid?(:save).should == false
115
+ betsy.errors.full_messages.first.should == '8 letters, no more, no less.'
116
+ end
104
117
  end
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
2
 
3
- describe DataMapper::Validations::UniqueValidator do
3
+ describe Validatable::ValidatesUniquenessOf do
4
4
 
5
5
  before(:all) do
6
6
  fixtures('people')
@@ -8,8 +8,8 @@ describe DataMapper::Validations::UniqueValidator do
8
8
 
9
9
  it 'must have a unique name' do
10
10
  class Animal
11
- validations.clear!
12
- validates_uniqueness_of :name, :context => :save
11
+ validations.clear
12
+ validates_uniqueness_of :name, :event => :save
13
13
  end
14
14
 
15
15
  bugaboo = Animal.new
@@ -25,8 +25,8 @@ describe DataMapper::Validations::UniqueValidator do
25
25
 
26
26
  it 'must have a unique name for their occupation' do
27
27
  class Person
28
- validations.clear!
29
- validates_uniqueness_of :name, :context => :save, :scope => :occupation
28
+ validations.clear
29
+ validates_uniqueness_of :name, :event => :save, :scope => :occupation
30
30
  end
31
31
 
32
32
  new_programmer_scott = Person.new(:name => 'Scott', :age => 29, :occupation => 'Programmer')
@@ -41,4 +41,17 @@ describe DataMapper::Validations::UniqueValidator do
41
41
  new_programmer_scott.errors.full_messages.first.should == "Name has already been taken"
42
42
  end
43
43
 
44
+ it "should allow custom error messages" do
45
+ class Animal
46
+ validations.clear
47
+ validates_uniqueness_of :name, :event => :save, :message => 'You try to steal my name? I kill you!'
48
+ end
49
+
50
+ bugaboo = Animal.new
51
+ bugaboo.valid?.should == true
52
+
53
+ bugaboo.name = 'Bear'
54
+ bugaboo.valid?(:save).should == false
55
+ bugaboo.errors.full_messages.first.should == 'You try to steal my name? I kill you!'
56
+ end
44
57
  end