datamapper 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/CHANGELOG +5 -1
  2. data/FAQ +96 -0
  3. data/QUICKLINKS +12 -0
  4. data/README +57 -155
  5. data/environment.rb +61 -43
  6. data/example.rb +30 -12
  7. data/lib/data_mapper.rb +6 -1
  8. data/lib/data_mapper/adapters/abstract_adapter.rb +0 -57
  9. data/lib/data_mapper/adapters/data_object_adapter.rb +203 -97
  10. data/lib/data_mapper/adapters/mysql_adapter.rb +4 -0
  11. data/lib/data_mapper/adapters/postgresql_adapter.rb +7 -1
  12. data/lib/data_mapper/adapters/sql/coersion.rb +3 -2
  13. data/lib/data_mapper/adapters/sql/commands/load_command.rb +29 -10
  14. data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +4 -0
  15. data/lib/data_mapper/adapters/sql/mappings/column.rb +13 -9
  16. data/lib/data_mapper/adapters/sql/mappings/conditions.rb +172 -0
  17. data/lib/data_mapper/adapters/sql/mappings/table.rb +43 -17
  18. data/lib/data_mapper/adapters/sqlite3_adapter.rb +9 -2
  19. data/lib/data_mapper/associations.rb +75 -3
  20. data/lib/data_mapper/associations/belongs_to_association.rb +70 -36
  21. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +195 -86
  22. data/lib/data_mapper/associations/has_many_association.rb +168 -61
  23. data/lib/data_mapper/associations/has_n_association.rb +23 -3
  24. data/lib/data_mapper/attributes.rb +73 -0
  25. data/lib/data_mapper/auto_migrations.rb +2 -6
  26. data/lib/data_mapper/base.rb +5 -9
  27. data/lib/data_mapper/database.rb +4 -3
  28. data/lib/data_mapper/embedded_value.rb +66 -30
  29. data/lib/data_mapper/identity_map.rb +1 -3
  30. data/lib/data_mapper/is/tree.rb +121 -0
  31. data/lib/data_mapper/migration.rb +155 -0
  32. data/lib/data_mapper/persistence.rb +532 -218
  33. data/lib/data_mapper/property.rb +306 -0
  34. data/lib/data_mapper/query.rb +164 -0
  35. data/lib/data_mapper/support/blank.rb +2 -2
  36. data/lib/data_mapper/support/connection_pool.rb +5 -6
  37. data/lib/data_mapper/support/enumerable.rb +3 -3
  38. data/lib/data_mapper/support/errors.rb +10 -1
  39. data/lib/data_mapper/support/inflector.rb +174 -238
  40. data/lib/data_mapper/support/object.rb +54 -0
  41. data/lib/data_mapper/support/serialization.rb +19 -1
  42. data/lib/data_mapper/support/string.rb +7 -16
  43. data/lib/data_mapper/support/symbol.rb +3 -15
  44. data/lib/data_mapper/support/typed_set.rb +68 -0
  45. data/lib/data_mapper/types/base.rb +44 -0
  46. data/lib/data_mapper/types/string.rb +34 -0
  47. data/lib/data_mapper/validations/number_validator.rb +40 -0
  48. data/lib/data_mapper/validations/string_validator.rb +20 -0
  49. data/lib/data_mapper/validations/validator.rb +13 -0
  50. data/performance.rb +26 -1
  51. data/profile_data_mapper.rb +1 -1
  52. data/rakefile.rb +42 -2
  53. data/spec/acts_as_tree_spec.rb +11 -3
  54. data/spec/adapters/data_object_adapter_spec.rb +31 -0
  55. data/spec/associations/belongs_to_association_spec.rb +98 -0
  56. data/spec/associations/has_and_belongs_to_many_association_spec.rb +377 -0
  57. data/spec/associations/has_many_association_spec.rb +337 -0
  58. data/spec/attributes_spec.rb +23 -1
  59. data/spec/auto_migrations_spec.rb +86 -29
  60. data/spec/callbacks_spec.rb +107 -0
  61. data/spec/column_spec.rb +5 -2
  62. data/spec/count_command_spec.rb +33 -1
  63. data/spec/database_spec.rb +18 -0
  64. data/spec/dependency_spec.rb +4 -2
  65. data/spec/embedded_value_spec.rb +8 -8
  66. data/spec/fixtures/people.yaml +1 -1
  67. data/spec/fixtures/projects.yaml +10 -1
  68. data/spec/fixtures/tasks.yaml +6 -0
  69. data/spec/fixtures/tasks_tasks.yaml +2 -0
  70. data/spec/fixtures/tomatoes.yaml +1 -0
  71. data/spec/is_a_tree_spec.rb +149 -0
  72. data/spec/load_command_spec.rb +71 -9
  73. data/spec/magic_columns_spec.rb +17 -2
  74. data/spec/migration_spec.rb +267 -0
  75. data/spec/models/animal.rb +1 -1
  76. data/spec/models/candidate.rb +8 -0
  77. data/spec/models/career.rb +1 -1
  78. data/spec/models/chain.rb +8 -0
  79. data/spec/models/comment.rb +1 -1
  80. data/spec/models/exhibit.rb +1 -1
  81. data/spec/models/fence.rb +7 -0
  82. data/spec/models/fruit.rb +2 -2
  83. data/spec/models/job.rb +8 -0
  84. data/spec/models/person.rb +2 -3
  85. data/spec/models/post.rb +1 -1
  86. data/spec/models/project.rb +21 -1
  87. data/spec/models/section.rb +1 -1
  88. data/spec/models/serializer.rb +1 -1
  89. data/spec/models/task.rb +9 -0
  90. data/spec/models/tomato.rb +27 -0
  91. data/spec/models/user.rb +8 -2
  92. data/spec/models/zoo.rb +2 -7
  93. data/spec/paranoia_spec.rb +1 -1
  94. data/spec/{base_spec.rb → persistence_spec.rb} +207 -18
  95. data/spec/postgres_spec.rb +48 -6
  96. data/spec/property_spec.rb +90 -9
  97. data/spec/query_spec.rb +71 -5
  98. data/spec/save_command_spec.rb +11 -0
  99. data/spec/spec_helper.rb +14 -11
  100. data/spec/support/blank_spec.rb +8 -0
  101. data/spec/support/inflector_spec.rb +41 -0
  102. data/spec/support/object_spec.rb +9 -0
  103. data/spec/{serialization_spec.rb → support/serialization_spec.rb} +1 -1
  104. data/spec/support/silence_spec.rb +15 -0
  105. data/spec/{support_spec.rb → support/string_spec.rb} +3 -3
  106. data/spec/support/struct_spec.rb +12 -0
  107. data/spec/support/typed_set_spec.rb +66 -0
  108. data/spec/table_spec.rb +3 -3
  109. data/spec/types/string.rb +81 -0
  110. data/spec/validates_uniqueness_of_spec.rb +17 -0
  111. data/spec/validations/number_validator.rb +59 -0
  112. data/spec/validations/string_validator.rb +14 -0
  113. metadata +59 -17
  114. data/do_performance.rb +0 -153
  115. data/lib/data_mapper/support/active_record_impersonation.rb +0 -103
  116. data/lib/data_mapper/support/weak_hash.rb +0 -46
  117. data/spec/active_record_impersonation_spec.rb +0 -129
  118. data/spec/associations_spec.rb +0 -232
  119. data/spec/conditions_spec.rb +0 -49
  120. data/spec/has_many_association_spec.rb +0 -173
  121. data/spec/models/animals_exhibit.rb +0 -8
