datamapper-dm-core 0.9.11 → 0.10.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 (192) hide show
  1. data/.autotest +17 -14
  2. data/.gitignore +3 -1
  3. data/FAQ +6 -5
  4. data/History.txt +5 -39
  5. data/Manifest.txt +67 -76
  6. data/QUICKLINKS +1 -1
  7. data/README.txt +21 -15
  8. data/Rakefile +16 -15
  9. data/SPECS +2 -29
  10. data/TODO +1 -1
  11. data/dm-core.gemspec +11 -15
  12. data/lib/dm-core/adapters/abstract_adapter.rb +182 -185
  13. data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
  14. data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
  15. data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
  16. data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
  17. data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
  18. data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
  19. data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
  20. data/lib/dm-core/adapters.rb +135 -16
  21. data/lib/dm-core/associations/many_to_many.rb +372 -90
  22. data/lib/dm-core/associations/many_to_one.rb +220 -73
  23. data/lib/dm-core/associations/one_to_many.rb +319 -255
  24. data/lib/dm-core/associations/one_to_one.rb +66 -53
  25. data/lib/dm-core/associations/relationship.rb +560 -158
  26. data/lib/dm-core/collection.rb +1104 -381
  27. data/lib/dm-core/core_ext/kernel.rb +12 -0
  28. data/lib/dm-core/core_ext/symbol.rb +10 -0
  29. data/lib/dm-core/identity_map.rb +4 -34
  30. data/lib/dm-core/migrations.rb +1283 -0
  31. data/lib/dm-core/model/descendant_set.rb +81 -0
  32. data/lib/dm-core/model/hook.rb +45 -0
  33. data/lib/dm-core/model/is.rb +32 -0
  34. data/lib/dm-core/model/property.rb +248 -0
  35. data/lib/dm-core/model/relationship.rb +335 -0
  36. data/lib/dm-core/model/scope.rb +90 -0
  37. data/lib/dm-core/model.rb +570 -369
  38. data/lib/dm-core/property.rb +753 -280
  39. data/lib/dm-core/property_set.rb +141 -98
  40. data/lib/dm-core/query/conditions/comparison.rb +814 -0
  41. data/lib/dm-core/query/conditions/operation.rb +247 -0
  42. data/lib/dm-core/query/direction.rb +43 -0
  43. data/lib/dm-core/query/operator.rb +42 -0
  44. data/lib/dm-core/query/path.rb +102 -0
  45. data/lib/dm-core/query/sort.rb +45 -0
  46. data/lib/dm-core/query.rb +974 -492
  47. data/lib/dm-core/repository.rb +147 -107
  48. data/lib/dm-core/resource.rb +644 -429
  49. data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
  50. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
  51. data/lib/dm-core/support/chainable.rb +20 -0
  52. data/lib/dm-core/support/deprecate.rb +12 -0
  53. data/lib/dm-core/support/equalizer.rb +23 -0
  54. data/lib/dm-core/support/logger.rb +13 -0
  55. data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
  56. data/lib/dm-core/transaction.rb +333 -92
  57. data/lib/dm-core/type.rb +98 -60
  58. data/lib/dm-core/types/boolean.rb +1 -1
  59. data/lib/dm-core/types/discriminator.rb +34 -20
  60. data/lib/dm-core/types/object.rb +7 -4
  61. data/lib/dm-core/types/paranoid_boolean.rb +11 -9
  62. data/lib/dm-core/types/paranoid_datetime.rb +11 -9
  63. data/lib/dm-core/types/serial.rb +3 -3
  64. data/lib/dm-core/types/text.rb +3 -4
  65. data/lib/dm-core/version.rb +1 -1
  66. data/lib/dm-core.rb +106 -110
  67. data/script/performance.rb +102 -109
  68. data/script/profile.rb +169 -38
  69. data/spec/lib/adapter_helpers.rb +105 -0
  70. data/spec/lib/collection_helpers.rb +18 -0
  71. data/spec/lib/counter_adapter.rb +34 -0
  72. data/spec/lib/pending_helpers.rb +27 -0
  73. data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
  74. data/spec/public/associations/many_to_many_spec.rb +193 -0
  75. data/spec/public/associations/many_to_one_spec.rb +73 -0
  76. data/spec/public/associations/one_to_many_spec.rb +77 -0
  77. data/spec/public/associations/one_to_one_spec.rb +156 -0
  78. data/spec/public/collection_spec.rb +65 -0
  79. data/spec/public/model/relationship_spec.rb +924 -0
  80. data/spec/public/model_spec.rb +159 -0
  81. data/spec/public/property_spec.rb +829 -0
  82. data/spec/public/resource_spec.rb +71 -0
  83. data/spec/public/sel_spec.rb +44 -0
  84. data/spec/public/setup_spec.rb +145 -0
  85. data/spec/public/shared/association_collection_shared_spec.rb +317 -0
  86. data/spec/public/shared/collection_shared_spec.rb +1723 -0
  87. data/spec/public/shared/finder_shared_spec.rb +1619 -0
  88. data/spec/public/shared/resource_shared_spec.rb +924 -0
  89. data/spec/public/shared/sel_shared_spec.rb +112 -0
  90. data/spec/public/transaction_spec.rb +129 -0
  91. data/spec/public/types/discriminator_spec.rb +130 -0
  92. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  93. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
  94. data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
  95. data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
  96. data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
  97. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
  98. data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
  99. data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
  100. data/spec/semipublic/associations/relationship_spec.rb +194 -0
  101. data/spec/semipublic/associations_spec.rb +177 -0
  102. data/spec/semipublic/collection_spec.rb +142 -0
  103. data/spec/semipublic/property_spec.rb +61 -0
  104. data/spec/semipublic/query/conditions_spec.rb +528 -0
  105. data/spec/semipublic/query/path_spec.rb +443 -0
  106. data/spec/semipublic/query_spec.rb +2626 -0
  107. data/spec/semipublic/resource_spec.rb +47 -0
  108. data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
  109. data/spec/spec.opts +3 -1
  110. data/spec/spec_helper.rb +80 -57
  111. data/tasks/ci.rb +19 -31
  112. data/tasks/dm.rb +43 -48
  113. data/tasks/doc.rb +8 -11
  114. data/tasks/gemspec.rb +5 -5
  115. data/tasks/hoe.rb +15 -16
  116. data/tasks/install.rb +8 -10
  117. metadata +72 -93
  118. data/lib/dm-core/associations/relationship_chain.rb +0 -81
  119. data/lib/dm-core/associations.rb +0 -207
  120. data/lib/dm-core/auto_migrations.rb +0 -105
  121. data/lib/dm-core/dependency_queue.rb +0 -32
  122. data/lib/dm-core/hook.rb +0 -11
  123. data/lib/dm-core/is.rb +0 -16
  124. data/lib/dm-core/logger.rb +0 -232
  125. data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
  126. data/lib/dm-core/migrator.rb +0 -29
  127. data/lib/dm-core/scope.rb +0 -58
  128. data/lib/dm-core/support/array.rb +0 -13
  129. data/lib/dm-core/support/assertions.rb +0 -8
  130. data/lib/dm-core/support/errors.rb +0 -23
  131. data/lib/dm-core/support/kernel.rb +0 -11
  132. data/lib/dm-core/support/symbol.rb +0 -41
  133. data/lib/dm-core/support.rb +0 -7
  134. data/lib/dm-core/type_map.rb +0 -80
  135. data/lib/dm-core/types.rb +0 -19
  136. data/script/all +0 -4
  137. data/spec/integration/association_spec.rb +0 -1382
  138. data/spec/integration/association_through_spec.rb +0 -203
  139. data/spec/integration/associations/many_to_many_spec.rb +0 -449
  140. data/spec/integration/associations/many_to_one_spec.rb +0 -163
  141. data/spec/integration/associations/one_to_many_spec.rb +0 -188
  142. data/spec/integration/auto_migrations_spec.rb +0 -413
  143. data/spec/integration/collection_spec.rb +0 -1073
  144. data/spec/integration/data_objects_adapter_spec.rb +0 -32
  145. data/spec/integration/dependency_queue_spec.rb +0 -46
  146. data/spec/integration/model_spec.rb +0 -197
  147. data/spec/integration/mysql_adapter_spec.rb +0 -85
  148. data/spec/integration/postgres_adapter_spec.rb +0 -731
  149. data/spec/integration/property_spec.rb +0 -253
  150. data/spec/integration/query_spec.rb +0 -514
  151. data/spec/integration/repository_spec.rb +0 -61
  152. data/spec/integration/resource_spec.rb +0 -513
  153. data/spec/integration/sqlite3_adapter_spec.rb +0 -352
  154. data/spec/integration/sti_spec.rb +0 -273
  155. data/spec/integration/strategic_eager_loading_spec.rb +0 -156
  156. data/spec/integration/transaction_spec.rb +0 -75
  157. data/spec/integration/type_spec.rb +0 -275
  158. data/spec/lib/logging_helper.rb +0 -18
  159. data/spec/lib/mock_adapter.rb +0 -27
  160. data/spec/lib/model_loader.rb +0 -100
  161. data/spec/lib/publicize_methods.rb +0 -28
  162. data/spec/models/content.rb +0 -16
  163. data/spec/models/vehicles.rb +0 -34
  164. data/spec/models/zoo.rb +0 -48
  165. data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
  166. data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
  167. data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
  168. data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
  169. data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
  170. data/spec/unit/associations/many_to_many_spec.rb +0 -32
  171. data/spec/unit/associations/many_to_one_spec.rb +0 -159
  172. data/spec/unit/associations/one_to_many_spec.rb +0 -393
  173. data/spec/unit/associations/one_to_one_spec.rb +0 -7
  174. data/spec/unit/associations/relationship_spec.rb +0 -71
  175. data/spec/unit/associations_spec.rb +0 -242
  176. data/spec/unit/auto_migrations_spec.rb +0 -111
  177. data/spec/unit/collection_spec.rb +0 -182
  178. data/spec/unit/data_mapper_spec.rb +0 -35
  179. data/spec/unit/identity_map_spec.rb +0 -126
  180. data/spec/unit/is_spec.rb +0 -80
  181. data/spec/unit/migrator_spec.rb +0 -33
  182. data/spec/unit/model_spec.rb +0 -321
  183. data/spec/unit/naming_conventions_spec.rb +0 -36
  184. data/spec/unit/property_set_spec.rb +0 -90
  185. data/spec/unit/property_spec.rb +0 -753
  186. data/spec/unit/query_spec.rb +0 -571
  187. data/spec/unit/repository_spec.rb +0 -93
  188. data/spec/unit/resource_spec.rb +0 -649
  189. data/spec/unit/scope_spec.rb +0 -142
  190. data/spec/unit/transaction_spec.rb +0 -493
  191. data/spec/unit/type_map_spec.rb +0 -114
  192. data/spec/unit/type_spec.rb +0 -119
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe DataMapper::Resource do
4
+ before :all do
5
+ class ::User
6
+ include DataMapper::Resource
7
+
8
+ property :name, String, :key => true
9
+ property :age, Integer
10
+ property :description, Text
11
+ end
12
+
13
+ # This is a special class that needs to be an exact copy of User
14
+ class ::Clone
15
+ include DataMapper::Resource
16
+
17
+ property :name, String, :key => true
18
+ property :age, Integer
19
+ property :description, Text
20
+ end
21
+
22
+ class ::Comment
23
+ include DataMapper::Resource
24
+
25
+ property :id, Serial
26
+ property :body, Text
27
+
28
+ belongs_to :user
29
+ end
30
+
31
+ class ::Default
32
+ include DataMapper::Resource
33
+
34
+ property :name, String, :key => true, :default => 'a default value'
35
+ end
36
+
37
+ @user_model = User
38
+ end
39
+
40
+ supported_by :all do
41
+ before :all do
42
+ @user = @user_model.create(:name => 'dbussink', :age => 25, :description => "Test")
43
+ end
44
+
45
+ it_should_behave_like 'A semipublic Resource'
46
+ end
47
+ end
@@ -0,0 +1,126 @@
1
+ share_examples_for 'A semipublic Resource' do
2
+ before :all do
3
+ %w[ @user_model @user ].each do |ivar|
4
+ raise "+#{ivar}+ should be defined in before block" unless instance_variable_get(ivar)
5
+ end
6
+ end
7
+
8
+ it { @user.should respond_to(:dirty?) }
9
+
10
+ describe '#dirty?' do
11
+
12
+ describe 'on a non-dirty record' do
13
+
14
+ it { @user.should_not be_dirty }
15
+
16
+ end
17
+
18
+ describe 'on a dirty record' do
19
+
20
+ before { @user.age = 100 }
21
+
22
+ it { @user.should be_dirty }
23
+
24
+ end
25
+
26
+ describe 'on a new record, with no attributes, no default attributes, and no identity field' do
27
+
28
+ before { @user = @user_model.new }
29
+
30
+ it { @user.should_not be_dirty }
31
+
32
+ end
33
+
34
+ describe 'on a new record, with no attributes, no default attributes, and an identity field' do
35
+
36
+ before { @comment = Comment.new }
37
+
38
+ it { @comment.should be_dirty }
39
+
40
+ end
41
+
42
+ describe 'on a new record, with no attributes, default attributes, and no identity field' do
43
+
44
+ before { @default = Default.new }
45
+
46
+ it { @default.should be_dirty }
47
+
48
+ end
49
+
50
+
51
+ end
52
+
53
+ it { @user.should respond_to(:attribute_dirty?) }
54
+
55
+ describe '#attribute_dirty?' do
56
+
57
+ describe 'on a non-dirty record' do
58
+
59
+ it { @user.attribute_dirty?(:age).should be_false }
60
+
61
+ end
62
+
63
+ describe 'on a dirty record' do
64
+
65
+ before { @user.age = 100 }
66
+
67
+ it { @user.attribute_dirty?(:age).should be_true }
68
+
69
+ end
70
+
71
+ describe 'on a new record' do
72
+
73
+ before { @user = @user_model.new }
74
+
75
+ it { @user.attribute_dirty?(:age).should be_false }
76
+
77
+ end
78
+
79
+ end
80
+
81
+ it { @user.should respond_to(:repository) }
82
+
83
+ describe "#repository" do
84
+
85
+ before :all do
86
+ class ::Statistic
87
+ include DataMapper::Resource
88
+
89
+ def self.default_repository_name
90
+ :alternate
91
+ end
92
+
93
+ property :id, Serial
94
+ property :name, String
95
+ property :value, Integer
96
+ end
97
+ end
98
+
99
+ with_alternate_adapter do
100
+ it "should return the default adapter when nothing is specified" do
101
+ @user_model.create(:name => "carl").repository.should == @repository
102
+ @user_model.new.repository.should == @repository
103
+ @user_model.get("carl").repository.should == @repository
104
+ end
105
+
106
+ it "should return the default repository for the model" do
107
+ statistic = Statistic.create(:name => "visits", :value => 2)
108
+ statistic.repository.should == @alternate_repository
109
+ Statistic.new.repository.should == @alternate_repository
110
+ Statistic.get(statistic.id).repository.should == @alternate_repository
111
+ end
112
+
113
+ it "should return the repository defined by the current context" do
114
+ @alternate_repository.scope do
115
+ @user_model.new.repository.should == @alternate_repository
116
+ @user_model.create(:name => "carl").repository.should == @alternate_repository
117
+ @user_model.get("carl").repository.should == @alternate_repository
118
+ end
119
+
120
+ @alternate_repository.scope { @user_model.get("carl") }.repository.should == @alternate_repository
121
+ end
122
+ end
123
+
124
+ end
125
+
126
+ end
data/spec/spec.opts CHANGED
@@ -1,3 +1,5 @@
1
1
  --colour
