-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Inline lambdas passed to assertDoesNotThrows to support suspending functions #2684
Inline lambdas passed to assertDoesNotThrows to support suspending functions #2684
Conversation
junit-jupiter-api/src/main/kotlin/org/junit/jupiter/api/Assertions.kt
Outdated
Show resolved
Hide resolved
junit-jupiter-engine/src/test/kotlin/org/junit/jupiter/api/KotlinAssertionsTests.kt
Outdated
Show resolved
Hide resolved
@@ -147,6 +147,14 @@ inline fun <reified T : Throwable> assertThrows(noinline message: () -> String, | |||
}, Supplier(message)) | |||
} | |||
|
|||
@PublishedApi |
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.
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.
Again, possibly dumb question here, but why do we need this method to be inline
?
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.
Also, could you please move this method below the other ones calling it? :)
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.
Again, possibly dumb question here, but why do we need this method to be
inline
?
Because this function is ultimately the one responsible for calling the provided executable
. We want to run the executable
in the same context as the callsite of assertDoesNotThrow
(so that it can suspend, etc.), so we need to make sure the full call stack from assertDoesNotThrow
until here uses inlined functions. If we were to remove the inline
modifier on this function, we'll get a compiler error in all of the assertDoesNotThrow
functions saying that we're violating the inlineability (I totally just made that word up) of the executable
argument, and that we need to change the function signature to assertDoesNotThrow(noinline executable: () -> R)
. Doing so breaks the tests that now calls a suspending function, because the callback is no longer inlined.
edit: This is at least my understanding
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.
I see! Thanks for the explanation 😄
…ow-coroutines * upstream/main: Introduce AnnotationSupport.findAnnotation() that searches enclosing classes Introduce unit tests for AnnotationUtils.findAnnotation(Class,Class,boolean) Always include classes selected via @SelectClasses in suites Polishing Polishing Fix TypedArgumentConverter example in User Guide Ensure TypedArgumentConverter can convert to a primitive Introduce ReflectionUtils.isAssignableTo(Class,Class) Fix Javadoc tag in TypedArgumentConverter
@Test | ||
fun `assertDoesNotThrow with coroutines`() = runBlocking { | ||
val result = assertDoesNotThrow { | ||
suspend { "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.
We might want to have another test with a suspending function that actually throws an exception (thus making the test fail), since we want to make sure that the assertion is actually waiting for the "throwing"
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.
Just noticed the test factory below, you could even add one dynamic test in each dynamicContainer
for this new suspending function use case :)
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.
Done! d48eeb4
Codecov Report
@@ Coverage Diff @@
## main #2684 +/- ##
==========================================
- Coverage 91.47% 91.37% -0.11%
==========================================
Files 427 427
Lines 12067 12075 +8
Branches 941 941
==========================================
- Hits 11038 11033 -5
- Misses 788 801 +13
Partials 241 241
Continue to review full report at Codecov.
|
@williamboman could you please add an entry in the release notes? |
…ow-coroutines * upstream/main: Upgradle to 7.2-rc-3 Improve documentation on tags in User Guide Polishing Discover suite tests using parent configuration parameters Add support for private TempDir fields Document junit-team#2582 in release notes Simplify test Report exceptions thrown by CloseableResource as suppressed exceptions Use temp dir in constructor resolution test case Document scope in Javadoc Document configuration parameter Rename TempDirBehavior to TempDirectory.Scope Document in user guide Add to release notes Change TempDir to create a separate dir per declaration Split test case Reduce scope of SuppressWarnings annotation Revert "Add identifier element to `TempDir` annotation"
Done! Struggled a bit with the wording (for example, not sure if need to clarify it's Kotlin API or if that's implied), feel free to amend! |
documentation/src/docs/asciidoc/release-notes/release-notes-5.8.0-M2.adoc
Outdated
Show resolved
Hide resolved
) | ||
|
||
@PublishedApi | ||
internal inline fun <R> getThrowingSupplier(executable: () -> R): ThrowingSupplier<R> = try { |
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 sure about this method name which is "effectively public" due to @PublishedApi
. Maybe evaluateAndWrap
or sth. similar would be clearer.
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 that's a good call, agreed.
…8.0-M2.adoc Co-authored-by: Marc Philipp <marc@gradle.com>
…nctions (junit-team#2684) This commit adds support for suspending functions when `assertDoesNotThrow` is called from Kotlin. Closes junit-team#2674.
Resolves #2674.
Overview
Support for suspending functions was added for the assertThrows() counterpart (see #1851), but it seems like calling suspending functions in an assertDoesNotThrow() block is currently not supported.
I hereby agree to the terms of the JUnit Contributor License Agreement.
Definition of Done
@API
annotations