-
Notifications
You must be signed in to change notification settings - Fork 186
Feature/rework matcher #1076
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
Feature/rework matcher #1076
Conversation
@lwasylow - sorry for not reviewing it yet. |
l_result ut_equal := self; | ||
begin | ||
l_result.options.exclude.add_items(a_items); | ||
l_result.expectation.to_(l_result ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all calls to: l_result.expecatation
in this type are assuming that the expectation
attribute is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the number of places this is called, it would be good to delegate exception handling to a helper procedure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lwasylow
I don't really remember why this change was done.
I think it's part of some clean-up operation but not really part of new matcher. Is your memory any better than mine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went back to old conversations on slack from may 27th 2020 and found this:
To not duplicate old methods from matchers we can change behaviour.
UT_MATCHER is additional attribute of expectation which is set when function is called.
Procedure TO_EQUAL in UT_EXPECTATION works the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. I've found it. But after 2 years I can't even understand what I had in mind.
I'll put the original (polish) version here, just in case, as the free version of SLACK that we use purges messages history.
Propozycja:
Żeby nie duplikować wszystkich metod z matcherów w ut_Expectation można zmienić to zachowanie w następujący sposób:
ut_matcher a teraz dodatkowy atrybut expectation który jest ustawiany gdy wołana jest funcja.
Procedura to_equal w ut_Expectation działa jak dotychczas - raportuje expecattaion
Funkcja to_equal w ut_Expecattion_compound :
ustawia wartość pola expectation w przekazanym matcher na wartość self
zwraca matcher, tak żeby metchod chaining teraz już używał metod matchera (dzięki temu nie trzeba już duplikować dodatkowych metod w ut_expectation
Matcher może odwołać się teraz do expectation z którego został wywołany.
W procedurze matchera (ostatnia metoda w łańcuchu) self.expecation is null matcher nie woła expecataion, w innym wypadku procedury matcher wołaję metodę to_ przekazując self
W ten sposób składnia:
ut.expect(...).to_( equal(...).incude(...) ) sprawia, że:
matcher nie woła expectation, bo expectation nie jest ustawione w matcher
matcher jest przekazany do expectation i expectation wykonuje sprawdzenie wartości i raportuje
Składnia:
ut.expect(...).to_equal(...).include sprawia że:
to_equal ustawia self jako expectation w matcherze, zwraca matcher i dokonuje się metchod chaining
include wywoływane jest na matcherze i poniewarz jest to procedura i pole expectation jest ustawione, matcher woła metodę ecpectation.to_ przekazując self jako arcument
Powinno działać, ale jest 2 w nocy więc mogę majaczyć
Added synonym and grant for matcher Reworked expectation to work fine with syntax `to_( matcher() )` for to_be_within. TODO - add tests for other matchers with `to_( matcher )` and `not_to( matcher )` syntax
…tPLSQL into feature/rework_matcher
Reorganized code so that `be_within_pct` is only supported for `number` Added tests for non-supported syntax
No tests
Kudos, SonarCloud Quality Gate passed!
|
What's missing here? Maybe I can help |
Added sql-injection check.
While running the feature tests locally just now, I have noticed a pitfall of using set serverout on;
begin
ut.expect(date '2022-01-30').to_be_within(INTERVAL '1' MONTH).of_(date '2022-01-30');
end;
/
begin
ut.expect(date '2022-05-31').to_be_within(INTERVAL '1' MONTH).of_(date '2022-05-31');
end;
/
This is because: val '1' month, according to Interval maths is June 31st So, we would really need to rethink the maths and meaning of + 1 month to be more like select add_months(date '2022-05-31',1) from dual;
2022-06-30 12:00:00 AM It seems that only the |
Well. |
The stack overflow link references this spec: http://www.inf.fu-berlin.de/lehre/SS05/19517-V/FolienEtc/sql-foundation-aug94.pdf Table 11— “Valid values for fields in datetime items” (page 130) states: DAY - “ Within the range 1 to 31, but further constrained by the value of MONTH and YEAR fields, according to the rules for well-formed dates in the Gregorian calendar.” This suggests that valid Gregorian calendar days should be the result. I’d this behaviour of INTERVAL types an Oracle bug? |
I think we can work this around as we already have function to extract string from interval. I reckon we can try go this route to translate |
More digging and Oracle state this not a bug - just the way INTERVAL works. There’s an asktom from 2005 - Mr Kyte covers it all: https://asktom.oracle.com/pls/apex/f?p=100:11:0::::p11_question_id:1157035034361 |
I think I've found a solution that would still rely on internal oracle logic related to intervals. declare
l_result boolean;
begin
l_result :=
a_actual between (a_expected - a_distance) and (a_expected + a_distance);
end; The above results in problems when we calculate: select (timestamp '2022-01-30 14:45:56.123456' + interval '0-1' year to month) from dual; However we can express the same intent with a different formula: declare
l_result boolean;
begin
l_result := ( least( a_actual, a_expected ) - greatest(a_actual, a_expected) ) year to month <= a_distance;
end; That way, we avoid the problems with invalid dates rather than adding/subtracting interval to date, we calculate YM distance between dates and then compare it to expected max distance. For declare
l_result boolean;
begin
l_result := ( cast(least( a_actual, a_expected ) as timestamp) - cast( greatest(a_actual, a_expected) as timestamp) ) year to month <= a_distance;
end; |
…month Improved error handling for null values and incompatible datatypes Improved handling of negative dates (BC) Improved reporting of interval text value Improved datatypes to handle large&small precissions for timestamps
I have implemented required fixes. |
TODO - review readme and documentation update to assure that the matcher is well explained along with it's limitations and behaviour to make sure there is no confusion when folks will use it. |
7c121ab
to
4e0c703
Compare
4e0c703
to
86e84c8
Compare
Added human-readable reporting of tests run-time into `ut_documentation_reporter`.
…rk for Pull Requests
Kudos, SonarCloud Quality Gate passed! |
Question:
That is, should we relax the strict datatype check that is present for the |
…n expected (not only smaller). Updated documentation.
I have fixed 2 issues with pct matcher:
With the change introduced now we will have:
|
…nteger and cannot be used to express a decimal distace value. Improved tests coverage for various scenarios.
Please retry analysis of this Pull-Request directly on SonarCloud. |
Kudos, SonarCloud Quality Gate passed! |
Adding a matcher within_of.
Rework some of the compound expectation to use a pass a matcher to expectation to remove methods from ut_equal_compound.
Implements #77