2
2
  --loadby random
3
- --format progress
3
+ --require spec/lib/rspec_immediate_feedback_formatter.rb
4
+ --format Spec::Runner::Formatter::ImmediateFeedbackFormatter
5
+ --backtrace
data/spec/spec_helper.rb CHANGED
@@ -1,23 +1,52 @@
1
1
  require 'pathname'
2
2
  require 'rubygems'
3
3
 
4
- gem 'rspec', '~>1.2'
4
+ gem 'addressable', '~>2.0'
5
+ gem 'rspec', '>1.1.2'
6
+
7
+ require 'addressable/uri'
5
8
  require 'spec'
6
9
 
7
10
  SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
8
- require SPEC_ROOT.parent + 'lib/dm-core'
11
+ $LOAD_PATH.unshift(SPEC_ROOT.parent + 'lib')
12
+
13
+ require 'dm-core'
9
14
 
10
- # Load the various helpers for the spec suite
11
- Dir[(DataMapper.root / 'spec' / 'lib' / '*.rb').to_s].each do |file|
12
- require file
15
+ ENV['PLUGINS'].to_s.strip.split(/\s+/).each do |plugin|
16
+ require plugin
13
17
  end
14
18
 
15
- # setup mock adapters
16
- DataMapper.setup(:default2, "sqlite3::memory:")
19
+ Pathname.glob((SPEC_ROOT + '{lib,*/shared}/**/*.rb').to_s).each { |file| require file }
17
20
 
18
- [ :mock, :legacy, :west_coast, :east_coast ].each do |repository_name|
19
- DataMapper.setup(repository_name, "mock://localhost/#{repository_name}")
20
- end
21
+ # create sqlite3_fs directory if it doesn't exist
22
+ temp_db_dir = SPEC_ROOT.join('db')
23
+ temp_db_dir.mkpath
24
+
25
+ ENV['ADAPTERS'] ||= 'all'
26
+
27
+ HAS_DO = DataMapper::Adapters.const_defined?('DataObjectsAdapter')
28
+
29
+ ADAPTERS = []
30
+
31
+ PRIMARY = {
32
+ 'in_memory' => { :adapter => :in_memory },
33
+ 'yaml' => "yaml://#{temp_db_dir}/primary_yaml",
34
+ 'sqlite3' => 'sqlite3::memory:',
35
+ # 'sqlite3_fs' => "sqlite3://#{temp_db_dir}/primary.db",
36
+ 'mysql' => 'mysql://localhost/dm_core_test',
37
+ 'postgres' => 'postgres://localhost/dm_core_test',
38
+ 'oracle' => 'oracle://dm_core_test:dm_core_test@localhost/orcl'
39
+ }
40
+
41
+ ALTERNATE = {
42
+ 'in_memory' => { :adapter => :in_memory },
43
+ 'yaml' => "yaml://#{temp_db_dir}/secondary_yaml",
44
+ 'sqlite3' => "sqlite3://#{temp_db_dir}/alternate.db", # use a FS for the alternate because there can only be one memory db at a time in SQLite3
45
+ # 'sqlite3_fs' => "sqlite3://#{temp_db_dir}/alternate.db",
46
+ 'mysql' => 'mysql://localhost/dm_core_test2',
47
+ 'postgres' => 'postgres://localhost/dm_core_test2',
48
+ 'oracle' => 'oracle://dm_core_test2:dm_core_test2@localhost/orcl'
49
+ }
21
50
 
