Skip to content

Commit

Permalink
Lazy load entity and repository
Browse files Browse the repository at this point in the history
Additonally, adding validation for presence of entity and repository for load!
  • Loading branch information
Trung Lê committed Nov 27, 2014
1 parent eadd5ba commit e4e8e3e
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 28 deletions.
24 changes: 24 additions & 0 deletions lib/lotus/model/mapping.rb
Expand Up @@ -19,6 +19,30 @@ def initialize(name)
super("Cannot find collection: #{ name }")
end
end

# Invalid entity error.
#
# It gets raised when the application tries to access to a existing
# entity.
#
# @since 0.2.0
class EntityNotFound < ::StandardError
def initialize(name)
super("Cannot find class for entity: #{ name }")
end
end

# Invalid repository error.
#
# It gets raised when the application tries to access to a existing
# repository.
#
# @since 0.2.0
class RepositoryNotFound < ::StandardError
def initialize(name)
super("Cannot find class for repository: #{ name }")
end
end
end
end
end
55 changes: 44 additions & 11 deletions lib/lotus/model/mapping/collection.rb
Expand Up @@ -88,7 +88,9 @@ class ::Boolean
#
# @see Lotus::Model::Mapper#collection
def initialize(name, coercer_class, &blk)
@name, @coercer_class, @attributes = name, coercer_class, {}
@name = name
@coercer_class = coercer_class
@attributes = {}
instance_eval(&blk) if block_given?
end

Expand Down Expand Up @@ -126,9 +128,11 @@ def initialize(name, coercer_class, &blk)
# mapper.entity #=> Article
#
def entity(klass = nil)
@entity = klass if klass

Utils::Class.load!(@entity) if @entity
if klass
@entity = klass
else
@entity
end
end

# Defines the repository that interacts with this collection.
Expand Down Expand Up @@ -170,8 +174,6 @@ def repository(klass = nil)
else
@repository ||= default_repository_klass
end

Utils::Class.load!(@repository)
end

# Defines the identity for a collection.
Expand Down Expand Up @@ -386,21 +388,52 @@ def deserialize_attribute(attribute, value)
# @api private
# @since 0.1.0
def load!
@coercer = coercer_class.new(self)
configure_repository!
_load_entity!
_load_repository!
_load_coercer!

_configure_repository!
end

private

# Assigns a repository to an entity
#
# @see Lotus::Repository
#
# @api private
# @since 0.1.0
def configure_repository!
def _configure_repository!
repository.collection = name
repository.adapter = adapter
rescue NameError
repository.adapter = adapter if adapter
end

# Convert repository string to repository class
#
# @api private
# @since 0.2.0
def _load_repository!
@repository = Utils::Class.load!(repository)
rescue NameError
raise Lotus::Model::Mapping::RepositoryNotFound.new(repository.to_s)
end

# Convert entity string to entity class
#
# @api private
# @since 0.2.0
def _load_entity!
@entity = Utils::Class.load!(entity)
rescue NameError
raise Lotus::Model::Mapping::EntityNotFound.new(entity.to_s)
end

# Load coercer
#
# @api private
# @since 0.1.0
def _load_coercer!
@coercer = coercer_class.new(self)
end

# Retrieves the default repository class
Expand Down
10 changes: 10 additions & 0 deletions test/model/adapters/memory_adapter_test.rb
Expand Up @@ -6,10 +6,18 @@
include Lotus::Entity
end

class TestUserRepository
include Lotus::Repository
end

TestDevice = Struct.new(:id) do
include Lotus::Entity
end

class TestDeviceRepository
include Lotus::Repository
end

@mapper = Lotus::Model::Mapper.new do
collection :users do
entity TestUser
Expand All @@ -31,7 +39,9 @@

after do
Object.send(:remove_const, :TestUser)
Object.send(:remove_const, :TestUserRepository)
Object.send(:remove_const, :TestDevice)
Object.send(:remove_const, :TestDeviceRepository)
end

let(:collection) { :users }
Expand Down
10 changes: 10 additions & 0 deletions test/model/adapters/sql_adapter_test.rb
Expand Up @@ -6,10 +6,18 @@
include Lotus::Entity
end

class TestUserRepository
include Lotus::Repository
end

TestDevice = Struct.new(:id) do
include Lotus::Entity
end

class TestDeviceRepository
include Lotus::Repository
end

@mapper = Lotus::Model::Mapper.new do
collection :users do
entity TestUser
Expand All @@ -32,7 +40,9 @@

after do
Object.send(:remove_const, :TestUser)
Object.send(:remove_const, :TestUserRepository)
Object.send(:remove_const, :TestDevice)
Object.send(:remove_const, :TestDeviceRepository)
end

let(:collection) { :users }
Expand Down
56 changes: 39 additions & 17 deletions test/model/mapping/collection_test.rb
Expand Up @@ -46,8 +46,8 @@
@collection.entity('User')
end

it 'sets the value and classify the value' do
@collection.entity.must_equal User
it 'sets the value' do
@collection.entity.must_equal 'User'
end
end
end
Expand Down Expand Up @@ -80,26 +80,15 @@
@collection.repository('CustomUserRepository')
end

it 'sets the value and classify the value' do
@collection.repository.must_equal CustomUserRepository
it 'sets the value' do
@collection.repository.must_equal 'CustomUserRepository'
end
end
end

describe 'when a value is not given' do
it 'returns the default value' do
@collection.repository.must_equal UserRepository
end

describe 'when repository class is not found' do
before do
class KlassWithoutRepository; end
@collection.entity KlassWithoutRepository
end

it 'raises NameError' do
-> { @collection.repository }.must_raise NameError
end
@collection.repository.must_equal 'UserRepository'
end
end
end
Expand Down Expand Up @@ -140,11 +129,20 @@ class KlassWithoutRepository; end
describe '#load!' do
before do
@adapter = Lotus::Model::Adapters::SqlAdapter.new(nil, SQLITE_CONNECTION_STRING)
@collection.entity(User)
@collection.entity('User')
@collection.repository('UserRepository')
@collection.adapter = @adapter
@collection.load!
end

it 'converts entity to class' do
@collection.entity.must_equal User
end

it 'converts repository to class' do
@collection.repository.must_equal UserRepository
end

it 'sets up repository' do
UserRepository.collection.must_equal :users
UserRepository.instance_variable_get(:@adapter).must_equal @adapter
Expand All @@ -153,5 +151,29 @@ class KlassWithoutRepository; end
it 'instantiates coercer' do
@collection.instance_variable_get(:@coercer).must_be_instance_of Lotus::Model::Mapping::Coercer
end

describe 'when entity class does not exist' do
before do
@collection = Lotus::Model::Mapping::Collection.new(:users, Lotus::Model::Mapping::Coercer)
@collection.entity('NonExistingUser')
@collection.repository('UserRepository')
end

it 'raises error' do
-> { @collection.load! }.must_raise(Lotus::Model::Mapping::EntityNotFound)
end
end

describe 'when repository class does not exist' do
before do
@collection = Lotus::Model::Mapping::Collection.new(:users, Lotus::Model::Mapping::Coercer)
@collection.entity('User')
@collection.repository('NonExistingUserRepository')
end

it 'raises error' do
-> { @collection.load! }.must_raise(Lotus::Model::Mapping::RepositoryNotFound)
end
end
end
end

0 comments on commit e4e8e3e

Please sign in to comment.