Skip to content

Instantly share code, notes, and snippets.

@artemeff
Created July 13, 2015 12:11
Show Gist options
  • Save artemeff/eac1aaa169ff29931512 to your computer and use it in GitHub Desktop.
Save artemeff/eac1aaa169ff29931512 to your computer and use it in GitHub Desktop.
module IdentifiedCollection
module ClassMethods
attr_reader :objects
def identify_by(identity)
@objects = Hash.new
@identity = identity
end
def identity
@identity
end
def clean
@objects = Hash.new
end
end
module InstanceMethods
def initialize(*)
self.class.objects[identity] = self
end
def identity
send(self.class.identity)
end
end
def self.included(receiver)
receiver.extend ClassMethods
receiver.send :include, InstanceMethods
end
end
describe IdentifiedCollection do
class Dummy
include IdentifiedCollection
identify_by :name
attr_reader :name
def initialize(name)
@name = name
super
end
end
before { Dummy.clean }
context 'Class Methods' do
subject { Dummy }
context '#objects' do
it 'is Hash' do
expect(subject.objects).to be_a(Hash)
end
it 'has not objects by default' do
expect(subject.objects).to eq({})
end
end
context '#identity' do
it 'stores identity method name' do
expect(subject.identity).to eq(:name)
end
end
context '#clean' do
it 'cleans objects collection' do
obj = subject.new('john')
expect(subject.objects.size).to eq(1)
subject.clean
expect(subject.objects.size).to eq(0)
end
end
end
context 'Instance Methods' do
let(:name) { 'john doe' }
subject { Dummy.new(name) }
context '#identity' do
it 'returns object identity' do
expect(subject.identity).to eq(name)
end
end
end
context 'Integration' do
let!(:u1) { Dummy.new('john') }
let!(:u2) { Dummy.new('john') }
let!(:u3) { Dummy.new('doe') }
it 'adds two objects' do
expect(Dummy.objects.size).to eq(2)
expect(Dummy.objects).to include('john')
expect(Dummy.objects).to include('doe')
end
it 'adds the last one' do
expect(Dummy.objects['john']).to be(u2)
expect(Dummy.objects['john']).not_to be(u1)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment