1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
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
|