minimapper 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -241,11 +241,11 @@ You need mysql and postgres installed (but they do not have to be running) to be
241
241
 
242
242
  ### Next
243
243
 
244
+ * Make "informal" optional. If you only use minimapper/entity/core there is no need for it as a dependency.
244
245
  * Add some way to extend type conversions to keep that part of minimapper small.
245
246
  * Extract entity and model class lookup code from the ar-mapper and reuse it in the memory mapper.
246
247
  * Change the memory mapper to store entity attributes, not entity instances.
247
248
  - Unless this makes it difficult to handle associated data.
248
- * Make using Minimapper::Entity optional by providing shared examples of the behavior required by the mappers. Test the mappers with an object implementing only this behavior.
249
249
 
250
250
  ### Ideas
251
251
 
data/lib/minimapper/ar.rb CHANGED
@@ -21,7 +21,7 @@ module Minimapper
21
21
  end
22
22
 
23
23
  def all
24
- record_klass.all.map { |record| entity_klass.new(record.attributes) }
24
+ record_klass.all.map { |record| entity_for(record) }
25
25
  end
26
26
 
27
27
  def first
@@ -74,9 +74,9 @@ module Minimapper
74
74
 
75
75
  # Will attempt to use Project as the enity class when
76
76
  # the mapper class name is AR::ProjectMapper
77
- def entity_klass
78
- @entity_klass ||= ("::" + self.class.name.split('::').last.gsub(/Mapper/, '')).constantize
79
- @entity_klass
77
+ def entity_class
78
+ @entity_class ||= ("::" + self.class.name.split('::').last.gsub(/Mapper/, '')).constantize
79
+ @entity_class
80
80
  end
81
81
 
82
82
  def find_record_safely(id)
@@ -95,7 +95,10 @@ module Minimapper
95
95
 
96
96
  def entity_for(record)
97
97
  if record
98
- entity_klass.new(record.attributes)
98
+ entity = entity_class.new
99
+ entity.id = record.id
100
+ entity.attributes = record.attributes.symbolize_keys
101
+ entity
99
102
  else
100
103
  nil
101
104
  end
@@ -0,0 +1,27 @@
1
+ require 'minimapper/entity/convert'
2
+
3
+ module Minimapper
4
+ module Entity
5
+ module Attributes
6
+ def attributes(*list)
7
+ list.each do |attribute|
8
+ type = nil
9
+
10
+ if attribute.is_a?(Array)
11
+ attribute, type = attribute
12
+ end
13
+
14
+ define_method(attribute) do
15
+ instance_variable_get("@#{attribute}")
16
+ end
17
+
18
+ define_method("#{attribute}=") do |value|
19
+ value = Convert.new(value).to(type)
20
+ instance_variable_set("@#{attribute}", value)
21
+ attributes[attribute] = value
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # The core entity API required by minimapper. If your entity
2
+ # class implements this API, it should work with the data mappers.
3
+
4
+ module Minimapper
5
+ module Entity
6
+ module Core
7
+ attr_accessor :id
8
+
9
+ def attributes
10
+ @attributes ||= {}
11
+ end
12
+
13
+ def attributes=(new_attributes)
14
+ @attributes = attributes.merge(new_attributes)
15
+ end
16
+
17
+ def valid?
18
+ true
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ module Minimapper
2
+ module Entity
3
+ module Rails
4
+ def to_param
5
+ id
6
+ end
7
+
8
+ def persisted?
9
+ id
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,55 +1,18 @@
1
- # Minimapper does not require you to use this entity base class. It requires a
2
- # few methods to be present, like valid?, attributes, attributes=.
3
- #
4
- # I plan to add shared examples that cover the API which minimapper depends upon.
5
- #
6
- # This class also does some things needed for it to work well with rails.
1
+ # Look at minimapper/entity/core for the required API.
7
2
  require 'informal'
8
- require 'minimapper/entity/convert'
3
+ require 'minimapper/entity/core'
4
+ require 'minimapper/entity/attributes'
5
+ require 'minimapper/entity/rails'
9
6
 
10
7
  module Minimapper
