ghost_dm-core 1.3.0.beta
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/.autotest +29 -0
- data/.document +5 -0
- data/.gitignore +35 -0
- data/.yardopts +1 -0
- data/Gemfile +65 -0
- data/LICENSE +20 -0
- data/README.md +269 -0
- data/Rakefile +4 -0
- data/dm-core.gemspec +24 -0
- data/lib/dm-core.rb +292 -0
- data/lib/dm-core/adapters.rb +222 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +237 -0
- data/lib/dm-core/adapters/in_memory_adapter.rb +113 -0
- data/lib/dm-core/associations/many_to_many.rb +499 -0
- data/lib/dm-core/associations/many_to_one.rb +290 -0
- data/lib/dm-core/associations/one_to_many.rb +348 -0
- data/lib/dm-core/associations/one_to_one.rb +86 -0
- data/lib/dm-core/associations/relationship.rb +663 -0
- data/lib/dm-core/backwards.rb +13 -0
- data/lib/dm-core/collection.rb +1515 -0
- data/lib/dm-core/core_ext/kernel.rb +23 -0
- data/lib/dm-core/core_ext/pathname.rb +6 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +7 -0
- data/lib/dm-core/model.rb +874 -0
- data/lib/dm-core/model/hook.rb +103 -0
- data/lib/dm-core/model/is.rb +32 -0
- data/lib/dm-core/model/property.rb +249 -0
- data/lib/dm-core/model/relationship.rb +378 -0
- data/lib/dm-core/model/scope.rb +89 -0
- data/lib/dm-core/property.rb +866 -0
- data/lib/dm-core/property/binary.rb +21 -0
- data/lib/dm-core/property/boolean.rb +20 -0
- data/lib/dm-core/property/class.rb +17 -0
- data/lib/dm-core/property/date.rb +10 -0
- data/lib/dm-core/property/date_time.rb +10 -0
- data/lib/dm-core/property/decimal.rb +36 -0
- data/lib/dm-core/property/discriminator.rb +44 -0
- data/lib/dm-core/property/float.rb +16 -0
- data/lib/dm-core/property/integer.rb +22 -0
- data/lib/dm-core/property/invalid_value_error.rb +22 -0
- data/lib/dm-core/property/lookup.rb +27 -0
- data/lib/dm-core/property/numeric.rb +38 -0
- data/lib/dm-core/property/object.rb +34 -0
- data/lib/dm-core/property/serial.rb +14 -0
- data/lib/dm-core/property/string.rb +38 -0
- data/lib/dm-core/property/text.rb +9 -0
- data/lib/dm-core/property/time.rb +10 -0
- data/lib/dm-core/property_set.rb +177 -0
- data/lib/dm-core/query.rb +1366 -0
- data/lib/dm-core/query/conditions/comparison.rb +911 -0
- data/lib/dm-core/query/conditions/operation.rb +721 -0
- data/lib/dm-core/query/direction.rb +36 -0
- data/lib/dm-core/query/operator.rb +35 -0
- data/lib/dm-core/query/path.rb +114 -0
- data/lib/dm-core/query/sort.rb +39 -0
- data/lib/dm-core/relationship_set.rb +72 -0
- data/lib/dm-core/repository.rb +226 -0
- data/lib/dm-core/resource.rb +1214 -0
- data/lib/dm-core/resource/persistence_state.rb +75 -0
- data/lib/dm-core/resource/persistence_state/clean.rb +40 -0
- data/lib/dm-core/resource/persistence_state/deleted.rb +30 -0
- data/lib/dm-core/resource/persistence_state/dirty.rb +96 -0
- data/lib/dm-core/resource/persistence_state/immutable.rb +34 -0
- data/lib/dm-core/resource/persistence_state/persisted.rb +29 -0
- data/lib/dm-core/resource/persistence_state/transient.rb +80 -0
- data/lib/dm-core/spec/lib/adapter_helpers.rb +64 -0
- data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
- data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
- data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
- data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
- data/lib/dm-core/spec/setup.rb +174 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +341 -0
- data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +1232 -0
- data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
- data/lib/dm-core/spec/shared/semipublic/property_spec.rb +176 -0
- data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
- data/lib/dm-core/support/assertions.rb +8 -0
- data/lib/dm-core/support/chainable.rb +18 -0
- data/lib/dm-core/support/deprecate.rb +12 -0
- data/lib/dm-core/support/descendant_set.rb +89 -0
- data/lib/dm-core/support/equalizer.rb +48 -0
- data/lib/dm-core/support/ext/array.rb +22 -0
- data/lib/dm-core/support/ext/blank.rb +25 -0
- data/lib/dm-core/support/ext/hash.rb +67 -0
- data/lib/dm-core/support/ext/module.rb +47 -0
- data/lib/dm-core/support/ext/object.rb +57 -0
- data/lib/dm-core/support/ext/string.rb +24 -0
- data/lib/dm-core/support/ext/try_dup.rb +12 -0
- data/lib/dm-core/support/hook.rb +405 -0
- data/lib/dm-core/support/inflections.rb +60 -0
- data/lib/dm-core/support/inflector/inflections.rb +211 -0
- data/lib/dm-core/support/inflector/methods.rb +151 -0
- data/lib/dm-core/support/lazy_array.rb +451 -0
- data/lib/dm-core/support/local_object_space.rb +13 -0
- data/lib/dm-core/support/logger.rb +201 -0
- data/lib/dm-core/support/mash.rb +176 -0
- data/lib/dm-core/support/naming_conventions.rb +90 -0
- data/lib/dm-core/support/ordered_set.rb +380 -0
- data/lib/dm-core/support/subject.rb +33 -0
- data/lib/dm-core/support/subject_set.rb +250 -0
- data/lib/dm-core/version.rb +3 -0
- data/script/performance.rb +275 -0
- data/script/profile.rb +218 -0
- data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
- data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +68 -0
- data/spec/public/associations/many_to_many_spec.rb +197 -0
- data/spec/public/associations/many_to_one_spec.rb +83 -0
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
- data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
- data/spec/public/associations/one_to_many_spec.rb +81 -0
- data/spec/public/associations/one_to_one_spec.rb +176 -0
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
- data/spec/public/collection_spec.rb +69 -0
- data/spec/public/finalize_spec.rb +76 -0
- data/spec/public/model/hook_spec.rb +246 -0
- data/spec/public/model/property_spec.rb +88 -0
- data/spec/public/model/relationship_spec.rb +1040 -0
- data/spec/public/model_spec.rb +462 -0
- data/spec/public/property/binary_spec.rb +41 -0
- data/spec/public/property/boolean_spec.rb +22 -0
- data/spec/public/property/class_spec.rb +28 -0
- data/spec/public/property/date_spec.rb +22 -0
- data/spec/public/property/date_time_spec.rb +22 -0
- data/spec/public/property/decimal_spec.rb +23 -0
- data/spec/public/property/discriminator_spec.rb +135 -0
- data/spec/public/property/float_spec.rb +22 -0
- data/spec/public/property/integer_spec.rb +22 -0
- data/spec/public/property/object_spec.rb +107 -0
- data/spec/public/property/serial_spec.rb +22 -0
- data/spec/public/property/string_spec.rb +22 -0
- data/spec/public/property/text_spec.rb +63 -0
- data/spec/public/property/time_spec.rb +22 -0
- data/spec/public/property_spec.rb +341 -0
- data/spec/public/resource_spec.rb +288 -0
- data/spec/public/sel_spec.rb +53 -0
- data/spec/public/setup_spec.rb +145 -0
- data/spec/public/shared/association_collection_shared_spec.rb +309 -0
- data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
- data/spec/public/shared/collection_shared_spec.rb +1667 -0
- data/spec/public/shared/finder_shared_spec.rb +1629 -0
- data/spec/rcov.opts +6 -0
- data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
- data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
- data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
- data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
- data/spec/semipublic/associations/relationship_spec.rb +200 -0
- data/spec/semipublic/associations_spec.rb +177 -0
- data/spec/semipublic/collection_spec.rb +110 -0
- data/spec/semipublic/model_spec.rb +96 -0
- data/spec/semipublic/property/binary_spec.rb +13 -0
- data/spec/semipublic/property/boolean_spec.rb +47 -0
- data/spec/semipublic/property/class_spec.rb +33 -0
- data/spec/semipublic/property/date_spec.rb +43 -0
- data/spec/semipublic/property/date_time_spec.rb +46 -0
- data/spec/semipublic/property/decimal_spec.rb +83 -0
- data/spec/semipublic/property/discriminator_spec.rb +19 -0
- data/spec/semipublic/property/float_spec.rb +82 -0
- data/spec/semipublic/property/integer_spec.rb +82 -0
- data/spec/semipublic/property/lookup_spec.rb +29 -0
- data/spec/semipublic/property/serial_spec.rb +13 -0
- data/spec/semipublic/property/string_spec.rb +13 -0
- data/spec/semipublic/property/text_spec.rb +31 -0
- data/spec/semipublic/property/time_spec.rb +50 -0
- data/spec/semipublic/property_spec.rb +114 -0
- data/spec/semipublic/query/conditions/comparison_spec.rb +1501 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1294 -0
- data/spec/semipublic/query/path_spec.rb +471 -0
- data/spec/semipublic/query_spec.rb +3682 -0
- data/spec/semipublic/resource/state/clean_spec.rb +88 -0
- data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
- data/spec/semipublic/resource/state/dirty_spec.rb +162 -0
- data/spec/semipublic/resource/state/immutable_spec.rb +105 -0
- data/spec/semipublic/resource/state/transient_spec.rb +162 -0
- data/spec/semipublic/resource/state_spec.rb +230 -0
- data/spec/semipublic/resource_spec.rb +23 -0
- data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +199 -0
- data/spec/semipublic/shared/resource_state_shared_spec.rb +79 -0
- data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/core_ext/hash.rb +10 -0
- data/spec/support/core_ext/inheritable_attributes.rb +46 -0
- data/spec/support/properties/huge_integer.rb +17 -0
- data/spec/unit/array_spec.rb +23 -0
- data/spec/unit/blank_spec.rb +73 -0
- data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
- data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
- data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
- data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
- data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
- data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
- data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
- data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
- data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
- data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
- data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
- data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
- data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
- data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
- data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
- data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
- data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
- data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
- data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
- data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
- data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
- data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
- data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
- data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
- data/spec/unit/hash_spec.rb +28 -0
- data/spec/unit/hook_spec.rb +1235 -0
- data/spec/unit/inflections_spec.rb +16 -0
- data/spec/unit/lazy_array_spec.rb +1949 -0
- data/spec/unit/mash_spec.rb +312 -0
- data/spec/unit/module_spec.rb +71 -0
- data/spec/unit/object_spec.rb +38 -0
- data/spec/unit/try_dup_spec.rb +46 -0
- data/tasks/ci.rake +1 -0
- data/tasks/spec.rake +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +365 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
# TODO: move these specs into shared specs for #copy
|
|
4
|
+
describe DataMapper::Model do
|
|
5
|
+
before :all do
|
|
6
|
+
module ::Blog
|
|
7
|
+
class Article
|
|
8
|
+
include DataMapper::Resource
|
|
9
|
+
|
|
10
|
+
property :id, Serial
|
|
11
|
+
property :title, String, :required => true
|
|
12
|
+
property :content, Text, :writer => :private, :default => lambda { |resource, property| resource.title }
|
|
13
|
+
property :subtitle, String
|
|
14
|
+
property :author, String, :required => true
|
|
15
|
+
|
|
16
|
+
belongs_to :original, self, :required => false
|
|
17
|
+
has n, :revisions, self, :child_key => [ :original_id ]
|
|
18
|
+
has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
DataMapper.finalize
|
|
22
|
+
|
|
23
|
+
@article_model = Blog::Article
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
supported_by :all do
|
|
27
|
+
before :all do
|
|
28
|
+
@author = 'Dan Kubb'
|
|
29
|
+
|
|
30
|
+
@original = @article_model.create(:title => 'Original Article', :author => @author)
|
|
31
|
+
@article = @article_model.create(:title => 'Sample Article', :original => @original, :author => @author)
|
|
32
|
+
@other = @article_model.create(:title => 'Other Article', :author => @author)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it { @article_model.should respond_to(:copy) }
|
|
36
|
+
|
|
37
|
+
describe '#copy' do
|
|
38
|
+
with_alternate_adapter do
|
|
39
|
+
before :all do
|
|
40
|
+
if @article_model.respond_to?(:auto_migrate!)
|
|
41
|
+
# force the article model to be available in the alternate repository
|
|
42
|
+
@article_model.auto_migrate!(@adapter.name)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe 'between identical models' do
|
|
47
|
+
before :all do
|
|
48
|
+
@return = @resources = @article_model.copy(@repository.name, @adapter.name)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'should return a Collection' do
|
|
52
|
+
@return.should be_a_kind_of(DataMapper::Collection)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'should return Resources' do
|
|
56
|
+
@return.each { |resource| resource.should be_a_kind_of(DataMapper::Resource) }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'should have each Resource set to the expected Repository' do
|
|
60
|
+
@resources.each { |resource| resource.repository.name.should == @adapter.name }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'should create the Resources in the expected Repository' do
|
|
64
|
+
@article_model.all(:repository => DataMapper.repository(@adapter.name)).should == @resources
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe 'between different models' do
|
|
69
|
+
before :all do
|
|
70
|
+
@other.destroy
|
|
71
|
+
@article.destroy
|
|
72
|
+
@original.destroy
|
|
73
|
+
|
|
74
|
+
# make sure the default repository is empty
|
|
75
|
+
@article_model.all(:repository => @repository).should be_empty
|
|
76
|
+
|
|
77
|
+
# add an extra property to the alternate model
|
|
78
|
+
DataMapper.repository(@adapter.name) do
|
|
79
|
+
@article_model.property :status, String, :default => 'new'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
if @article_model.respond_to?(:auto_migrate!)
|
|
83
|
+
@article_model.auto_migrate!(@adapter.name)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# add new resources to the alternate repository
|
|
87
|
+
DataMapper.repository(@adapter.name) do
|
|
88
|
+
# use an id value that is unique
|
|
89
|
+
@heff1 = @article_model.create(:id => 99, :title => 'Alternate Repository', :author => @author)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# copy from the alternate to the default repository
|
|
93
|
+
@return = @resources = @article_model.copy(@adapter.name, :default)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'should return a Collection' do
|
|
97
|
+
@return.should be_a_kind_of(DataMapper::Collection)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'should return Resources' do
|
|
101
|
+
@return.each { |resource| resource.should be_a_kind_of(DataMapper::Resource) }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'should have each Resource set to the expected Repository' do
|
|
105
|
+
@resources.each { |resource| resource.repository.name.should == :default }
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'should return the expected resources' do
|
|
109
|
+
# match on id because resources from different repositories are different
|
|
110
|
+
@resources.map { |resource| resource.id }.should == [ @heff1.id ]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'should add the resources to the alternate repository' do
|
|
114
|
+
@article.model.get(*@heff1.key).should_not be_nil
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
describe DataMapper::Model do
|
|
123
|
+
extend DataMapper::Spec::CollectionHelpers::GroupMethods
|
|
124
|
+
|
|
125
|
+
self.loaded = false
|
|
126
|
+
|
|
127
|
+
before :all do
|
|
128
|
+
module ::Blog
|
|
129
|
+
class Article
|
|
130
|
+
include DataMapper::Resource
|
|
131
|
+
|
|
132
|
+
property :id, Serial
|
|
133
|
+
property :title, String, :required => true, :default => 'Default Title'
|
|
134
|
+
property :content, Text
|
|
135
|
+
property :subtitle, String
|
|
136
|
+
|
|
137
|
+
belongs_to :original, self, :required => false
|
|
138
|
+
has n, :revisions, self, :child_key => [ :original_id ]
|
|
139
|
+
has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
|
|
140
|
+
has n, :publications, :through => Resource
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class Publication
|
|
144
|
+
include DataMapper::Resource
|
|
145
|
+
|
|
146
|
+
property :id, Serial
|
|
147
|
+
property :name, String
|
|
148
|
+
|
|
149
|
+
has n, :articles, :through => Resource
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
DataMapper.finalize
|
|
153
|
+
|
|
154
|
+
@article_model = Blog::Article
|
|
155
|
+
@publication_model = Blog::Publication
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
supported_by :all do
|
|
159
|
+
# model cannot be a kicker
|
|
160
|
+
def should_not_be_a_kicker; end
|
|
161
|
+
|
|
162
|
+
def model?; true end
|
|
163
|
+
|
|
164
|
+
before :all do
|
|
165
|
+
@articles = @article_model
|
|
166
|
+
|
|
167
|
+
@original = @articles.create(:title => 'Original Article')
|
|
168
|
+
@article = @articles.create(:title => 'Sample Article', :content => 'Sample', :original => @original)
|
|
169
|
+
@other = @articles.create(:title => 'Other Article', :content => 'Other')
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe '#new' do
|
|
173
|
+
subject { model.new(*args) }
|
|
174
|
+
|
|
175
|
+
let(:model) { @article_model }
|
|
176
|
+
|
|
177
|
+
context 'with no arguments' do
|
|
178
|
+
let(:args) { [] }
|
|
179
|
+
|
|
180
|
+
it { should be_instance_of(model) }
|
|
181
|
+
|
|
182
|
+
its(:attributes) { should == { :title => 'Default Title' } }
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context 'with an empty Hash' do
|
|
186
|
+
let(:args) { [ {} ] }
|
|
187
|
+
|
|
188
|
+
it { should be_instance_of(model) }
|
|
189
|
+
|
|
190
|
+
its(:attributes) { should == { :title => 'Default Title' } }
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
context 'with a non-empty Hash' do
|
|
194
|
+
let(:attributes) { { :title => 'A Title' } }
|
|
195
|
+
let(:args) { [ attributes ] }
|
|
196
|
+
|
|
197
|
+
it { should be_instance_of(model) }
|
|
198
|
+
|
|
199
|
+
its(:attributes) { should == attributes }
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
context 'with nil' do
|
|
203
|
+
let(:args) { [ nil ] }
|
|
204
|
+
|
|
205
|
+
it { should be_instance_of(model) }
|
|
206
|
+
|
|
207
|
+
its(:attributes) { should == { :title => 'Default Title' } }
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
[ :create, :create! ].each do |method|
|
|
212
|
+
describe "##{method}" do
|
|
213
|
+
subject { model.send(method, *args) }
|
|
214
|
+
|
|
215
|
+
let(:model) { @article_model }
|
|
216
|
+
|
|
217
|
+
context 'with no arguments' do
|
|
218
|
+
let(:args) { [] }
|
|
219
|
+
|
|
220
|
+
it { should be_instance_of(model) }
|
|
221
|
+
|
|
222
|
+
it { should be_saved }
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
context 'with an empty Hash' do
|
|
226
|
+
let(:args) { [ {} ] }
|
|
227
|
+
|
|
228
|
+
it { should be_instance_of(model) }
|
|
229
|
+
|
|
230
|
+
it { should be_saved }
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
context 'with a non-empty Hash' do
|
|
234
|
+
let(:attributes) { { :title => 'A Title' } }
|
|
235
|
+
let(:args) { [ attributes ] }
|
|
236
|
+
|
|
237
|
+
it { should be_instance_of(model) }
|
|
238
|
+
|
|
239
|
+
it { should be_saved }
|
|
240
|
+
|
|
241
|
+
its(:title) { should == attributes[:title] }
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
context 'with nil' do
|
|
245
|
+
let(:args) { [ nil ] }
|
|
246
|
+
|
|
247
|
+
it { should be_instance_of(model) }
|
|
248
|
+
|
|
249
|
+
it { should be_saved }
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
[ :destroy, :destroy! ].each do |method|
|
|
255
|
+
describe "##{method}" do
|
|
256
|
+
subject { model.send(method) }
|
|
257
|
+
|
|
258
|
+
let(:model) { @article_model }
|
|
259
|
+
|
|
260
|
+
it 'should remove all resources' do
|
|
261
|
+
method(:subject).should change { model.any? }.from(true).to(false)
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
[ :update, :update! ].each do |method|
|
|
267
|
+
describe "##{method}" do
|
|
268
|
+
subject { model.send(method, *args) }
|
|
269
|
+
|
|
270
|
+
let(:model) { @article_model }
|
|
271
|
+
|
|
272
|
+
context 'with attributes' do
|
|
273
|
+
let(:attributes) { { :title => 'Updated Title' } }
|
|
274
|
+
let(:args) { [ attributes ] }
|
|
275
|
+
|
|
276
|
+
it { should be(true) }
|
|
277
|
+
|
|
278
|
+
it 'should persist the changes' do
|
|
279
|
+
subject
|
|
280
|
+
model.all(:fields => [ :title ]).map { |resource| resource.title }.uniq.should == [ attributes[:title] ]
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
context 'with attributes where one is a parent association' do
|
|
285
|
+
let(:attributes) { { :original => @other } }
|
|
286
|
+
let(:args) { [ attributes ] }
|
|
287
|
+
|
|
288
|
+
it { should be(true) }
|
|
289
|
+
|
|
290
|
+
it 'should persist the changes' do
|
|
291
|
+
subject
|
|
292
|
+
model.all(:fields => [ :original_id ]).map { |resource| resource.original }.uniq.should == [ attributes[:original] ]
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
context 'with attributes where a required property is nil' do
|
|
297
|
+
let(:attributes) { { :title => nil } }
|
|
298
|
+
let(:args) { [ attributes ] }
|
|
299
|
+
|
|
300
|
+
it 'should raise InvalidValueError' do
|
|
301
|
+
expect { subject }.to(raise_error(DataMapper::Property::InvalidValueError) do |error|
|
|
302
|
+
error.property.should == model.title
|
|
303
|
+
end)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it_should_behave_like 'Finder Interface'
|
|
310
|
+
|
|
311
|
+
it 'DataMapper::Model should respond to raise_on_save_failure' do
|
|
312
|
+
DataMapper::Model.should respond_to(:raise_on_save_failure)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
describe '.raise_on_save_failure' do
|
|
316
|
+
subject { DataMapper::Model.raise_on_save_failure }
|
|
317
|
+
|
|
318
|
+
it { should be(false) }
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it 'DataMapper::Model should respond to raise_on_save_failure=' do
|
|
322
|
+
DataMapper::Model.should respond_to(:raise_on_save_failure=)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
describe '.raise_on_save_failure=' do
|
|
326
|
+
after do
|
|
327
|
+
# reset to the default value
|
|
328
|
+
reset_raise_on_save_failure(DataMapper::Model)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
subject { DataMapper::Model.raise_on_save_failure = @value }
|
|
332
|
+
|
|
333
|
+
describe 'with a true value' do
|
|
334
|
+
before do
|
|
335
|
+
@value = true
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
it { should be(true) }
|
|
339
|
+
|
|
340
|
+
it 'should set raise_on_save_failure' do
|
|
341
|
+
method(:subject).should change {
|
|
342
|
+
DataMapper::Model.raise_on_save_failure
|
|
343
|
+
}.from(false).to(true)
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
describe 'with a false value' do
|
|
348
|
+
before do
|
|
349
|
+
@value = false
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
it { should be(false) }
|
|
353
|
+
|
|
354
|
+
it 'should set raise_on_save_failure' do
|
|
355
|
+
method(:subject).should_not change {
|
|
356
|
+
DataMapper::Model.raise_on_save_failure
|
|
357
|
+
}
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
it 'A model should respond to raise_on_save_failure' do
|
|
363
|
+
@article_model.should respond_to(:raise_on_save_failure)
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
describe '#raise_on_save_failure' do
|
|
367
|
+
after do
|
|
368
|
+
# reset to the default value
|
|
369
|
+
reset_raise_on_save_failure(DataMapper::Model)
|
|
370
|
+
reset_raise_on_save_failure(@article_model)
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
subject { @article_model.raise_on_save_failure }
|
|
374
|
+
|
|
375
|
+
describe 'when DataMapper::Model.raise_on_save_failure has not been set' do
|
|
376
|
+
it { should be(false) }
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
describe 'when DataMapper::Model.raise_on_save_failure has been set to true' do
|
|
380
|
+
before do
|
|
381
|
+
DataMapper::Model.raise_on_save_failure = true
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it { should be(true) }
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
describe 'when model.raise_on_save_failure has been set to true' do
|
|
388
|
+
before do
|
|
389
|
+
@article_model.raise_on_save_failure = true
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it { should be(true) }
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
it 'A model should respond to raise_on_save_failure=' do
|
|
397
|
+
@article_model.should respond_to(:raise_on_save_failure=)
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
describe '#raise_on_save_failure=' do
|
|
401
|
+
after do
|
|
402
|
+
# reset to the default value
|
|
403
|
+
reset_raise_on_save_failure(@article_model)
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
subject { @article_model.raise_on_save_failure = @value }
|
|
407
|
+
|
|
408
|
+
describe 'with a true value' do
|
|
409
|
+
before do
|
|
410
|
+
@value = true
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
it { should be(true) }
|
|
414
|
+
|
|
415
|
+
it 'should set raise_on_save_failure' do
|
|
416
|
+
method(:subject).should change {
|
|
417
|
+
@article_model.raise_on_save_failure
|
|
418
|
+
}.from(false).to(true)
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
describe 'with a false value' do
|
|
423
|
+
before do
|
|
424
|
+
@value = false
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
it { should be(false) }
|
|
428
|
+
|
|
429
|
+
it 'should set raise_on_save_failure' do
|
|
430
|
+
method(:subject).should_not change {
|
|
431
|
+
@article_model.raise_on_save_failure
|
|
432
|
+
}
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
it 'A model should respond to allowed_writer_methods' do
|
|
438
|
+
@article_model.should respond_to(:allowed_writer_methods)
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
describe '#allowed_writer_methods' do
|
|
442
|
+
subject { @article_model.allowed_writer_methods }
|
|
443
|
+
|
|
444
|
+
let(:expected_writer_methods) do
|
|
445
|
+
%w[ original= revisions= previous= publications= article_publications=
|
|
446
|
+
id= title= content= subtitle= original_id= persisted_state= ].to_set
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
it { should be_kind_of(Set) }
|
|
450
|
+
|
|
451
|
+
it { should be_all { |method| method.kind_of?(String) } }
|
|
452
|
+
|
|
453
|
+
it { should be_frozen }
|
|
454
|
+
|
|
455
|
+
it 'is idempotent' do
|
|
456
|
+
should equal(instance_eval(&self.class.subject))
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
it { should eql(expected_writer_methods) }
|
|
460
|
+
end
|
|
461
|
+
end
|
|
462
|
+
end
|