Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content

Add be_within 'fuzzy' matcher #77

Closed

Description

@jgebal

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) )

Activity

  1. added this to the milestone on Oct 17, 2016
  2. self-assigned this
    on Oct 18, 2016
  3. jgebal commented on Nov 21, 2016

    @jgebal
    MemberAuthor

    Similar should be available for dates, timestamps and intevals (once suported)

  4. modified the milestones: , on Dec 7, 2016
  5. Pazus commented on Dec 7, 2016

    @Pazus
    Member

    Rescheduled to version 3.1

  6. proldan commented on Mar 22, 2017

    @proldan
    Contributor

    What should pct mean in dates and intervals? Should it be a percentage of a day for dates?

  7. Shoelace commented on Mar 23, 2017

    @Shoelace
    Member

    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

  8. jgebal commented on May 15, 2017

    @jgebal
    MemberAuthor

    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:

    ut.expect(sysdate).to_( be_within( interval '1' day, to_date( '20170515', 'yyyy-mm-dd' ) ) );
  9. removed this from the v3.1.0 milestone on Feb 5, 2018
  10. 20 remaining items

  11. PhilippSalvisberg commented on Jun 15, 2020

    @PhilippSalvisberg
    Member

    The definition of the INTERVAL DAY TO SECOND Data Type is

    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:

    ut.expect(l_actual_interval).to_be(l_expected_interval).with_tolerance(interval '5' minute);
    

    and for the second example

    ut.expect(l_actual_date).to_be(timestamp '2020-06-14 22:11.34').with_tolerance(interval '5' minute);
    

    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.

  12. jgebal commented on Jun 16, 2020

    @jgebal
    MemberAuthor

    I think there are two aspects here

    • should we allow for interval/interval/interval as acual/expexted/tolerance
    • what syntax shoul be used for this expectation?

    Seems like you're supportive of the firts but suggest to use alternative syntax to (...).to_be_within(...).of_(...)

  13. PhilippSalvisberg commented on Jun 16, 2020

    @PhilippSalvisberg
    Member

    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.

  14. lwasylow commented on Jun 16, 2020

    @lwasylow
    Member

    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.

  15. jgebal commented on Jun 16, 2020

    @jgebal
    MemberAuthor

    One more:
    ut.expect(...).to_be_close_to(...).with_tolerance(...);

  16. PhilippSalvisberg commented on Jun 16, 2020

    @PhilippSalvisberg
    Member

    Why change the first part and not keep the existing variant to_be? I see with_tolerance optional because the default is a tolerance of zero.

  17. lwasylow commented on Jun 16, 2020

    @lwasylow
    Member

    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.

  18. PhilippSalvisberg commented on Jun 17, 2020

    @PhilippSalvisberg
    Member

    @lwasylow you were suggesting nearly_equal or approx_equal and @jgebal to_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?

  19. lwasylow commented on Jun 17, 2020

    @lwasylow
    Member

    @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.

  20. PhilippSalvisberg commented on Jun 17, 2020

    @PhilippSalvisberg
    Member

    @lwasylow no problem.

    As for syntax I personally think to_be is not descriptive and can be be easily misunderstood with equal

    Actually that's what I like. Standalone to_be really means "to be equal to ... with zero tolerance". You can express it explicitly like this

    ut.expect(l_actual).to_be(l_expected).with_tolerance(0);
    

    or like this

    ut.expect(l_actual).to_be(l_expected);
    

    And it feels right. And also with non-default values for tolerance like this:

    ut.expect(l_actual).to_be(l_expected).with_tolerance(0.5);
    

    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.

  21. jgebal commented on Jun 21, 2020

    @jgebal
    MemberAuthor

    @PhilippSalvisberg, @lwasylow

    Keep in mind that utPSLQL suppoers two flavors of syntax for expectations:

    • shortcut syntax: ut.expect(l_actual).to_**matcher(...)[.options(...)...]**;
    • 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 );

    The be_within is 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:

    begin
      ut.expect(interval).to_be_within(interval).of_(interval);
    
      ut.expect(date).to_be_within(interval).of_(interval);
      ut.expect(timestamp).to_be_within(interval).of_(timestamp);
      ut.expect(timestamp_tz).to_be_within(interval).of_(timestamp_tz);
      ut.expect(timestamp_ltz).to_be_within(interval).of_(timestamp_ltz);
    
      ut.expect(number).to_be_within(number).of_(number);
      ut.expect(number).to_be_within_pct(number).of_(number);
    end;
  22. PhilippSalvisberg commented on Jun 21, 2020

    @PhilippSalvisberg
    Member

    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.

  23. pesse commented on Jun 22, 2020

    @pesse
    Member

    @jgebal 's comments - as always a treasure of knowledge! ❤

  24. linked a pull request that will close this issueFeature/rework matcher #1076on Feb 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions