Thanks to visit codestin.com
Credit goes to github.com

Skip to content

not_to(contain) fails while not_to_contain passes #1245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
micdol opened this issue Feb 28, 2023 · 6 comments · Fixed by #1246
Closed

not_to(contain) fails while not_to_contain passes #1245

micdol opened this issue Feb 28, 2023 · 6 comments · Fixed by #1246
Assignees
Labels
Milestone

Comments

@micdol
Copy link

micdol commented Feb 28, 2023

Describe the bug
Logically not_to(contain) should be the same as not_to_contain however the former fails while the latter passes. See reproduction steps for code.

Provide version info
utPLSQL: v3.1.14.4072-develop
Database: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.18.0.0.0

Information about client software
SQLDeveloper, SQLPlus cmd line

To Reproduce

create or replace package example as
    --%suite(example)

    --%test
    procedure not_to_contain_passes;

    --%test
    procedure not_to_bracket_contain_bracket_fails;
end;
/

create or replace package body example as
    procedure not_to_contain_passes
        is
        c1 sys_refcursor;
        c2 sys_refcursor;
    begin
        open c1 for select 'a' as letter from dual union all select 'b' from dual;
        open c2 for select 'c' as letter from dual;
        ut.expect(c1).not_to_contain(c2); -- !!!
    end not_to_contain_passes;

    procedure not_to_bracket_contain_bracket_fails
        is
        c1 sys_refcursor;
        c2 sys_refcursor;
    begin
        open c1 for select 'a' as letter from dual union all select 'b' from dual;
        open c2 for select 'c' as letter from dual;
        ut.expect(c1).not_to(contain(c2)); -- !!!!
    end not_to_bracket_contain_bracket_fails;
end;
/

set serveroutput on;
execute ut.run(a_path => 'example');

Output:

example
  not_to_contain_passes [,011 sec]
  not_to_bracket_contain_bracket_fails [,014 sec] (FAILED - 1)
 
Failures:
 
  1) not_to_bracket_contain_bracket_fails
      Actual: (refcursor [ count = 2 ])
          Data-types:
          <LETTER>CHAR</LETTER>
          Data:
          <ROW><LETTER>a</LETTER></ROW><ROW><LETTER>b</LETTER></ROW>
       was expected not to contain:(refcursor [ count = 1 ])
          Data-types:
          <LETTER>CHAR</LETTER>
          Data:
          <ROW><LETTER>c</LETTER></ROW>
      at "RDP_MYCO_APEX_UT.EXAMPLE.NOT_TO_BRACKET_CONTAIN_BRACKET_FAILS", line 19 ut.expect(c1).not_to(contain(c2)); -- !!!!
       
Finished in ,026737 seconds
2 tests, 1 failed, 0 errored, 0 disabled, 0 warning(s)

Expected behavior
not_to_contain should work the same way as not_to(contain)

@lwasylow
Copy link
Member

lwasylow commented Mar 1, 2023

It's arguable:) not is here negation.
So you asking if the set contains the other set and then negating result.
I that case results of to contain coming as false and then you apply not to negate which result in true.

So in fact what you asking is negate result of check to_contain which is not the same as not_contain.

This is my suspicion would need to look into code to confirm.
I'm pretty sure we had that discussion with team or another ticket and operator not is used to negation of result.
With sets is getting a bit more blurry but given that you have there a proper operator to use don't think is a showstopper.

Let me know if that's answer your question.

@micdol
Copy link
Author

micdol commented Mar 1, 2023

To be honest I' struggling to understand the reasoning here. In comparisonnot_to_equal/not_to(equal) works as I'd expect. Can you give an example of actual case where this difference could be used please?


By the way, I found the following entry in the documentation

The negated version of contain ( not_to_contain ) is successful only when all values from expected set are not part of actual (they are disjoint and there is no overlap).

So this might suggest a difference you mentioned... And looking into source of ut_expectations.tpb line 687:

  member procedure not_to_contain(self in ut_expectation, a_expected sys_refcursor) is
  begin
    self.not_to( ut_contain(a_expected).negated() );
  end;

I think this is what you mentioned, yet again I do not understand why. This double negation not_to + .negated() seems off - compare this matcher to all the other not_to_XXX matchers in the file.

@lwasylow
Copy link
Member

lwasylow commented Mar 1, 2023

The negated is a member function that set a flag on matcher to set it to negated. So it does not provide a double negation logic from what I see.

There is an extra logic when that flag is set which is probably the reason why you getting wrong results using not_to() without that flag.

It feels counterintuitive the way it working at the moment for this, you are correct.
I will look closer into this when got a moment.
For time being please use not_to_contain version which I think working as expected.

@lwasylow lwasylow added the bug label Mar 1, 2023
@jgebal
Copy link
Member

jgebal commented Mar 2, 2023

I agree that not_to_contain() should act exactly the same as not_to( contain() )
It's a bug and needs yo be fixed.

Nice catch @micdol and thanks for reporting it.

Side question.
Do you actually use the not_to( contain() ) syntax and if so why this over the other one.
Are you using some sotr of dynamic testing?

Om really curious of your use case.

@micdol
Copy link
Author

micdol commented Mar 2, 2023

I use not_to(contain) cause my primary code editor, IntelliJ, recognizes and applies syntax highlighting for it, while it fails to do so for not_to_contain.

@kukimik
Copy link
Contributor

kukimik commented Mar 13, 2023

See #1173 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants