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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
|
require 'spec_helper'
describe Virtus, '#attribute' do
let(:name) { :test }
let(:options) { {} }
shared_examples_for 'a class with boolean attribute' do
subject { Test }
let(:object) { subject.new }
it 'defines reader and writer' do
object.test = true
expect(object).to be_test
end
it 'defines predicate method' do
object.test = false
expect(object).to_not be_test
end
end
shared_examples_for 'an object with string attribute' do
it { is_expected.to respond_to(:test) }
it { is_expected.to respond_to(:test=) }
it 'can write and read the attribute' do
subject.test = :foo
expect(subject.test).to eql('foo')
end
end
it 'returns self' do
klass = Class.new { include Virtus }
expect(klass.attribute(:test, String)).to be(klass)
end
it 'raises error when :name is a reserved name on a class' do
klass = Class.new { include Virtus }
expect { klass.attribute(:attributes, Set) }.to raise_error(
ArgumentError, ':attributes is not allowed as an attribute name'
)
end
it 'raises error when :name is a reserved name on an instance' do
object = Class.new.new.extend(Virtus)
expect { object.attribute(:attributes, Set) }.to raise_error(
ArgumentError, ':attributes is not allowed as an attribute name'
)
end
it 'allows :attributes as an attribute name when mass-assignment is not included' do
klass = Class.new { include Virtus::Model::Core }
klass.attribute(:attributes, Set)
expect(klass.attribute_set[:attributes]).to be_instance_of(Virtus::Attribute::Collection)
end
it 'allows specifying attribute without type' do
klass = Class.new { include Virtus::Model::Core }
klass.attribute(:name)
expect(klass.attribute_set[:name]).to be_instance_of(Virtus::Attribute)
end
context 'with a class' do
context 'when type is Boolean' do
before :all do
class Test
include Virtus
attribute :test, Boolean
end
end
after :all do
Object.send(:remove_const, :Test)
end
it_behaves_like 'a class with boolean attribute'
end
context 'when type is "Boolean"' do
before :all do
class Test
include Virtus
attribute :test, 'Boolean'
end
end
after :all do
Object.send(:remove_const, :Test)
end
it_behaves_like 'a class with boolean attribute'
end
context 'when type is Axiom::Types::Boolean' do
before :all do
class Test
include Virtus
attribute :test, Axiom::Types::Boolean
end
end
after :all do
Object.send(:remove_const, :Test)
end
it_behaves_like 'a class with boolean attribute' do
before do
pending 'this will be fixed once Attribute::Boolean subclass is gone'
end
end
end
context 'when type is :Boolean' do
before :all do
class Test
include Virtus
attribute :test, 'Boolean'
end
end
after :all do
Object.send(:remove_const, :Test)
end
it_behaves_like 'a class with boolean attribute'
context 'with a subclass' do
it_behaves_like 'a class with boolean attribute' do
subject { Class.new(Test) }
it 'gets attributes from the parent class' do
Test.attribute :other, Integer
expect(subject.attribute_set[:other]).to eql(Test.attribute_set[:other])
end
end
end
end
context 'when type is Decimal' do
before :all do
class Test
include Virtus
attribute :test, Decimal
end
end
after :all do
Object.send(:remove_const, :Test)
end
it 'maps type to the corresponding axiom type' do
expect(Test.attribute_set[:test].type).to be(Axiom::Types::Decimal)
end
end
end
context 'with a module' do
let(:mod) {
Module.new {
include Virtus
attribute :test, String
}
}
let(:model) { Class.new }
context 'included in the class' do
before do
model.send(:include, mod)
end
it 'adds attributes from the module to a class that includes it' do
expect(model.attribute_set[:test]).to be_instance_of(Virtus::Attribute)
end
it_behaves_like 'an object with string attribute' do
subject { model.new }
end
end
context 'included in the class' do
it_behaves_like 'an object with string attribute' do
subject { model.new.extend(mod) }
end
end
end
context 'with an instance' do
subject { model.new }
let(:model) { Class.new }
before do
subject.extend(Virtus)
subject.attribute(:test, String)
end
it_behaves_like 'an object with string attribute'
end
context 'using custom module' do
subject { model.new }
let(:model) {
Class.new {
include Virtus.model { |config| config.coerce = false }
attribute :test, String
}
}
it { is_expected.to respond_to(:test) }
it { is_expected.to respond_to(:test=) }
it 'writes and reads attributes' do
subject.test = :foo
expect(subject.test).to be(:foo)
end
end
end
|