22
51
  # These environment variables will override the default connection string:
23
52
  # MYSQL_SPEC_URI
@@ -26,66 +55,60 @@ end
26
55
  #
27
56
  # For example, in the bash shell, you might use:
28
57
  # export MYSQL_SPEC_URI="mysql://localhost/dm_core_test?socket=/opt/local/var/run/mysql5/mysqld.sock"
29
- #
30
- def setup_adapter(name, default_uri)
58
+
59
+ adapters = ENV['ADAPTERS'].split(' ').map { |adapter_name| adapter_name.strip.downcase }.uniq
60
+ adapters = PRIMARY.keys if adapters.include?('all')
61
+
62
+ PRIMARY.only(*adapters).each do |name, default|
63
+ connection_string = ENV["#{name.upcase}_SPEC_URI"] || default
31
64
  begin
32
- adapter = DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
65
+ adapter = DataMapper.setup(name.to_sym, connection_string)
33
66
 
34
- if name.to_s == ENV['ADAPTER']
35
- Object.const_set('ADAPTER', ENV['ADAPTER'].to_sym)
36
- DataMapper::Repository.adapters[:default] = adapter
67
+ # test the connection if possible
68
+ if adapter.respond_to?(:query)
69
+ name == 'oracle' ? adapter.query('SELECT 1 FROM dual') : adapter.query('SELECT 1')
37
70
  end
