orm_adapter 0.0.1 → 0.0.2

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
@@ -3,12 +3,13 @@ source "http://rubygems.org"
3
3
  gem "yard"
4
4
 
5
5
  group :test do
6
- gem "activerecord", "~>3.0.0"
7
- gem "mongoid", "~>2.0.0.beta.17"
8
- gem "rspec", "~>2.0.0.beta.22"
6
+ gem "activerecord", "~> 3.0.0"
7
+ gem "mongoid", "~> 2.0.0.beta.17"
8
+ gem "rspec", "~> 2.0.0.rc"
9
9
  gem "jeweler"
10
10
  gem "rake"
11
11
  gem "sqlite3-ruby"
12
12
  gem "datamapper"
13
13
  gem "dm-sqlite-adapter"
14
+ gem "dm-active_model"
14
15
  end
@@ -14,7 +14,7 @@ GEM
14
14
  addressable (2.2.1)
15
15
  arel (1.0.1)
16
16
  activesupport (~> 3.0.0)
17
- bson (1.0.9)
17
+ bson (1.1)
18
18
  builder (2.1.2)
19
19
  data_objects (0.10.2)
20
20
  addressable (~> 2.1)
@@ -81,16 +81,16 @@ GEM
81
81
  tzinfo (~> 0.3.22)
82
82
  will_paginate (~> 3.0.pre)
83
83
  rake (0.8.7)
84
- rspec (2.0.0.beta.22)
85
- rspec-core (= 2.0.0.beta.22)
86
- rspec-expectations (= 2.0.0.beta.22)
87
- rspec-mocks (= 2.0.0.beta.22)
88
- rspec-core (2.0.0.beta.22)
89
- rspec-expectations (2.0.0.beta.22)
84
+ rspec (2.0.0.rc)
85
+ rspec-core (= 2.0.0.rc)
86
+ rspec-expectations (= 2.0.0.rc)
87
+ rspec-mocks (= 2.0.0.rc)
88
+ rspec-core (2.0.0.rc)
89
+ rspec-expectations (2.0.0.rc)
90
90
  diff-lcs (>= 1.1.2)
91
- rspec-mocks (2.0.0.beta.22)
92
- rspec-core (= 2.0.0.beta.22)
93
- rspec-expectations (= 2.0.0.beta.22)
91
+ rspec-mocks (2.0.0.rc)
92
+ rspec-core (= 2.0.0.rc)
93
+ rspec-expectations (= 2.0.0.rc)
94
94
  rubyforge (2.0.4)
95
95
  json_pure (>= 1.1.7)
96
96
  sqlite3-ruby (1.3.1)
@@ -1,3 +1,9 @@
1
+ == master
2
+
3
+ * Add #get to the API. Ensure both #get and #get! complies with to_key requirements. [José Valim]
4
+ * Extract tests into shared example. Give instructions on how to write a new adapter. [Ian White]
5
+
6
+
1
7
  == 0.0.1
2
8
 
3
9
  * Initial release [Ian White, José Valim]
@@ -1,9 +1,7 @@
1
- = orm_adapter
1
+ = ORM Adapter
2
2
 
3
3
  Provides a single point of entry for popular ruby ORMs. Its target audience is gem authors who want to support more than one ORM.
4
4
 
5
- Currently supported ORMs are ActiveRecord, DataMapper and MongoId.
6
-
7
5
 
8
6
  == Example of use
9
7
 
@@ -20,10 +18,29 @@ Currently supported ORMs are ActiveRecord, DataMapper and MongoId.
20
18
  user_model.create!(:name => 'fred') # create a fred
21
19
 
22
20
 
21
+ == Supported ORMs
22
+
23
+ Currently supported ORMs are *ActiveRecord*, *DataMapper* and *MongoId*.
24
+
25
+ We welcome you to write new adapters as gems. ORM Adapter will stay focused in having these three major ORMs working.
26
+
27
+ To write an adapter look at <tt>lib/orm_adapter/adapters/active_record.rb</tt> for an example of implementation. To see how to test it, look at <tt>spec/orm_adapter/example_app_shared.rb</tt>, <tt>spec/orm_adapter/adapters/active_record_spec.rb</tt>. You'll need to require the target ORM in <tt>spec/spec_helper.rb</tt>
28
+
29
+
30
+ == Goals
31
+
32
+ ORM Adapter goal is to support a minimum API used by most of the plugins that needs agnosticism beyond Active Model.
33
+
34
+ ORM Adapter will support only basic methods, as +get+, +find_first+, <tt>create!</tt> and so forth. It is not ORM Adapter's goal to support different query constructions, handle table joins, etc.
35
+
36
+ If you need complex queries, we recommend you to subclass ORM Adapters in your plugin and extend it expressing these query conditions as part of your domain logic.
37
+
38
+
23
39
  == History
24
40
 
41
+ orm_adapter is an extraction from {pickle}[http://github.com/ianwhite/pickle] by {Ian White}[http://github.com/ianwhite]. Pickle's orm adapter included work by {Daniel Neighman}[http://github.com/hassox], {Josh Bassett}[http://github.com/nullobject], {Marc Lee}[http://github.com/maleko], and {Sebastian Zuchmanski}[http://github.com/sebcioz].
25
42
 
26
- orm_adapter is an extraction from {pickle}[http://github.com/ianwhite/pickle] by {Ian White}[http://github.com/ianwhite]. Pickle's orm adapter included work by {Daniel Neighman}[http://github.com/hassox] and {Josh Bassett}[http://github.com/nullobject]. {José Valim}[http://github.com/josevalim] suggested the extraction, and worked on the first release with Ian.
43
+ {José Valim}[http://github.com/josevalim] suggested the extraction, and worked on the first release with Ian.
27
44
 
28
45
 
29
46
  == Copyright
data/Rakefile CHANGED
@@ -16,7 +16,7 @@ begin
16
16
  require 'jeweler'
17
17
  Jeweler::Tasks.new do |gem|
18
18
  gem.name = "orm_adapter"
19
- gem.version = OrmAdapter::Version::String
19
+ gem.version = OrmAdapter::VERSION
20
20
  gem.summary = %Q{Provides a single point of entry for using basic features of ruby ORMs}
21
21
  gem.description = %Q{Provides a single point of entry for using basic features of ruby ORMs}
22
22
  gem.email = "ian.w.white@gmail.com"
@@ -37,7 +37,12 @@ class ActiveRecord::Base
37
37
 
38
38
  # Get an instance by id of the model
39
39
  def get!(id)
40
- klass.find(id)
40
+ klass.find(wrap_key(id))
41
+ end
42
+
43
+ # Get an instance by id of the model
44
+ def get(id)
45
+ klass.first :conditions => { klass.primary_key => wrap_key(id) }
41
46
  end
42
47
 
43
48
  # Find the first instance matching conditions
@@ -59,15 +64,12 @@ class ActiveRecord::Base
59
64
 
60
65
  # Introspects the klass to convert and objects in conditions into foreign key and type fields
61
66
  def conditions_to_fields(conditions)
62
- conditions.inject({}) do |fields, (key, value)|
67
+ conditions = conditions.dup
68
+ conditions.each do |key, value|
63
69
  if value.is_a?(ActiveRecord::Base) && klass.column_names.include?("#{key}_id")
64
- if klass.column_names.include?("#{key}_type")
65
- fields.merge("#{key}_id" => value.id, "#{key}_type" => value.class.base_class.name)
66
- else
67
- fields.merge("#{key}_id" => value.id)
68
- end
69
- else
70
- fields.merge(key => value)
70
+ conditions.delete(key)
71
+ conditions["#{key}_id"] = value.id
72
+ conditions["#{key}_type"] = value.class.base_class.name if klass.column_names.include?("#{key}_type")
71
73
  end
72
74
  end
73
75
  end
@@ -28,6 +28,11 @@ module DataMapper
28
28
  klass.get!(id)
29
29
  end
30
30
 
31
+ # Get an instance by id of the model
32
+ def get(id)
33
+ klass.get(id)
34
+ end
35
+
31
36
  # Find the first instance matching conditions
32
37
  def find_first(conditions)
33
38
  klass.first(conditions)
@@ -24,7 +24,12 @@ module Mongoid
24
24
 
25
25
  # Get an instance by id of the model
26
26
  def get!(id)
27
- klass.find(id)
27
+ klass.find(wrap_key(id))
28
+ end
29
+
30
+ # Get an instance by id of the model
31
+ def get(id)
32
+ klass.first(:conditions => { :id => wrap_key(id) })
28
33
  end
29
34
 
30
35
  # Find the first instance matching conditions
@@ -28,11 +28,24 @@ module OrmAdapter
28
28
  raise NotSupportedError
29
29
  end
30
30
 
31
- # Get an instance by id of the model
31
+ # Get an instance by id of the model. Raises an error if a model is not found.
32
+ # This should comply with ActiveModel#to_key API, i.e.:
33
+ #
34
+ # User.to_adapter.get!(@user.to_key) == @user
35
+ #
32
36
  def get!(id)
33
37
  raise NotSupportedError
34
38
  end
35
39
 
40
+ # Get an instance by id of the model. Returns nil if a model is not found.
41
+ # This should comply with ActiveModel#to_key API, i.e.:
42
+ #
43
+ # User.to_adapter.get(@user.to_key) == @user
44
+ #
45
+ def get
46
+ raise NotSupportedError
47
+ end
48
+
36
49
  # Find the first instance matching conditions
37
50
  def find_first(conditions)
38
51
  raise NotSupportedError
@@ -47,9 +60,15 @@ module OrmAdapter
47
60
  def create!(attributes)
48
61
  raise NotSupportedError
49
62
  end
63
+
64
+ protected
65
+
66
+ def wrap_key(key)
67
+ key.is_a?(Array) ? key.first : key
68
+ end
50
69
  end
51
70
 
52
- class NotSupportedError < RuntimeError
71
+ class NotSupportedError < NotImplementedError
53
72
  def to_s
54
73
  "method not supported by this orm adapter"
55
74
  end
@@ -1,16 +1,3 @@
1
- require 'yaml'
2
-
3
1
  module OrmAdapter
4
- module Version
5
- Hash = YAML.load_file(File.dirname(__FILE__) + '/../../VERSION.yml')
6
- Major = Hash[:major]
7
- Minor = Hash[:minor]
8
- Patch = Hash[:patch]
9
- Build = Hash[:build]
10
- String = "#{Major}.#{Minor}.#{Patch}#{".#{Build}" if Build}"
11
-
12
- def self.to_s
13
- String
14
- end
15
- end
2
+ VERSION = "0.0.2"
16
3
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{orm_adapter}
8
- s.version = "0.0.1"
8
+ s.version = "0.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ian White", "Jose Valim"]
12
- s.date = %q{2010-10-06}
12
+ s.date = %q{2010-10-10}
13
13
  s.description = %q{Provides a single point of entry for using basic features of ruby ORMs}
14
14
  s.email = %q{ian.w.white@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -24,7 +24,6 @@ Gem::Specification.new do |s|
24
24
  "LICENSE",
25
25
  "README.rdoc",
26
26
  "Rakefile",
27
- "VERSION.yml",
28
27
  "lib/orm_adapter.rb",
29
28
  "lib/orm_adapter/adapters/active_record.rb",
30
29
  "lib/orm_adapter/adapters/data_mapper.rb",
@@ -36,6 +35,7 @@ Gem::Specification.new do |s|
36
35
  "spec/orm_adapter/adapters/active_record_spec.rb",
37
36
  "spec/orm_adapter/adapters/data_mapper_spec.rb",
38
37
  "spec/orm_adapter/adapters/mongoid_spec.rb",
38
+ "spec/orm_adapter/example_app_shared.rb",
39
39
  "spec/orm_adapter_spec.rb",
40
40
  "spec/spec_helper.rb"
41
41
  ]
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
48
48
  "spec/orm_adapter/adapters/active_record_spec.rb",
49
49
  "spec/orm_adapter/adapters/data_mapper_spec.rb",
50
50
  "spec/orm_adapter/adapters/mongoid_spec.rb",
51
+ "spec/orm_adapter/example_app_shared.rb",
51
52
  "spec/orm_adapter_spec.rb",
52
53
  "spec/spec_helper.rb"
53
54
  ]
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'orm_adapter/example_app_shared'
2
3
 
3
4
  if !defined?(ActiveRecord::Base)
4
5
  puts "** require 'active_record' to run the specs in #{__FILE__}"
@@ -8,7 +9,6 @@ else
8
9
  ActiveRecord::Migration.suppress_messages do
9
10
  ActiveRecord::Schema.define(:version => 0) do
10
11
  create_table(:users, :force => true) {|t| t.string :name; t.belongs_to :site }
11
- create_table(:sites, :force => true) {|t| t.string :name }
12
12
  create_table(:notes, :force => true) {|t| t.belongs_to :owner, :polymorphic => true }
13
13
  end
14
14
  end
@@ -16,12 +16,7 @@ else
16
16
  module ArOrmSpec
17
17
  class User < ActiveRecord::Base
18
18
  belongs_to :site, :class_name => "ArOrmSpec::Site"
19
- has_many :ar_notes, :as => :owner
20
- end
21
-
22
- class Site < ActiveRecord::Base
23
- has_many :users, :class_name => 'ArOrmSpec::User'
24
- has_many :notes, :as => :owner, :class_name => 'ArOrmSpec::Note'
19
+ has_many :notes, :as => :owner
25
20
  end
26
21
 
27
22
  class AbstractNoteClass < ActiveRecord::Base
@@ -33,116 +28,27 @@ else
33
28
  end
34
29
 
35
30
  # here be the specs!
36
- describe ActiveRecord::Base::OrmAdapter do
31
+ describe '[ActiveRecord orm adapter]' do
37
32
  before do
38
33
  User.delete_all
39
34
  Note.delete_all
40
- Site.delete_all
41
35
  end
42
36
 
43
- subject { ActiveRecord::Base::OrmAdapter }
44
-
45
- specify "except_classes should return the names of active record session store classes" do
46
- subject.except_classes.should == ["CGI::Session::ActiveRecordStore::Session", "ActiveRecord::SessionStore::Session"]
47
- end
48
-
49
- specify "model_classes should return all of the non abstract model classes (that are not in except_classes)" do
50
- subject.model_classes.should == [User, Site, Note]
51
- end
52
-
53
- describe "get!(id)" do
54
- specify "should return the instance of klass with id if it exists" do
55
- user = User.create!
56
- User.to_adapter.get!(user.id).should == user
57
- end
58
-
59
- specify "should raise an error if the klass does not have an instance with that id" do
60
- lambda { User.to_adapter.get!(1) }.should raise_error
61
- end
62
- end
63
-
64
- describe "find_first(klass, conditions)" do
65
- specify "should return first model matching conditions, if it exists" do
66
- user = User.create! :name => "Fred"
67
- User.to_adapter.find_first(:name => "Fred").should == user
68
- end
37
+ describe "the OrmAdapter class" do
38
+ subject { ActiveRecord::Base::OrmAdapter }
69
39
 
70
- specify "should return nil if no conditions match" do
71
- User.to_adapter.find_first(:name => "Betty").should == nil
72
- end
73
-
74
- specify "should handle belongs_to objects in attributes hash" do
75
- site = Site.create!
76
- user = User.create! :name => "Fred", :site => site
77
- User.to_adapter.find_first(:site => site).should == user
40
+ specify "#except_classes should return the names of active record session store classes" do
41
+ subject.except_classes.should == ["CGI::Session::ActiveRecordStore::Session", "ActiveRecord::SessionStore::Session"]
78
42
  end
79
43
 
80
- specify "should handle belongs_to :polymorphic objects in attributes hash" do
81
- site = Site.create!
82
- note = Note.create! :owner => site
83
- Note.to_adapter.find_first(:owner => site).should == note
44
+ specify "#model_classes should return all of the non abstract model classes (that are not in except_classes)" do
45
+ subject.model_classes.should == [User, Note]
84
46
  end
85
47
  end
86
48
 
87
- describe "find_all(klass, conditions)" do
88
- specify "should return all models matching conditions" do
89
- user1 = User.create! :name => "Fred"
90
- user2 = User.create! :name => "Fred"
91
- user3 = User.create! :name => "Betty"
92
- User.to_adapter.find_all(:name => "Fred").should == [user1, user2]
93
- end
94
-
95
- specify "should return empty array if no conditions match" do
96
- User.to_adapter.find_all(:name => "Betty").should == []
97
- end
98
-
99
- specify "should handle belongs_to objects in conditions hash" do
100
- site1, site2 = Site.create!, Site.create!
101
- user1, user2 = User.create!(:site => site1), User.create!(:site => site2)
102
- User.to_adapter.find_all(:site => site1).should == [user1]
103
- end
104
-
105
- specify "should handle polymorphic belongs_to objects in conditions hash" do
106
- site1, site2 = Site.create!, Site.create!
107
- note1, note2 = site1.notes.create!, site2.notes.create!
108
- Note.to_adapter.find_all(:owner => site1).should == [note1]
109
- end
110
- end
111
-
112
- describe "create!(klass, attributes)" do
113
- it "should create a model using the given attributes" do
114
- User.to_adapter.create!(:name => "Fred")
115
- User.last.name.should == "Fred"
116
- end
117
-
118
- it "should raise error if the create fails" do
119
- lambda { User.to_adapter.create!(:non_existent => true) }.should raise_error
120
- end
121
-
122
- it "should handle belongs_to objects in attributes hash" do
123
- site = Site.create!
124
- User.to_adapter.create!(:site => site)
125
- User.last.site.should == site
126
- end
127
-
128
- it "should handle polymorphic belongs_to objects in attributes hash" do
129
- site = Site.create!
130
- Note.to_adapter.create!(:owner => site)
131
- Note.last.owner.should == site
132
- end
133
-
134
- it "should handle has_many objects in attributes hash" do
135
- users = [User.create!, User.create!]
136
- Site.to_adapter.create!(:users => users)
137
- Site.last.users.should == users
138
- end
139
- end
140
-
141
- describe "<model class>#to_adapter" do
142
- it "should return an adapter instance for the receiver" do
143
- User.to_adapter.should be_a(OrmAdapter::Base)
144
- User.to_adapter.klass.should == User
145
- end
49
+ it_should_behave_like "example app with orm_adapter" do
50
+ let(:user_class) { User }
51
+ let(:note_class) { Note }
146
52
  end
147
53
  end
148
54
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'orm_adapter/example_app_shared'
2
3
 
3
4
  if !defined?(DataMapper)
4
5
  puts "** require 'dm-core' to run the specs in #{__FILE__}"
@@ -32,86 +33,20 @@ else
32
33
  Note.destroy
33
34
  end
34
35
 
35
- subject { DataMapper::Resource::OrmAdapter }
36
-
37
- specify "model_classes should return all of datamapper resources" do
38
- subject.model_classes.should == [User, Note]
39
- end
40
-
41
- describe "get!(klass, id)" do
42
- specify "should return the instance of klass with id if it exists" do
43
- user = User.create!
44
- User.to_adapter.get!(user.id).should == user
45
- end
46
-
47
- specify "should raise an error if the klass does not have an instance with that id" do
48
- lambda { User.to_adapter.get!(1) }.should raise_error
49
- end
50
- end
51
-
52
- describe "find_first(klass, conditions)" do
53
- specify "should return first model matching conditions, if it exists" do
54
- user = User.create! :name => "Fred"
55
- User.to_adapter.find_first(:name => "Fred").should == user
56
- end
36
+ describe "the OrmAdapter class" do
37
+ subject { DataMapper::Resource::OrmAdapter }
57
38
 
58
- specify "should return nil if no conditions match" do
59
- User.to_adapter.find_first(:name => "Betty").should == nil
60
- end
61
-
62
- specify "should handle belongs_to objects in attributes hash" do
63
- user = User.create!
64
- note = Note.create! :owner => user
65
- Note.to_adapter.find_first(:owner => user).should == note
39
+ specify "#model_classes should return all of the non abstract model classes (that are not in except_classes)" do
40
+ subject.model_classes.should == [User, Note]
66
41
  end
67
42
  end
68
-
69
- describe "find_all(klass, conditions)" do
70
- specify "should return all models matching conditions" do
71
- user1 = User.create! :name => "Fred"
72
- user2 = User.create! :name => "Fred"
73
- user3 = User.create! :name => "Betty"
74
- User.to_adapter.find_all(:name => "Fred").should == [user1, user2]
75
- end
76
43
 
77
- specify "should return empty array if no conditions match" do
78
- User.to_adapter.find_all(:name => "Betty").should == []
79
- end
80
-
81
- specify "should handle belongs_to objects in conditions hash" do
82
- user1, user2 = User.create!, User.create!
83
- note1, note2 = user1.notes.create!, user2.notes.create!
84
- Note.to_adapter.find_all(:owner => user1).should == [note1]
85
- end
86
- end
87
-
88
- describe "create!(klass, attributes)" do
89
- it "should create a model using the given attributes" do
90
- User.to_adapter.create!(:name => "Fred")
91
- User.last.name.should == "Fred"
92
- end
93
-
94
- it "should raise error if the create fails" do
95
- lambda { subject.create!(:non_existent => true) }.should raise_error
96
- end
97
-
98
- it "should handle belongs_to objects in attributes hash" do
99
- user = User.create!
100
- Note.to_adapter.create!(:owner => user)
101
- Note.last.owner.should == user
102
- end
103
-
104
- it "should handle has_many objects in attributes hash" do
105
- notes = [Note.create!, Note.create!]
106
- User.to_adapter.create!(:notes => notes)
107
- User.last.notes.should == notes
108
- end
109
- end
110
-
111
- describe "<model class>#to_adapter" do
112
- it "should return an adapter instance for the receiver" do
113
- User.to_adapter.should be_a(OrmAdapter::Base)
114
- User.to_adapter.klass.should == User
44
+ it_should_behave_like "example app with orm_adapter" do
45
+ let(:user_class) { User }
46
+ let(:note_class) { Note }
47
+
48
+ def reload_model(model)
49
+ model.class.get(model.id)
115
50
  end
116
51
  end
117
52
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'orm_adapter/example_app_shared'
2
3
 
3
4
  if !defined?(Mongoid) || !(Mongo::Connection.new.db('orm_adapter_spec') rescue nil)
4
5
  puts "** require 'mongoid' start mongod to run the specs in #{__FILE__}"
@@ -28,81 +29,17 @@ else
28
29
  Note.delete_all
29
30
  end
30
31
 
31
- subject { Mongoid::Document::OrmAdapter }
32
-
33
- specify "model_classes should return all of mongoid resources" do
34
- (subject.model_classes & [User, Note]).to_set.should == [User, Note].to_set
35
- end
36
-
37
- describe "get!(klass, id)" do
38
- specify "should return the instance of klass with id if it exists" do
39
- user = User.create!
40
- User.to_adapter.get!(user.id).should == user
41
- end
42
-
43
- specify "should raise an error if the klass does not have an instance with that id" do
44
- lambda { User.to_adapter.get!(1) }.should raise_error
45
- end
46
- end
47
-
48
- describe "find_first(klass, conditions)" do
49
- specify "should return first model matching conditions, if it exists" do
50
- user = User.create! :name => "Fred"
51
- User.to_adapter.find_first(:name => "Fred").should == user
52
- end
32
+ describe "the OrmAdapter class" do
33
+ subject { Mongoid::Document::OrmAdapter }
53
34
 
54
- specify "should return nil if no conditions match" do
55
- User.to_adapter.find_first(:name => "Betty").should == nil
56
- end
57
-
58
- specify "should handle belongs_to objects in attributes hash" do
59
- user = User.create!
60
- note = Note.create! :owner => user
61
- Note.to_adapter.find_first(:owner => user).should == note
35
+ specify "#model_classes should return all document classes" do
36
+ (subject.model_classes & [User, Note]).to_set.should == [User, Note].to_set
62
37
  end
63
38
  end
64
39
 
65
- describe "find_all(klass, conditions)" do
66
- specify "should return all models matching conditions" do
67
- user1 = User.create! :name => "Fred"
68
- user2 = User.create! :name => "Fred"
69
- user3 = User.create! :name => "Betty"
70
- User.to_adapter.find_all(:name => "Fred").should == [user1, user2]
71
- end
72
-
73
- specify "should return empty array if no conditions match" do
74
- User.to_adapter.find_all(:name => "Betty").should == []
75
- end
76
-
77
- specify "should handle belongs_to objects in conditions hash" do
78
- user1, user2 = User.create!, User.create!
79
- note1, note2 = Note.create!(:owner_id => user1.id), Note.create!(:owner_id => user2.id)
80
- Note.to_adapter.find_all(:owner => user1).should == [note1]
81
- end
82
- end
83
-
84
- describe "create!(klass, attributes)" do
85
- it "should create a model using the given attributes" do
86
- User.to_adapter.create!(:name => "Fred")
87
- User.last.name.should == "Fred"
88
- end
89
-
90
- it "should raise error if the create fails" do
91
- lambda { User.to_adapter.create!(foo) }.should raise_error
92
- end
93
-
94
- it "should handle belongs_to objects in attributes hash" do
95
- user = User.create!
96
- Note.to_adapter.create!(:owner => user)
97
- Note.last.owner.should == user
98
- end
99
- end
100
-
101
- describe "<model class>#to_adapter" do
102
- it "should return an adapter instance for the receiver" do
103
- User.to_adapter.should be_a(OrmAdapter::Base)
104
- User.to_adapter.klass.should == User
105
- end
40
+ it_should_behave_like "example app with orm_adapter" do
41
+ let(:user_class) { User }
42
+ let(:note_class) { Note }
106
43
  end
107
44
  end
108
45
  end
@@ -0,0 +1,143 @@
1
+ # to test your new orm_adapter, make an example app that matches the functionality
2
+ # found in the existing specs for example, look at spec/orm_adapter/adapters/active_record_spec.rb
3
+ #
4
+ # Then you can execute this shared spec as follows:
5
+ #
6
+ # it_should_behave_like "execute app with orm_adapter" do
7
+ # let(:user_class) { User }
8
+ # let(:note_class) { Note }
9
+ #
10
+ # # optionaly define the following functions if the ORM does not support
11
+ # # this syntax - this should NOT use the orm_adapter, because we're testing that
12
+ # def create_model(klass, attrs = {})
13
+ # klass.create!(attrs)
14
+ # end
15
+ #
16
+ # def reload_model(model)
17
+ # model.class.find(model.id)
18
+ # end
19
+ # end
20
+ #
21
+ shared_examples_for "example app with orm_adapter" do
22
+
23
+ def create_model(klass, attrs = {})
24
+ klass.create!(attrs)
25
+ end
26
+
27
+ def reload_model(model)
28
+ model.class.find(model.id)
29
+ end
30
+
31
+ describe "an ORM class" do
32
+ subject { note_class }
33
+
34
+ it "#to_adapter should return an adapter instance" do
35
+ subject.to_adapter.should be_a(OrmAdapter::Base)
36
+ end
37
+
38
+ it "#to_adapter should return an adapter for the receiver" do
39
+ subject.to_adapter.klass.should == subject
40
+ end
41
+
42
+ it "#to_adapter should be cached" do
43
+ subject.to_adapter.object_id.should == subject.to_adapter.object_id
44
+ end
45
+ end
46
+
47
+ describe "adapter instance" do
48
+ let(:note_adapter) { note_class.to_adapter }
49
+ let(:user_adapter) { user_class.to_adapter }
50
+
51
+ describe "#get!(id)" do
52
+ it "should return the instance with id if it exists" do
53
+ user = create_model(user_class)
54
+ user_adapter.get!(user.id).should == user
55
+ end
56
+
57
+ it "should allow to_key like arguments" do
58
+ user = create_model(user_class)
59
+ user_adapter.get!(user.to_key).should == user
60
+ end
61
+
62
+ it "should raise an error if there is no instance with that id" do
63
+ lambda { user_adapter.get!("non-exitent id") }.should raise_error
64
+ end
65
+ end
66
+
67
+ describe "#get(id)" do
68
+ it "should return the instance with id if it exists" do
69
+ user = create_model(user_class)
70
+ user_adapter.get(user.id).should == user
71
+ end
72
+
73
+ it "should allow to_key like arguments" do
74
+ user = create_model(user_class)
75
+ user_adapter.get(user.to_key).should == user
76
+ end
77
+
78
+ it "should return nil if there is no instance with that id" do
79
+ user_adapter.get("non-exitent id").should be_nil
80
+ end
81
+ end
82
+
83
+ describe "#find_first(conditions)" do
84
+ it "should return first model matching conditions, if it exists" do
85
+ user = create_model(user_class, :name => "Fred")
86
+ user_adapter.find_first(:name => "Fred").should == user
87
+ end
88
+
89
+ it "should return nil if no conditions match" do
90
+ user_adapter.find_first(:name => "Betty").should == nil
91
+ end
92
+
93
+ it "when conditions contain associated object, should return first model if it exists" do
94
+ user = create_model(user_class)
95
+ note = create_model(note_class, :owner => user)
96
+ note_adapter.find_first(:owner => user).should == note
97
+ end
98
+ end
99
+
100
+ describe "#find_all(conditions)" do
101
+ it "should return only models matching conditions" do
102
+ user1 = create_model(user_class, :name => "Fred")
103
+ user2 = create_model(user_class, :name => "Fred")
104
+ user3 = create_model(user_class, :name => "Betty")
105
+ user_adapter.find_all(:name => "Fred").should == [user1, user2]
106
+ end
107
+
108
+ it "should return empty array if no conditions match" do
109
+ user_adapter.find_all(:name => "Fred").should == []
110
+ end
111
+
112
+ it "when conditions contain associated object, should return first model if it exists" do
113
+ user1, user2 = create_model(user_class), create_model(user_class)
114
+ note1 = create_model(note_class, :owner => user1)
115
+ note2 = create_model(note_class, :owner => user2)
116
+ note_adapter.find_all(:owner => user2).should == [note2]
117
+ end
118
+ end
119
+
120
+ describe "#create!(attributes)" do
121
+ it "should create a model with the passed attributes" do
122
+ user = user_adapter.create!(:name => "Fred")
123
+ reload_model(user).name.should == "Fred"
124
+ end
125
+
126
+ it "should raise error when create fails" do
127
+ lambda { user_adapter.create!(:user => create_model(note_class)) }.should raise_error
128
+ end
129
+
130
+ it "when attributes contain an associated object, should create a model with the attributes" do
131
+ user = create_model(user_class)
132
+ note = note_adapter.create!(:owner => user)
133
+ reload_model(note).owner.should == user
134
+ end
135
+
136
+ it "when attributes contain an has_many assoc, should create a model with the attributes" do
137
+ notes = [create_model(note_class), create_model(note_class)]
138
+ user = user_adapter.create!(:notes => notes)
139
+ reload_model(user).notes.should == notes
140
+ end
141
+ end
142
+ end
143
+ end
@@ -11,4 +11,5 @@ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
11
  end
12
12
  end
13
13
 
14
+ require 'dm-active_model' if defined?(DataMapper)
14
15
  require 'orm_adapter'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orm_adapter
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ian White
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-10-06 00:00:00 +01:00
19
+ date: 2010-10-10 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies: []
22
22
 
@@ -37,7 +37,6 @@ files:
37
37
  - LICENSE
38
38
  - README.rdoc
39
39
  - Rakefile
40
- - VERSION.yml
41
40
  - lib/orm_adapter.rb
42
41
  - lib/orm_adapter/adapters/active_record.rb
43
42
  - lib/orm_adapter/adapters/data_mapper.rb
@@ -49,6 +48,7 @@ files:
49
48
  - spec/orm_adapter/adapters/active_record_spec.rb
50
49
  - spec/orm_adapter/adapters/data_mapper_spec.rb
51
50
  - spec/orm_adapter/adapters/mongoid_spec.rb
51
+ - spec/orm_adapter/example_app_shared.rb
52
52
  - spec/orm_adapter_spec.rb
53
53
  - spec/spec_helper.rb
54
54
  has_rdoc: true
@@ -89,5 +89,6 @@ test_files:
89
89
  - spec/orm_adapter/adapters/active_record_spec.rb
90
90
  - spec/orm_adapter/adapters/data_mapper_spec.rb
91
91
  - spec/orm_adapter/adapters/mongoid_spec.rb
92
+ - spec/orm_adapter/example_app_shared.rb
92
93
  - spec/orm_adapter_spec.rb
93
94
  - spec/spec_helper.rb
@@ -1,4 +0,0 @@
1
- ---
2
- :major: 0
3
- :minor: 0
4
- :patch: 1