minimapper 0.1.0 → 0.1.1

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/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