@@ -5,24 +5,66 @@ require File.dirname(__FILE__) + "/spec_helper"
5
5
  if ENV['ADAPTER'] == 'postgresql'
6
6
 
7
7
  describe DataMapper::Adapters::PostgresqlAdapter::Mappings::Column do
8
+ before(:all) do
9
+ @mappings = DataMapper::Adapters::PostgresqlAdapter::Mappings
10
+ @table = @mappings::Table.new(database(:mock).adapter, "Zebu")
11
+ end
12
+
8
13
  it "should be able to set check-constraints on columns" do
9
- mappings = DataMapper::Adapters::PostgresqlAdapter::Mappings
10
- table = mappings::Table.new(database(:mock).adapter, "Zebu")
11
- column = mappings::Column.new(database(:mock).adapter, table, :age,
14
+ column = @mappings::Column.new(database(:mock).adapter, @table, :age,
12
15
  :integer, 1, { :check => "age > 18"})
13
16
  column.to_long_form.should match(/CHECK \(age > 18\)/)
14
17
  end
18
+
19
+ it "should not set varchar length if none is specified" do
20
+ column = @mappings::Column.new(database(:mock).adapter, @table,
21
+ :varchar_len_test, :string, 1, { })
22
+ column.size.should == nil
23
+ column.to_long_form.should match(/.varchar_len_test. varchar/)
24
+ end
25
+
26
+ it "should set varchar length when it is specified" do
27
+ column = @mappings::Column.new(database(:mock).adapter, @table,
28
+ :varchar_len_test, :string, 1, { :length => 100 })
29
+ column.size.should == 100
30
+ column.to_long_form.should match(/.varchar_len_test. varchar\(100\)/)
31
+ end
32
+
33
+ it "should accept :size as alternative to :length" do
34
+ column = @mappings::Column.new(database(:mock).adapter, @table,
35
+ :varchar_len_test, :string, 1, { :size => 100 })
36
+ column.size.should == 100
37
+ column.to_long_form.should match(/.varchar_len_test. varchar\(100\)/)
38
+ end
39
+
40
+ it "should have size of nil when length of integer is specified" do
41
+ column = @mappings::Column.new(database(:mock).adapter, @table,
42
+ :integer_len_test, :integer, 1, { :length => 1 })
43
+ column.size.should == nil
44
+ column.to_long_form.should match(/.integer_len_test./)
45
+ end
46
+
47
+ it "should have size of nil when length of integer is not specified, overriding the default" do
48
+ column = @mappings::Column.new(database(:mock).adapter, @table,
49
+ :integer_len_test, :integer, 1)
50
+ column.size.should == nil
51
+ column.to_long_form.should match(/.integer_len_test./)
52
+ end
15
53
  end
16
54
 
17
55
  describe DataMapper::Adapters::PostgresqlAdapter::Mappings::Table do
18
56
 
19
57
  before(:all) do
20
- class Cage < DataMapper::Base
58
+ class Cage #< DataMapper::Base # please do not remove this
59
+ include DataMapper::Base
60
+
21
61
  set_table_name "cages"
22
62
  property :name, :string
23
63
  end
24
64
 
25
- class CageInSchema < DataMapper::Base
65
+ class CageInSchema #< DataMapper::Base # please do not remove this
66
+ include DataMapper::Base
67
+
26
68
  set_table_name "my_schema.cages"
27
69
  property :name, :string
28
70
  end
@@ -51,4 +93,4 @@ if ENV['ADAPTER'] == 'postgresql'
51
93
 
52
94
  end
53
95
 
54
- end
96
+ end
@@ -1,3 +1,5 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
1
3
  describe DataMapper::Property do
2
4
 
3
5
  before(:all) do
@@ -5,22 +7,102 @@ describe DataMapper::Property do
5
7
  end
6
8
 
7
9
  it "should map a column" do
8
- pending('until Property is implemented')
9
10
  @property.column.should eql(database.table(Zoo)[:notes])
10
11
  end
11
12
 
12
13
  it "should determine lazyness" do
13
- pending('until Property is implemented')
14
14
  @property.should be_lazy
15
15
  end
16
16
 
17
- it "should determine protection level"
17
+ it "should determine protection level" do
18
+ @property.reader_visibility.should == :public
19
+ @property.writer_visibility.should == :public
20
+ end
21
+
22
+ it "should return instance variable name" do
23
+ @property.instance_variable_name.should == database.table(Zoo)[:notes].instance_variable_name
24
+ end
25
+
26
+ it "should add a validates_presence_of for not-null properties" do
27
+ class NullableZoo #< DataMapper::Base # please do not remove this
28
+ include DataMapper::Persistence
29
+
30
+ property :name, :string, :nullable => false, :default => "Zoo"
31
+ end
32
+ zoo = NullableZoo.new
33
+ zoo.valid?.should == false
34
+ zoo.name = "Content"
35
+ zoo.valid?.should == true
36
+ end
18
37
 
19
- it "should return instance variable name"
38
+ it "should add a validates_length_of for maximum size" do
39
+ class SizableZoo #< DataMapper::Base # please do not remove this
40
+ include DataMapper::Persistence
41
+ property :name, :string, :length => 50
42
+ end
43
+ zoo = SizableZoo.new(:name => "San Diego" * 100)
44
+ zoo.valid?.should == false
45
+ zoo.name = "San Diego"
46
+ zoo.valid?.should == true
47
+ end
20
48
 
21
- it "should add a validates_presence_of for not-null properties"
49
+ it "should add a validates_length_of for a range" do
50
+ class RangableZoo #< DataMapper::Base # please do not remove this
51
+ include DataMapper::Persistence
52
+ property :name, :string, :length => 2..255
53
+ end
54
+ zoo = RangableZoo.new(:name => "A")
55
+ zoo.valid?.should == false
56
+ zoo.name = "Zoo"
57
+ zoo.valid?.should == true
58
+ end
22
59
 
23
- it "should add a validates_format_of if you pass a format option"
60
+ it "should add a validates_format_of if you pass a format option" do
61
+ class FormatableUser
62
+ include DataMapper::Persistence
63
+ property :email, :string, :format => :email_address
64
+ end
65
+ user = FormatableUser.new(:email => "incomplete_email")
66
+ user.valid?.should == false
67
+ user.email = "complete_email@anonymous.com"
68
+ user.valid?.should == true
69
+ end
70
+
71
+ it "should not add a validates_presence_of for not-null properties if auto valdations are disabled" do
72
+ class NullableZoo #< DataMapper::Base # please do not remove this
73
+ include DataMapper::Persistence
74
+ property :name, :string, :nullable => false, :default => "Zoo", :auto_validation => false
75
+ end
76
+ zoo = NullableZoo.new
77
+ zoo.errors.empty?.should == true
78
+ end
79
+
80
+ it "should not add a validates_length_of if auto validations are disabled" do
81
+ class SizableZoo #< DataMapper::Base # please do not remove this
82
+ include DataMapper::Persistence
83
+ property :name, :string, :length => 50, :auto_validation => false
84
+ end
85
+ zoo = SizableZoo.new(:name => "San Diego" * 100)
86
+ zoo.errors.empty?.should == true
87
+ end
88
+
89
+ it "should not add a validates_format_of if you pass a format option if auto validations are disabled" do
90
+ class FormatableUser
91
+ include DataMapper::Persistence
92
+ property :email, :string, :format => :email_address, :auto_validation => false
93
+ end
94
+ user = FormatableUser.new(:email => "incomplete_email")
95
+ user.errors.empty?.should == true
96
+ end
97
+
98
+ it "should raise ArgumentError for unsupported types" do
99
+ lambda {
100
+ class PersistentFailure #< DataMapper::Base # please do not remove this
101
+ include DataMapper::Persistence
102
+ property :created_at, :timestamp
103
+ end
104
+ }.should raise_error(ArgumentError)
105
+ end
24
106
  end
25
107
 
26
108
  describe DataMapper::Adapters::Sql::Mappings do
@@ -44,8 +126,7 @@ describe DataMapper::Adapters::Sql::Mappings do
44
126
  end
45
127
 
46
128
  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
-
129
+ # pending("This one still needs some love to pass.")
49
130
  table = database.table(Person)
50
131
 
51
132
  # Every property's column should be represented in the Table's column mappings.
@@ -55,7 +136,7 @@ describe DataMapper::Adapters::Sql::Mappings do
55
136
 
56
137
  # For both models in the STI setup...
57
138
  SalesPerson.properties.each do |property|
58
- table.columns.should include(property.column)
139
+ database.table(SalesPerson).columns.should include(property.column)
59
140
  end
60
141
 
61
142
  # Even though Person's properties are fewer than a SalesPerson's
@@ -1,11 +1,77 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
2
 
3
- describe('A query') do
3
+ # * you have some crazy finder options... ie: Zoo, :name => 'bob', :include => :exhibits
4
+ #
5
+ # * you want to turn this into SQL.
6
+ #
7
+ # * you want to execute this SQL...
8
+ #
9
+ # * you want to load objects from the results, which means you have to know what columns in the results map to what objects
10
+ #
11
+ # * some values in the results will have no corresponding objects, theyll be indicators of other behaviour that should take place
12
+ # ie: the values for a m:n join table will tell you how to bind the associated objects together, or...
13
+ # the :type column will tell you what type to instantiate
14
+ #
15
+ #
16
+ # So... the Query class should basically take the options from step 1, give you the SQL in step 2,
17
+ # allow you to handle step 3, and expose types/result-set mappings to load objects by for step 4.
18
+ # step 5 should be handled in the DataObjectAdapter
19
+ describe DataMapper::Query do
4
20
 
5
- it 'should return a simple Array of primitives' do
6
- database.query("SELECT name FROM zoos").all? do |entry|
7
- entry.kind_of?(String)
8
- end.should == true
21
+ it "should generate the correct queries for the given options" do
22
+ query = DataMapper::Query.new(database(:mock).adapter, Zoo, :name => 'bob')
23
+ query.to_sql.should == "SELECT `id`, `name`, `updated_at` FROM `zoos` WHERE (`name` = ?)"
24
+ query.parameters.should == ['bob']
25
+
26
+ query = DataMapper::Query.new(database(:mock).adapter, Animal, :name => 'bob')
27
+ query.to_sql.should == "SELECT `id`, `name`, `nice` FROM `animals` WHERE (`name` = ?)"
28
+ query.parameters.should == ['bob']
29
+
30
+ query = DataMapper::Query.new(database(:mock).adapter, Project)
31
+ query.to_sql.should == "SELECT `id`, `title`, `description`, `deleted_at` FROM `projects` WHERE (`deleted_at` IS NULL OR `deleted_at` > NOW())"
32
+ query.parameters.should be_empty
33
+ end
34
+
35
+ it "should use the include option for lazily-loaded columns" do
36
+ query = DataMapper::Query.new(database(:mock).adapter, Zoo, :include => :notes)
37
+ query.to_sql.should == "SELECT `id`, `name`, `notes`, `updated_at` FROM `zoos`"
38
+ query.parameters.should be_empty
39
+ end
40
+
41
+ it "should generate the correct join query" do
42
+ query = DataMapper::Query.new(database(:mock).adapter, Zoo, :include => [:exhibits])
43
+ query.to_sql.should == <<-EOS.compress_lines
44
+ SELECT `zoos`.`id`, `zoos`.`name`, `zoos`.`updated_at`, `exhibits`.`id`, `exhibits`.`name`, `exhibits`.`zoo_id`
45
+ FROM `zoos`
46
+ JOIN `exhibits` ON `exhibits`.`zoo_id` = `zoos`.`id`
47
+ EOS
48
+
49
+ query = DataMapper::Query.new(database(:mock).adapter, Zoo, :include => [:exhibits], :name => ['bob', 'sam'])
50
+ query.to_sql.should == <<-EOS.compress_lines
51
+ SELECT `zoos`.`id`, `zoos`.`name`, `zoos`.`updated_at`, `exhibits`.`id`, `exhibits`.`name`, `exhibits`.`zoo_id`
52
+ FROM `zoos`
53
+ JOIN `exhibits` ON `exhibits`.`zoo_id` = `zoos`.`id`
54
+ WHERE (`zoos`.`name` IN ?)
55
+ EOS
56
+ query.parameters.should == [['bob', 'sam']]
57
+ end
58
+
59
+ it "should be forgiving with options that require Arrays" do
60
+
61
+ query = DataMapper::Query.new(database(:mock).adapter, Zoo, :conditions => ["`name` = ?", 'bob'])
62
+ query.to_sql.should == "SELECT `id`, `name`, `updated_at` FROM `zoos` WHERE (`name` = ?)"
63
+ query.parameters.should == ['bob']
64
+
65
+ query = DataMapper::Query.new(database(:mock).adapter, Zoo, :conditions => "`name` = 'bob'")
66
+ query.to_sql.should == "SELECT `id`, `name`, `updated_at` FROM `zoos` WHERE (`name` = 'bob')"
67
+ query.parameters.should be_empty
68
+
69
+ query = DataMapper::Query.new(database(:mock).adapter, Zoo, :include => :exhibits)
70
+ query.to_sql.should == <<-EOS.compress_lines
71
+ SELECT `zoos`.`id`, `zoos`.`name`, `zoos`.`updated_at`, `exhibits`.`id`, `exhibits`.`name`, `exhibits`.`zoo_id`
72
+ FROM `zoos`
73
+ JOIN `exhibits` ON `exhibits`.`zoo_id` = `zoos`.`id`
74
+ EOS
9
75
  end
10
76
 
11
77
  end
@@ -36,6 +36,11 @@ describe "Save Commands" do
36
36
  end
37
37
  end
38
38
 
39
+ it "should return success of save call, not status of query execution" do
40
+ # pending "http://wm.lighthouseapp.com/projects/4819/tickets/54-save-should-return-success"
41
+ Exhibit.first.save.should be_true
42
+ end
43
+
39
44
  it "should be invalid if invalid associations are loaded" do
40
45
  miami = Zoo.first(:name => 'Miami')
41
46
  fish_fancy = Exhibit.new
@@ -80,4 +85,10 @@ describe "Save Commands" do
80
85
  end
81
86
  end
82
87
 
88
+ it "save! should raise an error if validation failed" do
89
+ # pending "http://wm.lighthouseapp.com/projects/4819/tickets/29-dm-context-write"
90
+ empty = Zoo.new
91
+ lambda { empty.save! }.should raise_error(DataMapper::ValidationError)
92
+ end
93
+
83
94
  end
@@ -11,11 +11,11 @@ def fixtures(name)
11
11
  rescue
12
12
  nil
13
13
  end
14
-
15
- unless klass.nil?
14
+
15
+ unless klass.nil?
16
16
  database.logger.debug { "AUTOMIGRATE: #{klass}" }
17
17
  klass.auto_migrate!
18
-
18
+
19
19
  (entry.kind_of?(Array) ? entry : [entry]).each do |hash|
20
20
  if hash['type']
21
21
  Object::const_get(hash['type'])::create(hash)
@@ -24,19 +24,22 @@ def fixtures(name)
24
24
  end
25
25
  end
26
26
  else
27
- # TODO: Get rid of the stupid AnimalsExhibit model...
28
27
  table = database.table(name.to_s)
29
28
  table.create! true
30
-
31
- pp database.schema
32
-
33
- (entry.kind_of?(Array) ? entry : [entry]).each do |hash|
29
+ table.activate_associations!
30
+
31
+ #pp database.schema
32
+
33
+ (entry.kind_of?(Array) ? entry : [entry]).each do |hash|
34
34
  table.insert(hash)
35
35
  end
36
36
  end
37
37
  end
38
38
 
39
- # Pre-fill the database so non-destructive tests don't need to reload fixtures.
40
- Dir[File.dirname(__FILE__) + "/fixtures/*.yaml"].each do |path|
41
- fixtures(File::basename(path).sub(/\.yaml$/, ''))
39
+ def load_database
40
+ Dir[File.dirname(__FILE__) + "/fixtures/*.yaml"].each do |path|
41
+ fixtures(File::basename(path).sub(/\.yaml$/, ''))
42
+ end
42
43
  end
44
+
45
+ load_database
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe DataMapper::Support do
4
+ it "should mark empty objects as blank" do
5
+ [ nil, false, '', ' ', " \n\t \r ", [], {} ].each { |f| f.should be_blank }
6
+ [ Object.new, true, 0, 1, 'a', [nil], { nil => 0 } ].each { |t| t.should_not be_blank }
7
+ end
8
+ end
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe Inflector do
4
+ it "should camelize strings" do
5
+ Inflector.camelize("data_mapper").should == "DataMapper"
6
+ Inflector.camelize("data_mapper/support").should == "DataMapper::Support"
7
+ end
8
+
9
+ it "should pluralize strings" do
10
+ Inflector.pluralize("post").should == "posts"
11
+ Inflector.pluralize("octopus").should == "octopi"
12
+ Inflector.pluralize("sheep").should == "sheep"
13
+ Inflector.pluralize("word").should == "words"
14
+ Inflector.pluralize("the blue mailman").should == "the blue mailmen"
15
+ Inflector.pluralize("CamelOctopus").should == "CamelOctopi"
16
+ end
17
+
18
+ it "should singularize strings" do
19
+ Inflector.singularize("posts").should == "post"
20
+ Inflector.singularize("octopi").should == "octopus"
21
+ Inflector.singularize("sheep").should == "sheep"
22
+ Inflector.singularize("word").should == "word"
23
+ Inflector.singularize("the blue mailmen").should == "the blue mailman"
24
+ Inflector.singularize("CamelOctopi").should == "CamelOctopus"
25
+ end
26
+
27
+ it "should demodulize strings" do
28
+ Inflector.demodulize("DataMapper::Support").should == "Support"
29
+ end
30
+
31
+ it "should create foreign keys from class names and key names" do
32
+ Inflector.foreign_key("Animal").should == "animal_id"
33
+ Inflector.foreign_key("Admin::Post").should == "post_id"
34
+ Inflector.foreign_key("Animal", "name").should == "animal_name"
35
+ end
36
+
37
+ it "should constantize strings" do
38
+ Inflector.constantize("Class").should == Class
39
+ lambda { Inflector.constantize("asdf") }.should raise_error
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe DataMapper::Support::Object do
4
+
5
+ it "should be able to get a recursive constant" do
6
+ Object.recursive_const_get('DataMapper::Support::String').should == DataMapper::Support::String
7
+ end
8
+
9
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/spec_helper"
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
2
 
3
3
  describe DataMapper::Support::Serialization do
4
4
 
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe "Kernel#silence_warnings" do
4
+
5
+ it "should not warn" do
6
+ $VERBOSE.should_not be_nil
7
+
8
+ silence_warnings do
9
+ $VERBOSE.should be_nil
10
+ end
11
+
12
+ $VERBOSE.should_not be_nil
13
+ end
14
+
15
+ end