spec/praxis-blueprints/blueprint_spec.rb in praxis-blueprints-3.2 vs spec/praxis-blueprints/blueprint_spec.rb in praxis-blueprints-3.3
- old
+ new
@@ -1,12 +1,12 @@
+# frozen_string_literal: true
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe Praxis::Blueprint do
-
subject(:blueprint_class) { Person }
- its(:family){ should eq('hash') }
+ its(:family) { should eq('hash') }
context 'deterministic examples' do
it 'works' do
person_1 = Person.example('person 1')
person_2 = Person.example('person 1')
@@ -50,21 +50,18 @@
end
its(:finalized?) { should be(true) }
end
-
context '.finalize on that subclass' do
before do
blueprint_class.should_receive(:_finalize!).and_call_original
blueprint_class.finalize!
end
its(:finalized?) { should be(true) }
-
end
-
end
context 'creating a base abstract Blueprint class without attributes' do
subject!(:blueprint_class) do
Class.new(Praxis::Blueprint)
@@ -74,11 +71,10 @@
blueprint_class.should_receive(:_finalize!).and_call_original
blueprint_class.should_not_receive(:define_attribute)
blueprint_class.finalize!
blueprint_class.finalized?.should be(true)
end
-
end
it 'has an inner Struct class for the attributes' do
blueprint_class.attribute.type.should be blueprint_class::Struct
end
@@ -86,11 +82,10 @@
context '.views' do
it { blueprint_class.should respond_to(:views) }
it 'sorta has view objects' do
blueprint_class.views.should have_key(:default)
end
-
end
context 'an instance' do
shared_examples 'a blueprint instance' do
let(:expected_name) { blueprint_instance.name }
@@ -111,46 +106,43 @@
it { should be_empty }
end
end
end
-
context 'from Blueprint.example' do
subject(:blueprint_instance) { blueprint_class.example }
it_behaves_like 'a blueprint instance'
end
context 'wrapping an object' do
-
let(:data) do
{
name: 'Bob',
full_name: FullName.example,
address: Address.example,
- email: "bob@example.com",
+ email: 'bob@example.com',
aliases: [],
prior_addresses: [],
- parents: { father: Randgen.first_name, mother: Randgen.first_name},
- href: "www.example.com",
+ parents: { father: Randgen.first_name, mother: Randgen.first_name },
+ href: 'www.example.com',
alive: true
}
end
let(:resource) { blueprint_class.load(data).object }
subject(:blueprint_instance) { blueprint_class.new(resource) }
-
it_behaves_like 'a blueprint instance'
context 'creating additional blueprint instances from that object' do
subject(:additional_instance) { blueprint_class.new(resource) }
context 'with caching enabled' do
around do |example|
Praxis::Blueprint.caching_enabled = true
- Praxis::Blueprint.cache = Hash.new { |h,k| h[k] = Hash.new }
+ Praxis::Blueprint.cache = Hash.new { |h, k| h[k] = {} }
example.run
Praxis::Blueprint.caching_enabled = false
Praxis::Blueprint.cache = nil
end
@@ -163,19 +155,16 @@
end
context 'with caching disabled' do
it { should_not be blueprint_instance }
end
-
end
-
end
-
end
context '.describe' do
- let(:shallow ) { false }
+ let(:shallow) { false }
let(:example_object) { nil }
before do
expect(blueprint_class.attribute.type).to receive(:describe).with(shallow, example: example_object).ordered.and_call_original
end
@@ -185,22 +174,21 @@
# Describing a Person also describes the :myself and :friends attributes. They are both a Person and a Coll of Person.
# This means that Person type `describe` is called two more times, thes times with shallow=true
expect(blueprint_class.attribute.type).to receive(:describe).with(true, example: example_object).twice.and_call_original
end
- subject(:output){ blueprint_class.describe }
+ subject(:output) { blueprint_class.describe }
- its([:name]){ should eq(blueprint_class.name)}
- its([:id]){ should eq(blueprint_class.id)}
- its([:views]){ should be_kind_of(Hash)}
- its(:keys){ should_not include(:anonymous) }
+ its([:name]) { should eq(blueprint_class.name) }
+ its([:id]) { should eq(blueprint_class.id) }
+ its([:views]) { should be_kind_of(Hash) }
+ its(:keys) { should_not include(:anonymous) }
it 'should contain the an entry for each view' do
subject[:views].keys.should include(:default, :current, :extended, :master)
end
end
-
context 'for shallow descriptions' do
let(:shallow) { true }
it 'should not include views' do
blueprint_class.describe(true).key?(:views).should be(false)
@@ -216,12 +204,12 @@
klass.finalize!
klass
end
it 'reports their anonymous-ness' do
description = blueprint_class.describe(true)
- expect( description ).to have_key(:anonymous)
- expect( description[:anonymous] ).to be(true)
+ expect(description).to have_key(:anonymous)
+ expect(description[:anonymous]).to be(true)
end
end
end
context 'with an example' do
@@ -239,51 +227,53 @@
it 'outputs examples for leaf values using the provided example' do
output[:attributes][:name][:example].should eq example.name
output[:attributes][:age][:example].should eq example.age
+ output[:attributes][:aliases].should have_key(:example)
+ output[:attributes][:aliases][:example].should eq example.aliases.dump
+
output[:attributes][:full_name].should_not have_key(:example)
- output[:attributes][:aliases].should_not have_key(:example)
parents_attributes = output[:attributes][:parents][:type][:attributes]
parents_attributes[:father][:example].should eq example.parents.father
parents_attributes[:mother][:example].should eq example.parents.mother
end
end
end
context '.validate' do
- let(:hash) { {name: 'bob'} }
+ let(:hash) { { name: 'bob' } }
let(:person) { Person.load(hash) }
subject(:errors) { person.validate }
context 'that is valid' do
it { should be_empty }
end
context 'with invalid sub-attribute' do
- let(:hash) { {name: 'bob', address: {state: "ME"}} }
+ let(:hash) { { name: 'bob', address: { state: 'ME' } } }
it { should have(1).item }
its(:first) { should =~ /Attribute \$.address.state/ }
end
context 'for objects of the wrong type' do
it 'raises an error' do
- expect {
+ expect do
Person.validate(Object.new)
- }.to raise_error(ArgumentError, /Error validating .* as Person for an object of type Object/)
+ end.to raise_error(ArgumentError, /Error validating .* as Person for an object of type Object/)
end
end
end
context '.load' do
let(:hash) do
{
- :name => 'Bob',
- :full_name => {:first => 'Robert', :last => 'Robertson'},
- :address => {:street => 'main', :state => 'OR'}
+ name: 'Bob',
+ full_name: { first: 'Robert', last: 'Robertson' },
+ address: { street: 'main', state: 'OR' }
}
end
subject(:person) { Person.load(hash) }
it { should be_kind_of(Person) }
@@ -296,31 +286,28 @@
context 'for an Attributor::Model' do
subject(:full_name) { person.full_name }
it { should be_kind_of(FullName) }
end
end
-
end
-
context 'decorators' do
let(:name) { 'Soren II' }
let(:object) { Person.example.object }
subject(:person) { Person.new(object, decorators) }
-
context 'as a hash' do
- let(:decorators) { {name: name} }
+ let(:decorators) { { name: name } }
it do
person.name.should eq('Soren II')
end
its(:name) { should be(name) }
context 'an additional instance with the equivalent hash' do
- subject(:additional_person) { Person.new(object, {name: name}) }
+ subject(:additional_person) { Person.new(object, name: name) }
it { should_not be person }
end
context 'an additional instance with the same hash object' do
subject(:additional_person) { Person.new(object, decorators) }
@@ -332,42 +319,37 @@
it { should_not be person }
end
end
context 'as an object' do
- let(:decorators) { double("decorators", name: name) }
+ let(:decorators) { double('decorators', name: name) }
its(:name) { should be(name) }
context 'an additional instance with the same object' do
subject(:additional_person) { Person.new(object, decorators) }
it { should_not be person }
end
end
-
end
-
context 'with a provided :reference option on attributes' do
context 'that does not match the value set on the class' do
-
subject(:mismatched_reference) do
Class.new(Praxis::Blueprint) do
self.reference = Class.new(Praxis::Blueprint)
attributes(reference: Class.new(Praxis::Blueprint)) {}
end
end
it 'should raise an error' do
- expect {
+ expect do
mismatched_reference.attributes
- }.to raise_error
+ end.to raise_error
end
-
end
end
-
context '.example' do
context 'with some attribute values provided' do
let(:name) { 'Sir Bobbert' }
subject(:person) { Person.example(name: name) }
its(:name) { should eq(name) }
@@ -375,11 +357,10 @@
end
context '.render' do
let(:person) { Person.example('1') }
it 'is an alias to dump' do
-
person.object.contents
rendered = Person.render(person, view: :default)
dumped = Person.dump(person, view: :default)
expect(rendered).to eq(dumped)
end
@@ -389,30 +370,26 @@
let(:person) { Person.example }
let(:view_name) { :default }
let(:render_opts) { {} }
subject(:output) { person.render(view: view_name, **render_opts) }
-
-
context 'with a sub-attribute that is a blueprint' do
-
it { should have_key(:name) }
it { should have_key(:address) }
it 'renders the sub-attribute correctly' do
output[:address].should have_key(:street)
output[:address].should have_key(:state)
end
it 'reports a dump error with the appropriate context' do
- person.address.should_receive(:state).and_raise("Kaboom")
- expect {
+ person.address.should_receive(:state).and_raise('Kaboom')
+ expect do
person.render(view: view_name, context: ['special_root'])
- }.to raise_error(/Error while dumping attribute state of type Address for context special_root.address. Reason: .*Kaboom/)
+ end.to raise_error(/Error while dumping attribute state of type Address for context special_root.address. Reason: .*Kaboom/)
end
end
-
context 'with sub-attribute that is an Attributor::Model' do
it { should have_key(:full_name) }
it 'renders the model correctly' do
output[:full_name].should be_kind_of(Hash)
output[:full_name].should have_key(:first)
@@ -420,11 +397,11 @@
end
end
context 'using the `fields` option' do
context 'as a hash' do
- subject(:output) { person.render(fields: {address: {state: true}}) }
+ subject(:output) { person.render(fields: { address: { state: true } }) }
it 'should only have the address rendered' do
output.keys.should eq [:address]
end
it 'address should only have state' do
output[:address].keys.should eq [:state]
@@ -436,7 +413,6 @@
output.keys.should == [:full_name]
end
end
end
end
-
end