Skip to content

Commit

Permalink
refactoring the LazyDocumentHeader document to properly set source an…
Browse files Browse the repository at this point in the history
…d options
  • Loading branch information
marcosgz committed Aug 7, 2024
1 parent 07125cc commit b669ab0
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 53 deletions.
2 changes: 1 addition & 1 deletion lib/esse/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Document

def initialize(object, **options)
@object = object
@options = options
@options = options.freeze
end

# @return [String, Number] the document ID
Expand Down
57 changes: 32 additions & 25 deletions lib/esse/lazy_document_header.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,61 +17,68 @@ def self.coerce(value)
if value.is_a?(Esse::LazyDocumentHeader)
value
elsif value.is_a?(Esse::Document)
new(value.doc_header)
source = value.doc_header
new(id: source[:_id], type: source[:_type], routing: source[:routing], **value.options)
elsif value.is_a?(Hash)
resp = value.transform_keys do |key|
case key
when :_id, :id, '_id', 'id'
:_id
:id
when :_routing, :routing, '_routing', 'routing'
:routing
when :_type, :type, '_type', 'type'
:_type
:type
else
key.to_sym
end
end
new(resp)
resp[:id] ||= nil
new(**resp)
elsif String === value || Integer === value
new(_id: value)
new(id: value)
end
end

def initialize(attributes)
@attributes = attributes
attr_reader :id, :type, :routing, :options

def initialize(id:, type: nil, routing: nil, **extra_attributes)
@id = id
@type = type
@routing = routing
@options = extra_attributes.freeze
end

def valid?
!@attributes[:_id].nil?
!id.nil?
end

def to_h
@attributes
options.merge(_id: id).tap do |hash|
hash[:_type] = type if type
hash[:routing] = routing if routing
end
end

def id
@attributes.fetch(:_id)
def to_doc(source = {})
Document.new(self, source: source)
end

def type
@attributes[:_type]
def eql?(other)
self.class == other.class && id == other.id && type == other.type && routing == other.routing
end
alias_method :==, :eql?

def routing
@attributes[:routing]
end
class Document < Esse::Document
extend Forwardable

def options
@attributes.reject { |key, _| %i[_id _type routing].include?(key) }
end
def_delegators :object, :id, :type, :routing, :options

def to_doc(source = {})
HashDocument.new(source.merge(@attributes))
end
attr_reader :source

def eql?(other)
self.class == other.class && @attributes == other.instance_variable_get(:@attributes)
def initialize(lazy_header, source: {})
@source = source
super(lazy_header)
end
end
alias_method :==, :eql?
end
end
68 changes: 41 additions & 27 deletions spec/esse/lazzy_document_header_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

RSpec.describe Esse::LazyDocumentHeader do
let(:doc) { described_class.new(object.merge(options)) }
let(:object) { {} }
let(:object) { { id: nil } }
let(:options) { {} }

describe '#valid?' do
Expand All @@ -14,8 +14,8 @@
expect(doc.valid?).to be_falsey
end

context 'when _id is present' do
let(:object) { { _id: 1 } }
context 'when id is present' do
let(:object) { { id: 1 } }

it 'returns true' do
expect(doc.valid?).to be_truthy
Expand All @@ -26,14 +26,10 @@
describe '#id' do
it { expect(doc).to respond_to :id }

it 'should raise KeyError' do
expect { doc.id }.to raise_error
end
context 'when id is present' do
let(:object) { { id: 1 } }

context 'when _id is present' do
let(:object) { { _id: 1 } }

it 'returns the _id' do
it 'returns the id' do
expect(doc.id).to eq(1)
end
end
Expand All @@ -47,9 +43,9 @@
end

context 'when _type is present' do
let(:object) { { _type: 'foo' } }
let(:object) { { id: 1, type: 'foo' } }

it 'returns the _type' do
it 'returns the type' do
expect(doc.type).to eq('foo')
end
end
Expand All @@ -63,7 +59,7 @@
end

context 'when _routing is present' do
let(:object) { { routing: 'foo' } }
let(:object) { { id: 1, routing: 'foo' } }

it 'returns the _routing' do
expect(doc.routing).to eq('foo')
Expand All @@ -75,30 +71,30 @@
it { expect(doc).to respond_to :to_h }

it 'returns the object' do
expect(doc.to_h).to eq(object)
expect(doc.to_h).to eq(_id: nil)
end

context 'when _id is present' do
let(:object) { { _id: 1 } }
let(:object) { { id: 1 } }

it 'returns the object' do
expect(doc.to_h).to eq(object)
expect(doc.to_h).to eq(_id: 1)
end
end

context 'when _type is present' do
let(:object) { { _type: 'foo' } }
let(:object) { { id: 2, type: 'foo' } }

it 'returns the object' do
expect(doc.to_h).to eq(object)
expect(doc.to_h).to eq(_id: 2, _type: 'foo')
end
end

context 'when routing is present' do
let(:object) { { routing: 'foo' } }
let(:object) { { id: 3, routing: 'foo' } }

it 'returns the object' do
expect(doc.to_h).to eq(object)
expect(doc.to_h).to eq(_id: 3, routing: 'foo')
end
end
end
Expand All @@ -111,7 +107,7 @@
end

context 'when value is a LazyDocumentHeader' do
let(:object) { described_class.new(_id: 1) }
let(:object) { described_class.new(id: 1) }

it 'returns the same instance' do
expect(described_class.coerce(object)).to eq(object)
Expand Down Expand Up @@ -176,18 +172,36 @@
end

describe '#to_doc' do
let(:options) { { admin: true } }
let(:object) { { id: 1, routing: 'il', type: 'state' } }

it { expect(doc).to respond_to :to_doc }

it 'returns a HashDocument instance' do
expect(doc.to_doc).to be_a(Esse::HashDocument)
it 'returns a Esse::Document instance' do
expect(doc.to_doc).to be_a(Esse::Document)
end

it 'returns a Esse::Document instance with the id' do
expect(doc.to_doc.id).to eq(1)
end

it 'returns a Esse::Document instance routing' do
expect(doc.to_doc.routing).to eq('il')
end

it 'returns a Esse::Document instance with the type' do
expect(doc.to_doc.type).to eq('state')
end

it 'returns a HashDocument instance with the object as source' do
expect(doc.to_doc.source).to eq(object)
it 'returns a Esse::Document instance with the options' do
expect(doc.to_doc.options).to eq(admin: true)
end

it 'returns a HashDocument instance with the object as source and the given source' do
expect(doc.to_doc(foo: 'bar').source).to eq(object.merge(foo: 'bar'))
it 'returns a Esse::Document instance with the object as source and the given source' do
new_doc = doc.to_doc(foo: 'bar')
expect(new_doc.source).to eq(foo: 'bar')
expect(new_doc.object).to eq(doc)
expect(new_doc.options).to eq(admin: true)
end
end

Expand Down

0 comments on commit b669ab0

Please sign in to comment.