38
71
 
39
- true
40
- rescue Exception => e
41
- if name.to_s == ENV['ADAPTER']
42
- Object.const_set('ADAPTER', nil)
43
- warn "Could not load #{name} adapter: #{e}"
44
- end
45
- false
72
+ ADAPTERS << name
73
+ PRIMARY[name] = connection_string # ensure *_SPEC_URI is saved
74
+ rescue Exception => exception
75
+ puts "Could not connect to the database using #{connection_string.inspect} because: #{exception.inspect}"
46
76
  end
47
77
  end
48
78
 
49
- ENV['ADAPTER'] ||= 'sqlite3'
50
-
51
- HAS_SQLITE3 = setup_adapter(:sqlite3, 'sqlite3::memory:')
52
- HAS_MYSQL = setup_adapter(:mysql, 'mysql://localhost/dm_core_test')
53
- HAS_POSTGRES = setup_adapter(:postgres, 'postgres://postgres@localhost/dm_core_test')
54
-
55
- DataMapper::Logger.new(nil, :debug)
56
-
57
- # ----------------------------------------------------------------------
58
- # --- Do not declare new models unless absolutely necessary. Instead ---
59
- # --- pick a metaphor and use those models. If you do need new ---
60
- # --- models, define them according to the metaphor being used. ---
61
- # ----------------------------------------------------------------------
62
-
63
- Spec::Runner.configure do |config|
64
- config.before(:each) do
65
- # load_models_for_metaphor :vehicles
79
+ # speed up test execution on Oracle
80
+ if defined?(DataMapper::Adapters::OracleAdapter)
81
+ DataMapper::Adapters::OracleAdapter.instance_eval do
82
+ auto_migrate_with :delete # table data will be deleted instead of dropping and creating table
83
+ auto_migrate_reset_sequences false # primary key sequences will not be reset
66
84
  end
67
85
  end
68
86
 
69
- # ----------------------------------------------------------------------
70
- # --- All these models are going to be removed. Don't use them!!! ---
71
- # ----------------------------------------------------------------------
87
+ ADAPTERS.freeze
88
+ PRIMARY.freeze
72
89
 
73
- class Article
74
- include DataMapper::Resource
90
+ logger = DataMapper::Logger.new(DataMapper.root / 'log' / 'dm.log', :debug)
91
+ logger.auto_flush = true
75
92
 
76
- property :id, Serial
77
- property :blog_id, Integer
78
- property :created_at, DateTime
79
- property :author, String
80
- property :title, String
81
- end
93
+ Spec::Runner.configure do |config|
94
+ config.extend(DataMapper::Spec::AdapterHelpers)
95
+ config.include(DataMapper::Spec::PendingHelpers)
82
96
 
83
- class Comment
84
- include DataMapper::Resource
97
+ config.after :all do
98
+ # global model cleanup
99
+ descendants = DataMapper::Model.descendants.to_a
100
+ while model = descendants.shift
101
+ descendants.concat(model.descendants.to_a - [ model ])
85
102
 
86
- property :id, Serial # blah
87
- end
103
+ parts = model.name.split('::')
104
+ constant_name = parts.pop.to_sym
105
+ base = parts.empty? ? Object : Object.full_const_get(parts.join('::'))
106
+
107
+ if base.const_defined?(constant_name)
108
+ base.send(:remove_const, constant_name)
109
+ end
88
110
 
89
- class NormalClass
90
- # should not include DataMapper::Resource
111
+ DataMapper::Model.descendants.delete(model)
112
+ end
113
+ end
91
114
  end
data/tasks/ci.rb CHANGED
@@ -1,36 +1,24 @@
1
- task 'ci:doc' => :doc
1
+ desc 'Run metric_fu'
2
+ task :ci do
3
+ # sudo gem install jscruggs-metric_fu -s http://gems.github.com
4
+ require 'metric_fu'
2
5
 
3
- namespace :ci do
6
+ MetricFu::Configuration.run do |config|
7
+ specs = Pathname.glob(ENV['FILES'] || (ROOT + 'spec/**/*_spec.rb').to_s).sort.map { |file| file.to_s }
4
8
 
5
- task :prepare do
6
- rm_rf ROOT + "ci"
7
- mkdir_p ROOT + "ci"
8
- mkdir_p ROOT + "ci/doc"
9
- mkdir_p ROOT + "ci/cyclomatic"
10
- mkdir_p ROOT + "ci/token"
11
- end
12
-
13
- Spec::Rake::SpecTask.new(:spec => :prepare) do |t|
14
- t.spec_opts = ["--colour", "--format", "specdoc", "--format", "html:#{ROOT}/ci/rspec_report.html", "--diff"]
15
- t.spec_files = Pathname.glob((ROOT + 'spec/**/*_spec.rb').to_s)
16
- unless ENV['NO_RCOV']
17
- t.rcov = true
18
- t.rcov_opts << '--exclude' << "spec,gems"
19
- t.rcov_opts << '--text-summary'
20
- t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
21
- t.rcov_opts << '--only-uncovered'
22
- end
23
- end
24
-
25
- task :saikuro => :prepare do
26
- system "saikuro -c -i lib -y 0 -w 10 -e 15 -o ci/cyclomatic"
27
- mv 'ci/cyclomatic/index_cyclo.html', 'ci/cyclomatic/index.html'
28
-
29
- system "saikuro -t -i lib -y 0 -w 20 -e 30 -o ci/token"
30
- mv 'ci/token/index_token.html', 'ci/token/index.html'
9
+ config.rcov = {
10
+ :test_files => specs,
11
+ :rcov_opts => [
12
+ '--sort coverage',
13
+ '--no-html',
14
+ '--text-coverage',
15
+ '--no-color',
16
+ '--profile',
17
+ '--exclude spec',
18
+ "`which spec` -- #{specs.join(' ')}",
19
+ ],
20
+ }
31
21
  end
32
22
 
23
+ Rake::Task['metrics:all'].invoke
33
24
  end
34
-
35
- #task :ci => %w[ ci:spec ci:doc ci:saikuro install ci:publish ] # yard-related tasks do not work yet
36
- task :ci => %w[ ci:spec ]
data/tasks/dm.rb CHANGED
@@ -1,63 +1,58 @@
1
- task :default => 'dm:spec'
2
- task :spec => 'dm:spec'
3
- task :rcov => 'dm:rcov'
1
+ require 'spec/rake/spectask'
2
+ require 'spec/rake/verify_rcov'
4
3
 
5
- namespace :spec do
6
- task :unit => 'dm:spec:unit'
7
- task :integration => 'dm:spec:integration'
8
- end
4
+ task :default => 'spec'
9
5
 
10
- namespace :rcov do
11
- task :unit => 'dm:rcov:unit'
12
- task :integration => 'dm:rcov:integration'
6
+ RCov::VerifyTask.new(:verify_rcov => :rcov) do |config|
7
+ config.threshold = 88.1 # Make sure you have rcov 0.7 or higher!
13
8
  end
14
9
 
15
- namespace :dm do
16
- def run_spec(name, files, rcov)
17
- Spec::Rake::SpecTask.new(name) do |t|
18
- t.spec_opts << '--colour' << '--loadby' << 'random'
19
- t.spec_files = Pathname.glob(ENV['FILES'] || files.to_s).map { |f| f.to_s }
20
- t.rcov = rcov
21
- t.rcov_opts << '--exclude' << 'spec,environment.rb'
22
- t.rcov_opts << '--text-summary'
23
- t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
24
- t.rcov_opts << '--only-uncovered'
25
- end
10
+ def run_spec(name, files, rcov)
11
+ Spec::Rake::SpecTask.new(name) do |config|
12
+ config.spec_opts << '--options' << ROOT + 'spec/spec.opts'
13
+ config.spec_files = Pathname.glob(ENV['FILES'] || files.to_s).map { |file| file.to_s }
14
+ config.rcov = rcov
15
+ config.rcov_opts << '--exclude' << 'spec'
16
+ config.rcov_opts << '--text-summary'
17
+ config.rcov_opts << '--sort' << 'coverage'
18
+ config.rcov_opts << '--only-uncovered'
19
+ config.rcov_opts << '--profile'
20
+ #config.rcov_opts << '-w' # TODO: make sure it runs with warnings enabled
26
21
  end
