dm-core 1.0.0.rc3 → 1.0.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.
data/Gemfile CHANGED
@@ -71,7 +71,7 @@
71
71
  source 'http://rubygems.org'
72
72
 
73
73
  DATAMAPPER = 'git://github.com/datamapper'
74
- DM_VERSION = '~> 1.0.0.rc3'
74
+ DM_VERSION = '~> 1.0.0'
75
75
 
76
76
  group :runtime do # Runtime dependencies (as in the gemspec)
77
77
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0.rc3
1
+ 1.0.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dm-core}
8
- s.version = "1.0.0.rc3"
8
+ s.version = "1.0.0"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Dan Kubb"]
12
- s.date = %q{2010-05-27}
12
+ s.date = %q{2010-06-08}
13
13
  s.description = %q{Faster, Better, Simpler.}
14
14
  s.email = %q{dan.kubb@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -206,7 +206,14 @@ module DataMapper
206
206
 
207
207
  class UpdateConflictError < PersistenceError; end
208
208
 
209
- class SaveFailureError < PersistenceError; end
209
+ class SaveFailureError < PersistenceError
210
+ attr_reader :resource
211
+
212
+ def initialize(message, resource)
213
+ super(message)
214
+ @resource = resource
215
+ end
216
+ end
210
217
 
211
218
  class ImmutableError < RuntimeError; end
212
219
 
@@ -311,6 +318,10 @@ module DataMapper
311
318
  repository_name = model.repository_name
312
319
  relationships = model.relationships(repository_name).values
313
320
 
321
+ if name.to_s.strip.empty?
322
+ raise IncompleteModelError, "#{model.inspect} must have a name"
323
+ end
324
+
314
325
  if model.properties(repository_name).empty? &&
315
326
  !relationships.any? { |relationship| relationship.kind_of?(Associations::ManyToOne::Relationship) }
316
327
  raise IncompleteModelError, "#{name} must have at least one property or many to one relationship to be valid"
@@ -320,13 +331,11 @@ module DataMapper
320
331
  raise IncompleteModelError, "#{name} must have a key to be valid"
321
332
  end
322
333
 
323
-
324
334
  # initialize join models and target keys
325
335
  relationships.each do |relationship|
326
336
  relationship.child_key
327
337
  relationship.through if relationship.respond_to?(:through)
328
338
  relationship.via if relationship.respond_to?(:via)
329
339
  end
330
-
331
340
  end
332
341
  end
@@ -39,7 +39,8 @@ module DataMapper
39
39
  private
40
40
 
41
41
  def setup_hook(type, name, method, proc)
42
- if types = hooks[name]
42
+ types = hooks[name]
43
+ if types && types[type]
43
44
  types[type] << if proc
44
45
  ProcCommand.new(proc)
45
46
  else
@@ -54,8 +55,10 @@ module DataMapper
54
55
  def copy_hooks(model)
55
56
  hooks = Hash.new do |hooks, name|
56
57
  hooks[name] = Hash.new do |types, type|
57
- types[type] = self.hooks[name][type].map do |command|
58
- command.copy(model)
58
+ if self.hooks[name]
59
+ types[type] = self.hooks[name][type].map do |command|
60
+ command.copy(model)
61
+ end
59
62
  end
60
63
  end
61
64
  end
@@ -442,10 +442,10 @@ module DataMapper
442
442
  return true if destroyed?
443
443
  catch :halt do
444
444
  before_destroy_hook
445
- retval = _destroy
445
+ _destroy
446
446
  after_destroy_hook
447
- retval
448
447
  end
448
+ destroyed?
449
449
  end
450
450
 
451
451
  # Destroy the instance, remove it from the repository, bypassing hooks
@@ -457,6 +457,7 @@ module DataMapper
457
457
  def destroy!
458
458
  return true if destroyed?
459
459
  _destroy(false)
460
+ destroyed?
460
461
  end
461
462
 
462
463
  # Compares another Resource for equality
@@ -958,26 +959,13 @@ module DataMapper
958
959
  child_relationships.map { |relationship| relationship.get_collection(self) }
959
960
  end
960
961
 
961
- # Creates the resource with default values
962
+ # Commit the persisted state
962
963
  #
963
- # If resource is not dirty or a new (not yet saved),
964
- # this method returns false
965
- #
966
- # On successful save identity map of the repository is
967
- # updated
968
- #
969
- # Needs to be a protected method so that it is hookable
970
- #
971
- # The primary purpose of this method is to allow before :create
972
- # hooks to fire at a point just before/after resource creation
973
- #
974
- # @return [Boolean]
975
- # true if the receiver was successfully created
964
+ # @return [undefined]
976
965
  #
977
966
  # @api private
978
- def _create
967
+ def _persist
979
968
  self.persisted_state = persisted_state.commit
980
- true
981
969
  end
982
970
 
983
971
  # This method executes the hooks before and after resource creation
@@ -991,28 +979,12 @@ module DataMapper
991
979
  catch :halt do
992
980
  before_save_hook
993
981
  before_create_hook
994
- retval = _create
982
+ _persist
995
983
  after_create_hook
996
984
  after_save_hook
997
- retval
998
985
  end
999
986
  end
1000
987
 
1001
- # Updates resource state
1002
- #
1003
- # The primary purpose of this method is to allow before :update
1004
- # hooks to fire at a point just before/after resource update whether
1005
- # it is the result of Resource#save, or using Resource#update
1006
- #
1007
- # @return [Boolean]
1008
- # true if the receiver was successfully created
1009
- #
1010
- # @api private
1011
- def _update
1012
- self.persisted_state = persisted_state.commit
1013
- clean?
1014
- end
1015
-
1016
988
  # This method executes the hooks before and after resource updating
1017
989
  #
1018
990
  # @return [Boolean]
@@ -1024,18 +996,20 @@ module DataMapper
1024
996
  catch :halt do
1025
997
  before_save_hook
1026
998
  before_update_hook
1027
- retval = _update
999
+ _persist
1028
1000
  after_update_hook
1029
1001
  after_save_hook
1030
- retval
1031
1002
  end
1032
1003
  end
1033
1004
 
1005
+ # Destroy the resource
1006
+ #
1007
+ # @return [undefined]
1008
+ #
1034
1009
  # @api private
1035
1010
  def _destroy(execute_hooks = true)
1036
- deleted = persisted_state.delete
1037
- self.persisted_state = deleted.commit
1038
- true
1011
+ self.persisted_state = persisted_state.delete
1012
+ _persist
1039
1013
  end
1040
1014
 
1041
1015
  # @api private
@@ -1055,12 +1029,12 @@ module DataMapper
1055
1029
  # short-circuit if the resource is not dirty
1056
1030
  return saved? unless dirty_self?
1057
1031
 
1058
- new_resource = new?
1059
1032
  if execute_hooks
1060
- new_resource ? create_with_hooks : update_with_hooks
1033
+ new? ? create_with_hooks : update_with_hooks
1061
1034
  else
1062
- new_resource ? _create : _update
1035
+ _persist
1063
1036
  end
1037
+ clean?
1064
1038
  end
1065
1039
 
1066
1040
  # Saves the parent resources
@@ -1231,7 +1205,7 @@ module DataMapper
1231
1205
  # @api private
1232
1206
  def assert_save_successful(method, save_retval)
1233
1207
  if save_retval != true && raise_on_save_failure
1234
- raise SaveFailureError, "#{model}##{method} returned #{save_retval.inspect}, #{model} was not saved"
1208
+ raise SaveFailureError.new("#{model}##{method} returned #{save_retval.inspect}, #{model} was not saved", self)
1235
1209
  end
1236
1210
  end
1237
1211
 
@@ -17,8 +17,9 @@ module DataMapper
17
17
  while model = descendants.shift
18
18
  descendants.concat(model.descendants.to_a - [ model ])
19
19
 
20
- unless model.name.to_s[0] == ?#
21
- parts = model.name.split('::')
20
+ model_name = model.name.to_s.strip
21
+ unless model_name.empty? || model_name[0] == ?#
22
+ parts = model_name.split('::')
22
23
  constant_name = parts.pop.to_sym
23
24
  base = parts.empty? ? Object : Object.full_const_get(parts.join('::'))
24
25
 
@@ -767,6 +767,21 @@ share_examples_for 'A public Resource' do
767
767
  end
768
768
  end
769
769
 
770
+ describe 'on a new, invalid resource' do
771
+ before :all do
772
+ @user = @user_model.new(:name => nil)
773
+ @return = @user.__send__(method)
774
+ end
775
+
776
+ it 'should return false' do
777
+ @return.should be(false)
778
+ end
779
+
780
+ it 'should call save hook expected number of times' do
781
+ @user.save_hook_call_count.should == (method == :save ? 1 : nil)
782
+ end
783
+ end
784
+
770
785
  describe 'on a dirty invalid resource' do
771
786
  before :all do
772
787
  rescue_if @skip do
@@ -1,3 +1,3 @@
1
1
  module DataMapper
2
- VERSION = '1.0.0.rc3'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -1,32 +1,43 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
3
  describe DataMapper do
4
- describe '.setup' do
5
- it "should not raise with valid models" do
4
+ describe '.finalize' do
5
+ subject { DataMapper.finalize }
6
+
7
+ it 'should not raise with valid models' do
6
8
  class ::ValidObject
7
9
  include DataMapper::Resource
8
10
  property :id, Integer, :key => true
9
11
  end
10
- lambda { DataMapper.finalize }.should_not raise_error
12
+ method(:subject).should_not raise_error
11
13
  DataMapper::Model.descendants.delete(ValidObject)
12
14
  Object.send(:remove_const, :ValidObject)
13
15
  end
14
16
 
15
- it "should raise on an empty model" do
17
+ it 'should raise on an anonymous model' do
18
+ model = Class.new do
19
+ include DataMapper::Resource
20
+ property :id, Integer, :key => true
21
+ end
22
+ method(:subject).should raise_error(DataMapper::IncompleteModelError, "#{model.inspect} must have a name")
23
+ DataMapper::Model.descendants.delete(model)
24
+ end
25
+
26
+ it 'should raise on an empty model' do
16
27
  class ::EmptyObject
17
28
  include DataMapper::Resource
18
29
  end
19
- lambda { DataMapper.finalize }.should raise_error
30
+ method(:subject).should raise_error(DataMapper::IncompleteModelError, 'EmptyObject must have at least one property or many to one relationship to be valid')
20
31
  DataMapper::Model.descendants.delete(EmptyObject)
21
32
  Object.send(:remove_const, :EmptyObject)
22
33
  end
23
34
 
24
- it "should raise on a keyless model" do
35
+ it 'should raise on a keyless model' do
25
36
  class ::KeylessObject
26
37
  include DataMapper::Resource
27
38
  property :name, String
28
39
  end
29
- lambda { DataMapper.finalize }.should raise_error
40
+ method(:subject).should raise_error(DataMapper::IncompleteModelError, 'KeylessObject must have a key to be valid')
30
41
  DataMapper::Model.descendants.delete(KeylessObject)
31
42
  Object.send(:remove_const, :KeylessObject)
32
43
  end
@@ -12,6 +12,7 @@ describe DataMapper::Model::Hook do
12
12
  end
13
13
 
14
14
  class ::ModelHookSpecsSubclass < ModelHookSpecs; end
15
+
15
16
  DataMapper.finalize
16
17
  end
17
18
 
@@ -99,11 +100,11 @@ describe DataMapper::Model::Hook do
99
100
  supported_by :all do
100
101
  before do
101
102
  @hooks = hooks = []
102
- ModelHookSpecs.before(:create) { hooks << :inherited_hook }
103
+ ModelHookSpecs.before(:an_instance_method) { hooks << :inherited_hook }
103
104
  end
104
105
 
105
106
  it 'should execute inherited hook' do
106
- ModelHookSpecsSubclass.create
107
+ ModelHookSpecsSubclass.new.an_instance_method
107
108
  @hooks.should == [ :inherited_hook ]
108
109
  end
109
110
  end
@@ -113,22 +114,21 @@ describe DataMapper::Model::Hook do
113
114
  supported_by :all do
114
115
  before do
115
116
  @hooks = hooks = []
116
- ModelHookSpecsSubclass.before(:create) { hooks << :hook }
117
+ ModelHookSpecsSubclass.before(:an_instance_method) { hooks << :hook }
117
118
  end
118
119
 
119
120
  it 'should execute hook' do
120
- ModelHookSpecsSubclass.create
121
+ ModelHookSpecsSubclass.new.an_instance_method
121
122
  @hooks.should == [ :hook ]
122
123
  end
123
124
 
124
125
  it 'should not alter hooks in the parent class' do
125
126
  @hooks.should be_empty
126
- ModelHookSpecs.create
127
+ ModelHookSpecs.new.an_instance_method
127
128
  @hooks.should == []
128
129
  end
129
130
  end
130
131
  end
131
-
132
132
  end
133
133
 
134
134
  describe '#after' do
@@ -206,5 +206,40 @@ describe DataMapper::Model::Hook do
206
206
  end
207
207
  end
208
208
  end
209
+
210
+ describe 'with an inherited hook' do
211
+ supported_by :all do
212
+ before do
213
+ @hooks = hooks = []
214
+ ModelHookSpecs.after(:an_instance_method) { hooks << :inherited_hook }
215
+ end
216
+
217
+ it 'should execute inherited hook' do
218
+ ModelHookSpecsSubclass.new.an_instance_method
219
+ @hooks.should == [ :inherited_hook ]
220
+ end
221
+ end
222
+ end
223
+
224
+ describe 'with a hook declared in the subclasss' do
225
+ supported_by :all do
226
+ before do
227
+ @hooks = hooks = []
228
+ ModelHookSpecsSubclass.after(:an_instance_method) { hooks << :hook }
229
+ end
230
+
231
+ it 'should execute hook' do
232
+ ModelHookSpecsSubclass.new.an_instance_method
233
+ @hooks.should == [ :hook ]
234
+ end
235
+
236
+ it 'should not alter hooks in the parent class' do
237
+ @hooks.should be_empty
238
+ ModelHookSpecs.new.an_instance_method
239
+ @hooks.should == []
240
+ end
241
+ end
242
+ end
243
+
209
244
  end
210
245
  end
@@ -172,7 +172,9 @@ describe DataMapper::Resource do
172
172
  end
173
173
 
174
174
  it 'should raise an exception' do
175
- method(:subject).should raise_error(DataMapper::SaveFailureError, "Blog::User##{method} returned false, Blog::User was not saved")
175
+ method(:subject).should raise_error(DataMapper::SaveFailureError, "Blog::User##{method} returned false, Blog::User was not saved") { |error|
176
+ error.resource.should equal(@user)
177
+ }
176
178
  end
177
179
  end
178
180
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-core
3
3
  version: !ruby/object:Gem::Version
4
- hash: 977940572
5
- prerelease: true
4
+ hash: 23
5
+ prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
9
  - 0
10
- - rc3
11
- version: 1.0.0.rc3
10
+ version: 1.0.0
12
11
  platform: ruby
13
12
  authors:
14
13
  - Dan Kubb
@@ -16,7 +15,7 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2010-05-27 00:00:00 -07:00
18
+ date: 2010-06-08 00:00:00 -07:00
20
19
  default_executable:
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
@@ -305,14 +304,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
305
304
  required_rubygems_version: !ruby/object:Gem::Requirement
306
305
  none: false
307
306
  requirements:
308
- - - ">"
307
+ - - ">="
309
308
  - !ruby/object:Gem::Version
310
- hash: 25
309
+ hash: 3
311
310
  segments:
312
- - 1
313
- - 3
314
- - 1
315
- version: 1.3.1
311
+ - 0
312
+ version: "0"
316
313
  requirements: []
317
314
 
318
315
  rubyforge_project: datamapper