Lab42::BasicConstraints
N.B. All these code examples are verified with the speculate_about gem
A collection of constraints
Context A Quick Overview
Given That we alias Lab42::BasicConstraints
to BC
require "lab42/basic_constraints/alias"
Given
let :all_basic_constraints do
%i[
all_digits_string alphanumeric_string
bool
date date_time day
hour
int
lowercase_string
minute month
non_negative_int non_negative_number number
positive_int positive_number
second string symbol
uppercase_string
year
]
end
let :all_parametrized_constraints do
%i[ int_range limited_string ]
end
Then All Basic Constraints can be listed by means of BC.all_constraints
expect( Set.new(BC.all_constraints) ).to eq(Set.new(all_basic_constraints + all_parametrized_constraints))
And they are implemented of course
all_basic_constraints.each do | constraint_name |
expect( BC.from_symbol(constraint_name) ).to be_a(BC::Constraint)
end
expect( BC.int_range(min: 0) ).to be_a(BC::Constraint)
expect( BC.limited_string(max: 10) ).to be_a(BC::Constraint)
So we got the ball, now use it!
The ball, BTW, is a Lab42::Result
see lab42_result gem for more info
Given the non_negative_int
constraint
let(:non_neg_int) {BC.non_negative_int}
Then we can just call it
non_neg_int.(0) in [:ok, nil]
non_neg_int.(-1) in [error, ]
expect(error).to eq(BC::ConstraintError)
expect().to eq("-1 is not a legal non_negative_int")
Example: Get a constraint by symbol
pn = BC.from_symbol(:positive_number)
pn.(1) in [:ok, nil]
Example: Constraints with and without defaults
expect {BC.from_symbol(:positive_number).default}
.to raise_error(Lab42::BasicConstraints::MissingDefaultError, "Constraint positive_number has no predefined default")
expect( BC.non_negative_int.default ).to eq(0)
Example: Avoiding the Exception, à la Hash#fetch
expect( BC.from_symbol(:positive_number).default{42} ).to eq(42)
Context Time's a Sticky Wicket
... but as defaults are defined for runtime that shall really help us with that
Given that we have timecop
require "timecop"
let(:d) {BC.date}
let(:error) {Lab42::BasicConstraints::ConstraintError}
Then we can show that the year's default value will not be at compile time but at runtime:
year = BC.year
Timecop.freeze(Time.utc(1905)) do
expect( year.default ).to eq(1905)
end
Of course a check for legality is performed
Example: Illegal Dates
d.("2020-00-01") in [raised, ]
expect( raised ).to eq(error)
expect( ).to eq(%{"2020-00-01" is not a legal date})
Context Equality More Of A Tricky Sticker
And Most Surprisingly
expect(BC.bool).not_to eq(BC.bool)
However in many cases the name and the default say a lot about a constraint's behavior
Given
let(:natural) {BC.non_negative_int}
let(:def42) {BC.non_negative_int.set_default(42)}
Then we can compare as follows
expect( natural.name ).to eq(BC.non_negative_int.name)
expect( natural.default ).to eq(0)
expect( def42.name ).to eq(BC.non_negative_int.name)
expect( def42.default ).to eq(42)
Detailed Description of all Constraints
date_and_time_constraints div_constraints string_constraints
LICENSE
Copyright 2020 Robert Dober [email protected]
Apache-2.0 c.f LICENSE