11
8
  module Entity
12
- module ClassMethods
13
- def attributes(*list)
14
- list.each do |attribute|
15
- type = nil
16
-
17
- if attribute.is_a?(Array)
18
- attribute, type = attribute
19
- end
20
-
21
- define_method(attribute) do
22
- instance_variable_get("@#{attribute}")
23
- end
24
-
25
- define_method("#{attribute}=") do |value|
26
- value = Convert.new(value).to(type)
27
- instance_variable_set("@#{attribute}", value)
28
- attributes[attribute] = value
29
- end
30
- end
31
- end
32
- end
33
-
34
- module InstanceMethods
35
- def to_param
36
- id
37
- end
38
-
39
- def persisted?
40
- id
41
- end
42
-
43
- def attributes
44
- @attributes ||= {}
45
- end
46
- end
9
+ include Minimapper::Entity::Core
47
10
 
48
11
  def self.included(klass)
49
12
  klass.send(:include, Informal::Model)
50
- klass.send(:include, InstanceMethods)
51
- klass.send(:extend, ClassMethods)
52
- klass.attributes [ :id, :Integer ], [ :created_at, :DateTime ], [ :updated_at, :DateTime ]
13
+ klass.send(:include, Minimapper::Entity::Rails)
14
+ klass.send(:extend, Minimapper::Entity::Attributes)
15
+ klass.attributes([ :id, :Integer ], [ :created_at, :DateTime ], [ :updated_at, :DateTime ])
53
16
  end
54
17
  end
55
18
  end
@@ -1,3 +1,3 @@
1
1
  module Minimapper
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/spec/ar_spec.rb CHANGED
@@ -1,17 +1,15 @@
1
1
  require "spec_helper"
2
- require "minimapper/entity"
2
+ require "minimapper/entity/core"
3
3
  require "minimapper/ar"
4
4
 
5
5
  class TestEntity
6
- include Minimapper::Entity
7
- attributes :name, :github_url
8
- validates :name, :presence => true
6
+ include Minimapper::Entity::Core
9
7
  end
10
8
 
11
9
  class TestMapper < Minimapper::AR
12
10
  private
13
11
 
14
- def entity_klass
12
+ def entity_class
15
13
  TestEntity
16
14
  end
17
15
 
@@ -27,7 +25,7 @@ end
27
25
 
28
26
  describe Minimapper::AR do
29
27
  let(:repository) { TestMapper.new }
30
- let(:entity_klass) { TestEntity }
28
+ let(:entity_class) { TestEntity }
31
29
 
32
30
  include_examples :mapper
33
31
  end
@@ -1,5 +1,5 @@
1
1
  shared_examples :mapper do
2
- # expects repository and entity_klass to be defined
2
+ # expects repository and entity_class to be defined
3
3
 
4
4
  describe "#create" do
5
5
  it "sets an id on the entity" do
@@ -23,11 +23,14 @@ shared_examples :mapper do
23
23
  entity = build_valid_entity
24
24
  repository.create(entity)
25
25
  repository.last.object_id.should_not == entity.object_id
26
- repository.last.name.should == "test"
26
+ repository.last.attributes[:name].should == "test"
27
27
  end
28
28
 
29
29
  it "validates the record before saving" do
30
- entity = entity_klass.new
30
+ entity = entity_class.new
31
+ def entity.valid?
32
+ false
33
+ end
31
34
  repository.create(entity).should be_false
32
35
  end
33
36
  end
@@ -37,9 +40,9 @@ shared_examples :mapper do
37
40
  entity = build_valid_entity
38
41
  repository.create(entity)
39
42
  found_entity = repository.find(entity.id)
40
- found_entity.name.should == "test"
43
+ found_entity.attributes[:name].should == "test"
41
44
  found_entity.id.should == entity.id
42
- found_entity.should be_kind_of(Minimapper::Entity)
45
+ found_entity.should be_kind_of(Minimapper::Entity::Core)
43
46
  end
44
47
 
45
48
  it "supports string ids" do
@@ -65,9 +68,9 @@ shared_examples :mapper do
65
68
  entity = build_valid_entity
66
69
  repository.create(entity)
67
70
  found_entity = repository.find_by_id(entity.id)
68
- found_entity.name.should == "test"
71
+ found_entity.attributes[:name].should == "test"
69
72
  found_entity.id.should == entity.id
70
- found_entity.should be_kind_of(Minimapper::Entity)
73
+ found_entity.should be_kind_of(Minimapper::Entity::Core)
71
74
  end
72
75
 
73
76
  it "supports string ids" do
@@ -97,7 +100,7 @@ shared_examples :mapper do
97
100
  all_entities = repository.all
98
101
  all_entities.map(&:id).should include(first_created_entity.id)
99
102
  all_entities.map(&:id).should include(second_created_entity.id)
100
- all_entities.first.should be_kind_of(Minimapper::Entity)
103
+ all_entities.first.should be_kind_of(Minimapper::Entity::Core)
101
104
  end
102
105
 
103
106
  it "does not return the same instances" do
@@ -114,7 +117,7 @@ shared_examples :mapper do
114
117
  repository.create(first_created_entity)
115
118
  repository.create(build_valid_entity)
116
119
  repository.first.id.should == first_created_entity.id
117
- repository.first.should be_kind_of(entity_klass)
120
+ repository.first.should be_kind_of(entity_class)
118
121
  end
119
122
 
120
123
  it "does not return the same instance" do
@@ -135,7 +138,7 @@ shared_examples :mapper do
135
138
  repository.create(build_valid_entity)
136
139
  repository.create(last_created_entity)
137
140
  repository.last.id.should == last_created_entity.id
138
- repository.last.should be_kind_of(entity_klass)
141
+ repository.last.should be_kind_of(entity_class)
139
142
  end
140
143
 
141
144
  it "does not return the same instance" do
@@ -163,21 +166,24 @@ shared_examples :mapper do
163
166
  entity = build_valid_entity
164
167
  repository.create(entity)
165
168
 
166
- entity.name = "Updated"
167
- repository.last.name.should == "test"
169
+ entity.attributes = { :name => "Updated" }
170
+ repository.last.attributes[:name].should == "test"
168
171
 
169
172
  repository.update(entity)
170
173
  repository.last.id.should == entity.id
171
- repository.last.name.should == "Updated"
174
+ repository.last.attributes[:name].should == "Updated"
172
175
  end
173
176
 
174
177
  it "does not update and returns false when the entity isn't valid" do
175
178
  entity = build_valid_entity
176
179
  repository.create(entity)
177
- entity.name = nil
180
+
181
+ def entity.valid?
182
+ false
183
+ end
178
184
 
179
185
  repository.update(entity).should be_false
180
- repository.last.name.should == "test"
186
+ repository.last.attributes[:name].should == "test"
181
187
  end
182
188
 
183
189
  it "returns true" do
@@ -219,12 +225,13 @@ shared_examples :mapper do
219
225
  end
220
226
 
221
227
  it "fails when the entity does not have an id" do
222
- entity = entity_klass.new
228
+ entity = entity_class.new
223
229
  lambda { repository.delete(entity) }.should raise_error(Minimapper::Common::CanNotFindEntity)
224
230
  end
225
231
 
226
232
  it "fails when the entity can not be found" do
227
- entity = entity_klass.new(:id => -1)
233
+ entity = entity_class.new
234
+ entity.id = -1
228
235
  lambda { repository.delete(entity) }.should raise_error(Minimapper::Common::CanNotFindEntity)
229
236
  end
230
237
  end
@@ -255,6 +262,8 @@ shared_examples :mapper do
255
262
  private
256
263
 
257
264
  def build_valid_entity
258
- entity_klass.new(:name => 'test')
265
+ entity = entity_class.new
266
+ entity.attributes = { :name => 'test' }
267
+ entity
259
268
  end
260
269
  end
@@ -0,0 +1,32 @@
1
+ require 'minimapper/entity/core'
2
+
3
+ class BasicEntity
4
+ include Minimapper::Entity::Core
5
+ end
6
+
7
+ describe Minimapper::Entity::Core do
8
+ it "can get and set an attributes hash" do
9
+ entity = BasicEntity.new
10
+ entity.attributes.should == {}
11
+ entity.attributes = { :one => 1 }
12
+ entity.attributes.should == { :one => 1 }
13
+ end
14
+
15
+ it "does not replace the existing hash" do
16
+ entity = BasicEntity.new
17
+ entity.attributes = { :one => 1 }
18
+ entity.attributes = { :two => 2 }
19
+ entity.attributes.should == { :one => 1, :two => 2 }
20
+ end
21
+
22
+ it "returns true for valid?" do
23
+ entity = BasicEntity.new
24
+ entity.should be_valid
25
+ end
26
+
27
+ it "responds to id" do
28
+ entity = BasicEntity.new
29
+ entity.id = 10
30
+ entity.id.should == 10
31
+ end
32
+ end
data/unit/entity_spec.rb CHANGED
@@ -4,6 +4,12 @@ class TestEntity
4
4
  include Minimapper::Entity
5
5
  end
6
6
 
7
+ class TestUser
8
+ include Minimapper::Entity
9
+ attributes :name
10
+ validates :name, :presence => true
11
+ end
12
+
7
13
  describe Minimapper::Entity do
8
14
  it "handles base attributes" do
9
15
  entity = TestEntity.new
@@ -28,11 +34,13 @@ describe Minimapper::Entity do
28
34
  entity.id = "10"
29
35
  entity.id.should == 10
30
36
  end
31
- end
32
37
 
33
- class TestUser
34
- include Minimapper::Entity
35
- attributes :name
38
+ it "applies validations" do
39
+ user = TestUser.new
40
+ user.should_not be_valid
41
+ user.name = "Joe"
42
+ user.should be_valid
43
+ end
36
44
  end
37
45
 
38
46
  describe Minimapper::Entity, "attributes without type" do
data/unit/memory_spec.rb CHANGED
@@ -1,15 +1,13 @@
1
1
  require 'minimapper/memory'
2
- require 'minimapper/entity'
2
+ require 'minimapper/entity/core'
3
3
 
4
- class TestEntity
5
- include Minimapper::Entity
6
- attributes :name
7
- validates :name, :presence => true
4
+ class BasicEntity
5
+ include Minimapper::Entity::Core
8
6
  end
9
7
 
10
8
  describe Minimapper::Memory do
11
9
  let(:repository) { described_class.new }
12
- let(:entity_klass) { TestEntity }
10
+ let(:entity_class) { BasicEntity }
13
11
 
14
12
  include_examples :mapper
15
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minimapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-11-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: informal
16
- requirement: &70274943136540 !ruby/object:Gem::Requirement
16
+ requirement: &70315666068220 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70274943136540
24
+ version_requirements: *70315666068220
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70274943135820 !ruby/object:Gem::Requirement
27
+ requirement: &70315666067440 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70274943135820
35
+ version_requirements: *70315666067440
36
36
  description: A minimalistic way of separating your models from ORMs like ActiveRecord
37
37
  (by implementing the repository pattern)
38
38
  email:
@@ -52,7 +52,10 @@ files:
52
52
  - lib/minimapper/ar.rb
53
53
  - lib/minimapper/common.rb
54
54
  - lib/minimapper/entity.rb
55
+ - lib/minimapper/entity/attributes.rb
55
56
  - lib/minimapper/entity/convert.rb
57
+ - lib/minimapper/entity/core.rb
58
+ - lib/minimapper/entity/rails.rb
56
59
  - lib/minimapper/memory.rb
57
60
  - lib/minimapper/repository.rb
58
61
  - lib/minimapper/version.rb
@@ -64,6 +67,7 @@ files:
64
67
  - spec/support/database_setup.rb
65
68
  - spec/support/shared_examples/mapper.rb
66
69
  - unit/entity/convert_spec.rb
70
+ - unit/entity/core_spec.rb
67
71
  - unit/entity_spec.rb
68
72
  - unit/memory_spec.rb
69
73
  - unit/repository_spec.rb