gems.virtus-1.0.5.spec.integration.custom_collection_attributes_spec.rb Maven / Gradle / Ivy
The newest version!
require 'spec_helper'
describe 'custom collection attributes' do
let(:library) { Examples::Library.new }
let(:books) { library.books }
before do
module Examples end
Examples.const_set 'BookCollection', book_collection_class
module Examples
class Book
include Virtus
attribute :title, String
end
class BookCollectionAttribute < Virtus::Attribute::Collection
primitive BookCollection
end
class Library
include Virtus
attribute :books, BookCollection[Book]
end
end
end
after do
[:BookCollectionAttribute, :BookCollection, :Book, :Library].each do |const|
Examples.send(:remove_const, const)
end
end
shared_examples_for 'a collection' do
it 'can be used as Virtus attributes' do
attribute = Examples::Library.attribute_set[:books]
expect(attribute).to be_kind_of(Examples::BookCollectionAttribute)
end
it 'defaults to an empty collection' do
books_should_be_an_empty_collection
end
it 'coerces nil' do
library.books = nil
books_should_be_an_empty_collection
end
it 'coerces an empty array' do
library.books = []
books_should_be_an_empty_collection
end
it 'coerces an array of attribute hashes' do
library.books = [{ :title => 'Foo' }]
expect(books).to be_kind_of(Examples::BookCollection)
end
it 'coerces its members' do
library.books = [{ :title => 'Foo' }]
expect(books.count).to eq(1)
expect(books.first).to be_kind_of(Examples::Book)
end
def books_should_be_an_empty_collection
expect(books).to be_kind_of(Examples::BookCollection)
expect(books.count).to eq(0)
end
end
context 'with an array subclass' do
let(:book_collection_class) { Class.new(Array) }
it_behaves_like 'a collection'
end
context 'with an enumerable' do
require 'forwardable'
let(:book_collection_class) {
Class.new do
extend Forwardable
include Enumerable
def_delegators :@array, :each, :<<
def initialize(*args)
@array = Array[*args]
end
def self.[](*args)
new(*args)
end
end
}
it_behaves_like 'a collection'
end
end