datamapper 0.2.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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