22
+ end
27
23
 
28
- unit_specs = ROOT + 'spec/unit/**/*_spec.rb'
29
- integration_specs = ROOT + 'spec/integration/**/*_spec.rb'
30
- all_specs = ROOT + 'spec/**/*_spec.rb'
24
+ public_specs = ROOT + 'spec/public/**/*_spec.rb'
25
+ semipublic_specs = ROOT + 'spec/semipublic/**/*_spec.rb'
26
+ all_specs = ROOT + 'spec/**/*_spec.rb'
31
27
 
32
- desc "Run all specifications"
33
- run_spec('spec', all_specs, false)
28
+ desc 'Run all specifications'
29
+ run_spec('spec', all_specs, false)
34
30
 
35
- desc "Run all specifications with rcov"
36
- run_spec('rcov', all_specs, true)
31
+ desc 'Run all specifications with rcov'
32
+ run_spec('rcov', all_specs, true)
37
33
 
38
- namespace :spec do
39
- desc "Run unit specifications"
40
- run_spec('unit', unit_specs, false)
34
+ namespace :spec do
35
+ desc 'Run public specifications'
36
+ run_spec('public', public_specs, false)
41
37
 
42
- desc "Run integration specifications"
43
- run_spec('integration', integration_specs, false)
44
- end
38
+ desc 'Run semipublic specifications'
39
+ run_spec('semipublic', semipublic_specs, false)
40
+ end
45
41
 
46
- namespace :rcov do
47
- desc "Run unit specifications with rcov"
48
- run_spec('unit', unit_specs, true)
42
+ namespace :rcov do
43
+ desc 'Run public specifications with rcov'
44
+ run_spec('public', public_specs, true)
49
45
 
50
- desc "Run integration specifications with rcov"
51
- run_spec('integration', integration_specs, true)
52
- end
46
+ desc 'Run semipublic specifications with rcov'
47
+ run_spec('semipublic', semipublic_specs, true)
48
+ end
53
49
 
54
- desc "Run all comparisons with ActiveRecord"
55
- task :perf do
56
- sh ROOT + 'script/performance.rb'
57
- end
50
+ desc 'Run all comparisons with ActiveRecord'
51
+ task :perf do
52
+ sh ROOT + 'script/performance.rb'
53
+ end
58
54
 
59
- desc "Profile DataMapper"
60
- task :profile do
61
- sh ROOT + 'script/profile.rb'
62
- end
55
+ desc 'Profile DataMapper'
56
+ task :profile do
57
+ sh ROOT + 'script/profile.rb'
63
58
  end
data/tasks/doc.rb CHANGED
@@ -1,20 +1,17 @@
1
1
  # when yard's ready, it'll have to come back, but for now...
2
- Rake::RDocTask.new("doc") do |t|
3
- t.rdoc_dir = 'doc'
4
- t.title = "DataMapper - Ruby Object Relational Mapper"
5
- t.options = ['--line-numbers', '--inline-source', '--all']
6
- t.rdoc_files.include("README.txt", "QUICKLINKS", "FAQ", "lib/**/**/*.rb")
2
+ Rake::RDocTask.new('doc') do |config|
3
+ config.rdoc_dir = 'doc'
4
+ config.title = 'DataMapper - Ruby Object Relational Mapper'
5
+ config.options = %w[ --line-numbers --inline-source --all ]
6
+ config.rdoc_files.include('README.txt', 'QUICKLINKS', 'FAQ', 'lib/**/**/*.rb')
7
7
  end
8
8
 
9
9
  begin
10
- gem 'yard', '>=0.2.1'
11
10
  require 'yard'
12
11
 
13
- YARD::Rake::YardocTask.new("yardoc") do |t|
14
- t.options << '--protected'
15
- # t.options << '-q'
16
- # t.files << '...anyglobshere...'
12
+ YARD::Rake::YardocTask.new('yardoc') do |config|
13
+ config.files << 'lib/**/*.rb'
17
14
  end
18
- rescue Exception
15
+ rescue LoadError
19
16
  # yard not installed
20
17
  end
data/tasks/gemspec.rb CHANGED
@@ -1,20 +1,20 @@
1
- desc "Generate gemspec"
2
- task :gemspec do |x|
1
+ desc 'Generate gemspec'
2
+ task :gemspec do
3
3
  # Clean up extraneous files before checking manifest
4
4
  %x[rake clean]
5
5
 
6
6
  # Check the manifest before generating the gemspec
7
7
  manifest = %x[rake check_manifest]
8
- manifest.gsub!("(in /usr/local/projects/dm/dm-core)\n", "")
8
+ manifest.gsub!("(in /usr/local/projects/dm/dm-core)\n", '')
9
9
 
10
10
  unless manifest.empty?
11
- print "\n", "#"*68, "\n"
11
+ print "\n", '#' * 68, "\n"
12
12
  print <<-EOS
13
13
  Manifest.txt is not up-to-date. Please review the changes below.
14
14
  If the changes are correct, run 'rake check_manifest | patch'
15
15
  and then run this command again.
16
16
  EOS
17
- print "#"*68, "\n\n"
17
+ print '#' * 68, "\n\n"
18
18
  puts manifest
19
19
  else
20
20
  %x[rake debug_gem > #{GEM_NAME}.gemspec]
data/tasks/hoe.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require 'hoe'
2
2
 
3
- @config_file = "~/.rubyforge/user-config.yml"
3
+ @config_file = '~/.rubyforge/user-config.yml'
4
4
  @config = nil
5
- RUBYFORGE_USERNAME = "unknown"
5
+ RUBYFORGE_USERNAME = 'unknown'
6
6
  def rubyforge_username
7
7
  unless @config
8
8
  begin
@@ -16,31 +16,30 @@ Run 'rubyforge setup' to prepare your env for access to Rubyforge
16
16
  exit
17
17
  end
18
18
  end
19
- RUBYFORGE_USERNAME.replace @config["username"]
19
+ RUBYFORGE_USERNAME.replace @config['username']
20
20
  end
21
21
 
22
22
  # Remove hoe dependency
23
23
  class Hoe
24
24
  def extra_dev_deps
25
- @extra_dev_deps.reject! { |dep| dep[0] == "hoe" }
25
+ @extra_dev_deps.reject! { |dep| dep[0] == 'hoe' }
26
26
  @extra_dev_deps
27
27
  end
28
28
  end
29
29
 
30
- hoe = Hoe.new(GEM_NAME, GEM_VERSION) do |p|
30
+ # Don't use Hoe's test task
31
+ Hoe.plugins.delete(:test)
31
32
 
32
- p.developer(AUTHOR, EMAIL)
33
+ hoe = Hoe.spec(GEM_NAME) do
34
+ developer(AUTHOR, EMAIL)
33
35
 
34
- p.description = PROJECT_DESCRIPTION
35
- p.summary = PROJECT_SUMMARY
36
- p.url = PROJECT_URL
36
+ self.version = GEM_VERSION
37
+ self.description = PROJECT_DESCRIPTION
38
+ self.summary = PROJECT_SUMMARY
39
+ self.url = PROJECT_URL
37
40
 
38
- p.rubyforge_name = PROJECT_NAME if PROJECT_NAME
39
-
40
- p.clean_globs |= ["{coverage,doc,log,tmp}", "**/*.{log,db}", "profile_results.*", "**/.DS_Store"]
41
-
42
- GEM_DEPENDENCIES.each do |dep|
43
- p.extra_deps << dep
44
- end
41
+ self.rubyforge_name = PROJECT_NAME
45
42
 
43
+ clean_globs |= %w[ {coverage,doc,log,tmp} **/*.{log,db} profile_results.* **/.DS_Store spec/db ]
44
+ extra_deps |= GEM_DEPENDENCIES
46
45
  end
data/tasks/install.rb CHANGED
@@ -1,20 +1,18 @@
1
1
  WIN32 = (RUBY_PLATFORM =~ /win32|mingw|bccwin|cygwin/) rescue nil
2
2
  SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
3
3
 
4
- desc "Install #{GEM_NAME}"
4
+ def sudo_gem(cmd)
5
+ sh "#{SUDO} #{RUBY} -S gem #{cmd}", :verbose => false
6
+ end
7
+
5
8
  if WIN32
9
+ desc "Install #{GEM_NAME}"
6
10
  task :install => :gem do
7
- system %{gem install --no-rdoc --no-ri -l pkg/#{GEM_NAME}-#{GEM_VERSION}.gem}
8
- end
9
- namespace :dev do
10
- desc 'Install for development (for windows)'
11
- task :winstall => :gem do
12
- warn "You can now call 'rake install' instead of 'rake dev:winstall'."
13
- system %{gem install --no-rdoc --no-ri -l pkg/#{GEM_NAME}-#{GEM_VERSION}.gem}
14
- end
11
+ sudo_gem "install --no-rdoc --no-ri pkg/#{GEM_NAME}-#{GEM_VERSION}.gem"
15
12
  end
16
13
  else
14
+ desc "Install #{GEM_NAME}"
17
15
  task :install => :package do
18
- sh %{#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION}.gem}
16
+ sudo_gem "install --no-rdoc --no-ri pkg/#{GEM_NAME}-#{GEM_VERSION}.gem"
19
17
  end
20
18
  end