# frozen_string_literal: true RSpec.shared_examples_for 'Dry::Types::Nominal without primitive' do def be_boolean satisfy { |x| x == true || x == false } end describe '#constrained?' do it 'returns a boolean value' do expect(type.constrained?).to be_boolean end end describe '#default?' do it 'returns a boolean value' do expect(type.default?).to be_boolean end end describe '#valid?' do it 'returns a boolean value' do expect(type.valid?(1)).to be_boolean end end describe '#eql?' do it 'has #eql? defined' do expect(type).to eql(type) end end describe '#==' do it 'has #== defined' do expect(type).to eq(type) end end describe '#optional?' do it 'returns a boolean value' do expect(type.optional?).to be_boolean end end describe '#to_s' do it 'returns a custom string representation' do expect(type.to_s).to start_with('#<Dry::Types') if type.class.name.start_with?('Dry::Types') end end describe '#to_proc' do subject(:callable) { type.to_proc } it 'converts a type to a proc' do expect(callable).to be_a(Proc) end end end RSpec.shared_examples_for 'Dry::Types::Nominal#meta' do describe '#meta' do it 'allows setting meta information' do with_meta = type.meta(foo: :bar).meta(baz: '1') expect(with_meta).to be_instance_of(type.class) expect(with_meta.meta).to eql(foo: :bar, baz: '1') end it 'equalizes on empty meta' do expect(type).to eql(type.meta({})) end it 'equalizes on filled meta' do expect(type).to_not eql(type.meta(i_am: 'different')) end it 'is locally immutable' do expect(type.meta).to be_a ::Hash expect(type.meta).to be_frozen expect(type.meta).not_to have_key :immutable_test derived = type.meta(immutable_test: 1) expect(derived.meta).to be_frozen expect(derived.meta).to eql(immutable_test: 1) expect(type.meta).not_to have_key :immutable_test end end describe '#pristine' do it 'erases meta' do expect(type.meta(foo: :bar).pristine).to eql(type) end end end RSpec.shared_examples_for Dry::Types::Nominal do it_behaves_like 'Dry::Types::Nominal without primitive' describe '#primitive' do it 'returns a class' do expect(type.primitive).to be_instance_of(Class) end end describe '#constructor' do it 'returns a constructor' do constructor = type.constructor(&:to_s) expect(constructor).to be_a(Dry::Types::Type) end end end RSpec.shared_examples_for 'a constrained type' do |options = { inputs: Object.new }| inputs = options[:inputs] let(:fallback) { Object.new } describe '#call' do it 'yields a block on failure' do Array(inputs).each do |input| expect(type.(input) { fallback }).to be(fallback) end end it 'throws an error on invalid input' do Array(inputs).each do |input| expect { type.(input) }.to raise_error(Dry::Types::CoercionError) end end end end RSpec.shared_examples_for 'a nominal type' do |inputs: Object.new| describe '#call' do it 'always returns the input back' do Array(inputs).each do |input| expect(type.(input) { fail }).to be(input) expect(type.(input)).to be(input) end end end end