require 'sequel' require_relative '../spec_helper' require_relative '../../lib/kamerling/mapper' require_relative '../../lib/kamerling/project' require_relative '../../lib/kamerling/repo' require_relative '../../lib/kamerling/uuid' require_relative '../../lib/kamerling/uuid_entity' module Kamerling describe Repo do Tune = Class.new(UUIDEntity) { attrs genre: Symbol } describe '#<<' do it 'passes the Hash version of an object to the source via a mapper' do tune = Tune.new(genre: :chap_hop) source = fake(Sequel::Dataset) Repo.new(Tune, source) << tune source.must_have_received :<<, [tune.to_h] end it 'updates the source’s version if it exists there' do dataset = fake(Sequel::Dataset) source = fake(Sequel::Dataset) tune = Tune.new(genre: :chap_hop) stub(source).<<(tune.to_h) { fail Sequel::UniqueConstraintViolation } stub(source).where(uuid: tune.uuid) { dataset } Repo.new(Tune, source) << tune dataset.must_have_received :update, [tune.to_h] end end describe '#[]' do it 'hydrates the object found in the repo via a mapper' do tune = Tune.new(genre: :chap_hop) hash = { genre: :chap_hop, uuid: tune.uuid } source = { { uuid: tune.uuid } => hash } mapper = fake(:mapper, as: :class) stub(mapper).from_h(Tune, hash) { tune } retrieved = Repo.new(Tune, source, mapper: mapper)[tune.uuid] retrieved.to_h.must_equal tune.to_h end it 'raises NotFound if the object is not found in the repo' do -> { Repo.new(Tune, {})[UUID.new] }.must_raise Repo::NotFound end end describe '#all' do it 'returns all objects via a mapper' do tune = Tune.new(genre: :chap_hop) source = fake(Sequel::Dataset, all: [genre: :chap_hop, uuid: tune.uuid]) mapper = fake(:mapper, as: :class, from_h: tune) Repo.new(Tune, source, mapper: mapper).all.must_equal [tune] end end describe '#related_to' do it 'returns objects related to the given object via a mapper' do ragga = Tune.new(genre: :ragga) reggae = Tune.new(genre: :reggae) project = Project.new results = [ { genre: :ragga, uuid: ragga.uuid }, { genre: :reggae, uuid: reggae.uuid }, ] source = fake(Sequel::Dataset) stub(source).where(project_uuid: project.uuid) { results } mapper = fake(:mapper, as: :class) stub(mapper).from_h(Tune, genre: :ragga, uuid: ragga.uuid) { ragga } stub(mapper).from_h(Tune, genre: :reggae, uuid: reggae.uuid) { reggae } repo = Repo.new(Tune, source, mapper: mapper) repo.related_to(project).must_equal [ragga, reggae] end end end end