-
-
Notifications
You must be signed in to change notification settings - Fork 182
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
Allow custom assertions in XQSuite #4332
base: develop
Are you sure you want to change the base?
Conversation
I have a concern that your
The problem with mixing concerns is that we are then not creating composable building blocks. I think it needs to be simplified to do one thing, i.e. fail with an optional code and message. For a good example, see the JUnit |
f4e8fc7
to
91d1075
Compare
|
The example isn't clear at all as it uses an assert library which isn't part of this PR. Instead I was reading the commits themselves... |
Ah I see... It doesn't assert, however including them as args to test:fail, still mixes concerns and by extension limits the usefulness of test:fail. When I have a moment later I will try and propose some alternative function signatures, which still allow you to achieve the same goal but are more composable |
In order to get the desired test output on failure it is crucial to pass both expected and actual to test:fail. |
Thanks Juri. I understand and I am generally in favour of this, I think it just needs a little tweaking and discussion |
@adamretter I am all for discussions. I would appreciate it, though, that you state what you think needs to change and why. |
I think the full function signature for a test:fail($code as xs:QName?, $description as xs:string, $failure-object as item()*) as none We can then also have:
I have chosen the above function signatures to mirror that of By not mixing concerns, i.e. not forcing the user to include the A new implementation of such a function might look like: declare function test:fail($code as xs:QName?, $description as xs:string, $failure-object as item()*) as empty-sequence() {
fn:error(xs:QName("test:fail"), $description, ($code, $failure-object))
}; |
@adamretter I incorporated your feedback. |
Kudos, SonarCloud Quality Gate passed! |
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.
Not completely my cup of tea, but great to see the interaction
@line-o You still appear to have the old versions of |
@adamretter I cannot follow. Both expected and actual are necessary in every case. |
@line-o The premise behind all of my concerns with this PR is that having actual and expected values as explicit arguments mixes concerns in a negative way! Instead, with my proposal you have test:fail($code, $description, ($expected, $actual)) |
Your proposal, @adamretter, will not work.
|
That is solved simply by using a Map, e.g.: test:fail($code, $description, map {"expected" : $expected, "actual": $actual})
I am not sure what you mean by "the later code" - can you show me where to find this?
Again I am afraid, I am not sure what you mean by this. Can you show me where to find this? |
@adamretter I am sure you noticed that test:fail#0, and test:fail#1 were added to this PR along with their tests. declare %test:assertTrue function t:random-is-odd() as xs:boolean? {
if (( random-number-generator()?number * 1e16 ) mod 2)
then test:fail()
else true()
}; Regarding the usage of a map. Yes, this would solve the problem of keeping sequences apart. On the flip side there is no tooling in place to help you keep in mind what keys need to propagated. Whereas having them as explicit arguments means that in code editors like eXide, VSCode and intelliJ you will be presented with useful hints what needs to be added. The "later code" is here exist/exist-core/src/main/resources/org/exist/xquery/lib/xqsuite/xqsuite.xql Lines 425 to 446 in 8464ae4
|
#confused |
I believe two key purposes of a testing framework got confused here:
While the former has to have the expected and actual value the latter needs to know these only if the reporter wants to display these values. A dot-reporter for example only needs to know if the test passed or failed. But all the reporters of XQSuite I am aware of - XML, HTML, jUnit - do display at least one of them. That is why I chose to require them in the design of test:fail instead of making them optional. I have a hard time thinking of a reason why this is a bad decision and have not read a good one in the comments, yet. |
The only point I can think of is that it would be one parameter less, three instead of four. Developer experience and help from tooling outweighs this argument by a ton in my opinion. |
I think there are some things here that still need to be discussed and developed further, I will try and find some time later in the week to take a look |
As I read the discussion, the feature in itself is not in question but rather points related to usage? Can we compile a list of concerns and possible pitfalls that should be discussed? That may be a point for an upcoming call’s agenda. |
@adamretter can you elaborate on why you are against merging this PR? It's been several months. |
@dariok merging into the If further changes are necessary before a release, then that's a separate question. The question at hand is, if the PR is ready to be merged into develop. As it is not a breaking change, I d say yes. Further development of this or other features before or after the next release should happen in a new pr. |
+1 for me pulling in; maybe not perfect but good enough |
443fcef
to
868ebc5
Compare
Kudos, SonarCloud Quality Gate passed! |
needs to be rebases on current develop |
After a rebase, this is still awaiting further discussion and then likely some adjustment, before it gets merged |
3c6c245
to
ab27751
Compare
Kudos, SonarCloud Quality Gate passed! |
@dizzzz I will rebase this branch |
Now the correct version is declared
Store curried function test:run-tests in a variable $runner.
Store curried function test:test in a variable $test.
Add new functions test:fail#3 and test:fail#4 to XQSuite. Calling this function inside a XQSuite test function will stop execution by throwing a special error `test:failure`. This error is caught and handled as a failure allowing to create arbitrary custom assertions and the ability to provide specific error messages. Works in both XQuery and jUnit context. In jUnit you will only be presented with the serialized expected and actual values. For an example custom assertion see custom-assertion.xqm.
Since xqsuite.xql now exports an additional function the test checking for the number of exported functions failed. Was 7 and is now 8 (test:fail was added).
- `test:fail#3`: fail with custom **message**, expected and actual value - `test:fail#4`: allows to set an additional type The tests in custom-assertion.xqm were adapted and enhanced.
Allow backwards compatible implementations of custom assertions for packages that target multiple version of eXist-db, including ones that do not yet have `test:fail`.
ab27751
to
694ba19
Compare
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.
still in favour of pulling in, and seeing how the dice fall
Quality Gate passedIssues Measures |
Description:
Add new functions
test:fail#3
andtest:fail#4
to XQSuite. Calling one of these inside a XQSuite test function will stop execution by throwing a special errortest:failure
. This error is caught and handled as a failure allowing to create arbitrary custom assertions and the ability to provide specific error messages.(edit) After @adamretter's feedback the order of arguments was changed.
test:fail#3
: fail with custom message, expected and actual valuetest:fail#4
: fail with custom message, expected and actual value and a custom test typeWorks in both XQuery and jUnit context.
In jUnit you will only be presented with the serialized expected and actual values.
(edit) In order to provide this facility also to packages that target older versions of eXist-db, which might not have the
test:fail
function available both$test:FAILURE
$test:CUSTOM_ASSERTION_FAILURE_TYPE
are exposed. This allows to fall back to throwing the error directly in custom assertion code. In case of a failed assertion the test case will still fail. Though not as a failure but an error. Also expected and actual value might not be displayed nicely. But the provided custom message will still add value.
Example
test.xqm
assert.xqm
Running the above will yield
Reference:
This was added due to the limitations of XQuery function annotations and will allow to compare complex values,
loading fixtures and assertions from modules and provide human readable feedback via custom error messages.
Type of tests:
XQSuite tests in custom-assertion.xqm