You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For numbers we should allow a comparison with a percent_off deviation.
The syntax: ut.expect( a_actual =>1.23 ).to_( be_within( a_pct => 1, a_expected => 1.23456789 ) )
should give success ut.expect( a_actual =>1.2 ).to_( be_within( a_pct => 1, a_expected => 1.23456789 ) )
should give success
Calculation logic.
a_actual between (a_expected - ((a_expected * a_pct)/100) ) and (a_expected + ((a_expected * a_pct)/100) )
that may not make a whole lot of sense..
more useful for dates would be if it meant "number of seconds difference"
ie so 1-jan-2017 10:12:13 would match 1-jan-2017 10:12:14
I think that for dates, timestamps and intervals we should not think of within in terms of PCT.
For those data-types we should use interval as a measure of allowed deviation.
so the syntax woule be like:
INTERVAL DAY TO SECOND stores a period of time in terms of days, hours, minutes, and seconds. This data type is useful for representing the precise difference between two datetime values.
I like the Interval literals to express an interval in a human readable way. This helps especially for this use case. A comparison/assert with a tolerance. As @lwasylow I'd prefer a syntax as follows:
It's a well know equal comparison with an optional tolerance.
The tolerance can be an interval (year to month or day to second) or a number. Tolerance is applicable for datetime, timestamp, number comparisons. In case of datetime/timestamp a number tolerance is interpreted in days. This would be consistent with the datetime arithmetic of the Oracle Database.
should we allow for interval/interval/interval as acual/expexted/tolerance
Yes.
what syntax shoul be used for this expectation?
I favor (...).to_be(...).with_tolerance(...) over (...).to_be_within(...).of_(...). For me it is clearer which is the "tolerance" and which the value to compare to. However, there might be other things to consider like the return type of a method (making a fluent API harder or easier) and the consistency to other methods. I have not looked at these aspects.
For me a tolerance feel a better being second as for first part of name this can probably be modified there are multiple options like: nearly_equal or approx_equal instead of to_be
I think with_tolerance also is a much clearer expresion and falls into a format as we passing expected first and then a modifier of that comparision whether is a join by or a distance.
We need to change first part as currently we bene looking on to be within(3).of_(5) where 3 was a distance and 5 was a point from distance was measured.
@lwasylow you were suggesting nearly_equal or approx_equal and @jgebalto_be_close_to instead of to_be. So, my question was why? Just because you like it more or is there some limitation regarding overloading of to_be?
@PhilippSalvisberg, apologies I misread your post. For some reason I assumed you reffered to to_be_within. There is no restriction in to_be. As for syntax I personally think to_be is not descriptive and can be be easily misunderstood with equal. Personally I would prefer something more descriptive as well as distance being mandatory value positive, with zero is just a worse version of equal.
Hope that makes sense and clears.
passing matcher to expectation: ut.expect(l_actual).to_( matcher(...)[.options(...)...] );
So for fuzzy matcher we would need to name it be / ut_be.
That way we would end up with syntax like: ut.expect( 1 ).to_( be( 2 ).with_tolerance( 1 ) ); ut.expect( 1 ).not_to( be( 2 ).with_tolerance( 1 ) ); ut.expect( 1 ).to_be( 2 ).with_tolerance( 1 ); ut.expect( 1 ).not_to_be( 2 ).with_tolerance( 1 );
The be in OOP it s used to represent equal identity in sense of "the same object instance" not "the same value" or "identical object".
I think that be is too strong for this matcher and actually in PL/SQL it is quite impossible for two variables to point to (represent) the same object instance as assignments in PLSQL are done by deep copy of a variable.
We could have used be for equality but since we have decided to use to_equal I se no value in changing it now.
Overloading to_equal to support tolerance would also cause trouble with support for non-scalar data-types.
It will not be possible to apply with_tolerance to cursor, object type, nested table.
So we would need to add safety net for invalid syntax like: ut.expect( l_actual_cursor ).to_be( l_expected_cursor ).with_tolerance( 1 );
Thank you, @jgebal for the detailed answer. You got me with the link to RSpec (and because utPLSQL is based on that) and the explanation regarding the technical issues.
Activity
jgebal commentedon Nov 21, 2016
Similar should be available for dates, timestamps and intevals (once suported)
Pazus commentedon Dec 7, 2016
Rescheduled to version 3.1
proldan commentedon Mar 22, 2017
What should
pctmean in dates and intervals? Should it be a percentage of a day for dates?Shoelace commentedon Mar 23, 2017
that may not make a whole lot of sense..
more useful for dates would be if it meant "number of seconds difference"
ie so 1-jan-2017 10:12:13 would match 1-jan-2017 10:12:14
i guess you could say 50% would mean +/- 12hours
This commit solves issue utPLSQL#77
jgebal commentedon May 15, 2017
I think that for dates, timestamps and intervals we should not think of within in terms of PCT.
For those data-types we should use interval as a measure of allowed deviation.
so the syntax woule be like:
20 remaining items
PhilippSalvisberg commentedon Jun 15, 2020
The definition of the
INTERVAL DAY TO SECOND Data TypeisI like the
Interval literalsto express an interval in a human readable way. This helps especially for this use case. A comparison/assert with a tolerance. As @lwasylow I'd prefer a syntax as follows:and for the second example
It's a well know
equalcomparison with an optional tolerance.The tolerance can be an interval (year to month or day to second) or a number. Tolerance is applicable for datetime, timestamp, number comparisons. In case of datetime/timestamp a number tolerance is interpreted in days. This would be consistent with the datetime arithmetic of the Oracle Database.
jgebal commentedon Jun 16, 2020
I think there are two aspects here
Seems like you're supportive of the firts but suggest to use alternative syntax to
(...).to_be_within(...).of_(...)PhilippSalvisberg commentedon Jun 16, 2020
Yes.
I favor
(...).to_be(...).with_tolerance(...)over(...).to_be_within(...).of_(...). For me it is clearer which is the "tolerance" and which the value to compare to. However, there might be other things to consider like the return type of a method (making a fluent API harder or easier) and the consistency to other methods. I have not looked at these aspects.lwasylow commentedon Jun 16, 2020
For me a tolerance feel a better being second as for first part of name this can probably be modified there are multiple options like:
nearly_equalorapprox_equalinstead ofto_beI think
with_tolerancealso is a much clearer expresion and falls into a format as we passing expected first and then a modifier of that comparision whether is a join by or a distance.jgebal commentedon Jun 16, 2020
One more:
ut.expect(...).to_be_close_to(...).with_tolerance(...);
PhilippSalvisberg commentedon Jun 16, 2020
Why change the first part and not keep the existing variant
to_be? I seewith_toleranceoptional because the default is a tolerance of zero.lwasylow commentedon Jun 16, 2020
We need to change first part as currently we bene looking on to be within(3).of_(5) where 3 was a distance and 5 was a point from distance was measured.
PhilippSalvisberg commentedon Jun 17, 2020
@lwasylow you were suggesting
nearly_equalorapprox_equaland @jgebalto_be_close_toinstead ofto_be. So, my question was why? Just because you like it more or is there some limitation regarding overloading ofto_be?lwasylow commentedon Jun 17, 2020
@PhilippSalvisberg, apologies I misread your post. For some reason I assumed you reffered to
to_be_within. There is no restriction into_be. As for syntax I personally think to_be is not descriptive and can be be easily misunderstood with equal. Personally I would prefer something more descriptive as well as distance being mandatory value positive, with zero is just a worse version of equal.Hope that makes sense and clears.
PhilippSalvisberg commentedon Jun 17, 2020
@lwasylow no problem.
Actually that's what I like. Standalone
to_bereally means "to be equal to ... with zero tolerance". You can express it explicitly like thisor like this
And it feels right. And also with non-default values for tolerance like this:
I am therefore voting against the introduction of additional keywords. Because I think it unnecessarily bloats the syntax of utPLSQL.
We don't have to agree . Do whatever you and @jgebal think is best.
jgebal commentedon Jun 21, 2020
@PhilippSalvisberg, @lwasylow
Keep in mind that utPSLQL suppoers two flavors of syntax for expectations:
ut.expect(l_actual).to_**matcher(...)[.options(...)...]**;ut.expect(l_actual).to_( matcher(...)[.options(...)...] );So for fuzzy matcher we would need to name it
be/ut_be.That way we would end up with syntax like:
ut.expect( 1 ).to_( be( 2 ).with_tolerance( 1 ) );ut.expect( 1 ).not_to( be( 2 ).with_tolerance( 1 ) );ut.expect( 1 ).to_be( 2 ).with_tolerance( 1 );ut.expect( 1 ).not_to_be( 2 ).with_tolerance( 1 );The be in OOP it s used to represent equal identity in sense of "the same object instance" not "the same value" or "identical object".
I think that be is too strong for this matcher and actually in PL/SQL it is quite impossible for two variables to point to (represent) the same object instance as assignments in PLSQL are done by deep copy of a variable.
We could have used
befor equality but since we have decided to useto_equalI se no value in changing it now.Overloading
to_equalto support tolerance would also cause trouble with support for non-scalar data-types.It will not be possible to apply
with_toleranceto cursor, object type, nested table.So we would need to add safety net for invalid syntax like:
ut.expect( l_actual_cursor ).to_be( l_expected_cursor ).with_tolerance( 1 );The
be_withinis described as part of RSpec, which was as a reference for Domain Specific Language specification in utPLSQL expectations:https://relishapp.com/rspec/rspec-expectations/v/3-9/docs/built-in-matchers/be-within-matcher
Thanks for all the inputs.
I'm in favor of the following:
PhilippSalvisberg commentedon Jun 21, 2020
Thank you, @jgebal for the detailed answer. You got me with the link to RSpec (and because utPLSQL is based on that) and the explanation regarding the technical issues.
So, I support your approach.
pesse commentedon Jun 22, 2020
@jgebal 's comments - as always a treasure of knowledge! ❤