-
Notifications
You must be signed in to change notification settings - Fork 0
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
Add BlockListener support... #1575
base: master
Are you sure you want to change the base?
Add BlockListener support... #1575
Conversation
spock-core/src/main/java/org/spockframework/runtime/extension/IBlockListener.java
Outdated
Show resolved
Hide resolved
Hi @leonard84. I cannot perform a formal code review, because I am not a committer, but I hope that during the weekend I can find a small time slice to build and play around with it. I simply wanted to say thanks in advance for taking care of this feature request. It has not gone unnoticed. Quick question: Are you planning to add more commits to this PR? Code changes? User manual? I am just asking, not demanding anything. I simply do not want to start testing too early. As for the user manual, I can of course take a look at the unit tests and take it from there. But that might not be true for all future extension developers, I am just speaking for myself. |
e49b0e3
to
f1d1840
Compare
try { | ||
org.spockframework.runtime.SpockRuntime.callEnterBlock(this.getSpecificationContext(), new org.spockframework.runtime.model.BlockInfo(org.spockframework.runtime.model.BlockKind.WHEN, [])) | ||
foobar = this.foobar() | ||
org.spockframework.runtime.SpockRuntime.callExitBlock(this.getSpecificationContext(), new org.spockframework.runtime.model.BlockInfo(org.spockframework.runtime.model.BlockKind.WHEN, [])) |
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.
💬 this won't be called, fixing this makes for some awkward interactions between the individual AST transformations,
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 tried moving the blockListener logic where the blocks are written back in SpecRewriter#L388
, however this didn't work for some cases, e.g. cleanup
as it already replaced all Blocks with an anonymous block.
spock-specs/src/test/groovy/org/spockframework/smoke/ast/mock/MocksAstSpec.groovy
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/ErrorInfo.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/extension/IBlockListener.java
Outdated
Show resolved
Hide resolved
c3f30eb
to
0f3197e
Compare
As this PR seems a little bit stalled, I pushed the code I initially created ~6 months ago as a PoC for the BlockListener support. It a very raw version (with a lot of diagnostic stuff to be amended in the future), but functional in some basic scenarios. The JPA session, where requested, is flushed after the https://github.com/szpak/spock-jpa-flush-enforcer/tree/preview1 I would like to awake discussion about future shape of this PR. @leonard84 @kriegaex WDYT? |
It mostly hangs on the problems that adding the exit listener introduces #1575 (comment) |
0f3197e
to
ae38bda
Compare
ae38bda
to
353cbf9
Compare
I think I've fixed the issues, but I need another fresh set of eyes to verify that everything looks good, I've stared at too many snapshots already. |
spock-core/src/main/java/org/spockframework/runtime/SpecificationContext.java
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/FeatureInfo.java
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/IErrorContext.java
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/extension/IBlockListener.java
Show resolved
Hide resolved
@AndreasTu, as I mentioned earlier, I'll write some documentation and polish it later. Thanks for your comments in any case. However, I'm looking for a review of the correctness of the implementation and generated code and general usability. |
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've switched my experimental (and heavily work-in-progress) extension to the latest version and it still works as expected without any modification. Nice.
I will think about the possible corner cases, I might encounter there.
Btw, I wonder, if it is still a recommended way to decide if the block listener was intended for the current iteration?
spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/extension/IBlockListener.java
Show resolved
Hide resolved
spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/DataProviders.groovy
Outdated
Show resolved
Hide resolved
spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/DataProviders.groovy
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/BlockInfo.java
Show resolved
Hide resolved
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.
Some things missing in multiple places:
- license headers
- JavaDoc
- documentation
@Beta
@since
spock-core/src/main/java/org/spockframework/compiler/AstUtil.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/compiler/DeepBlockRewriter.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/ErrorInfo.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/FeatureInfo.java
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/IErrorContext.java
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/IErrorContext.java
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/model/IErrorContext.java
Show resolved
Hide resolved
Btw. could we also support |
I don't think it would be intuitive or really helpful.
However, you are most familiar with that part of the code. |
No idea. :-D But we can also start without and see where and how need arises. |
Forgot to publish my responses 😅 |
spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/ErrorContext.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/runtime/SpecificationContext.java
Outdated
Show resolved
Hide resolved
spock-core/src/main/java/org/spockframework/lang/ISpecificationContext.java
Outdated
Show resolved
Hide resolved
@szpak, can you motivate this use case more? At first glance, I'd try to register a block listener that can handle all iterations instead of one per iteration. |
Hmm, I think the main problem was to get the |
5a2f3f2
to
c9ee05f
Compare
We could easily pass in the current instance. The question is whether we should. I've also been debating whether I should give access to the current |
Definitely that's the good question. What are the design difference between interceptors (which have access to
Do you see any good cases where it would be necessary for listeners in practice? To read the values set by the other extensions/interceptors? |
Trying to use ThreadLocal was failing with strange effect at first and in the end, it turned out that my original problem with "wrong iteration" was caused by the fact, I was not removing the block listener added in the iteration interceptor. As a result, in the second iteration 2 listeners were called (and checking the iteration index worked as a workaround)... In the end, I can use just one block listener without any iteration index checking. Thanks. https://github.com/szpak/spock-jpa-flush-enforcer/compare/preview2...preview3?expand=1 |
@szpak you should just register the blocklister once for the feature where you add the interationInterceptor instead of adding/removing it every time. Otherwise, you'll run into problems in parallel execution mode. |
Thanks, fixed: |
Regarding
Some people might use it as a informal (and broken) placeholders. However, it should be easy to fix. Btw, could we reuse BlockInfo if no GString is detected, and create a new instance only if an evaluation is needed? |
Maybe, with increased complexity. |
I have no real preference in any way for or against the How about we go with the existing behavior, and if someone wants the GString support in the future, we can still make the break? |
I am a bit out of the loop. But this sounds very useful to me. |
This feature allows extension authors to register a IBlockListener for a feature to observe the execution of a feature in more detail. This surfaces some of Spock's idiosyncrasies, for example interaction assertions are actually setup right before entering the preceding `when`-block as well as being evaluated on leaving the `when`-block before actually entering the `then`-block. The only valid block description is a constant String, although some users mistakenly try to use a dynamic GString. Using anything other than a String, will be treated as a separate statement and thus ignored.
Prior to this commit, IRunListener.error(ErrorInfo) didn't give any context where the error happened.
dcb9f79
to
b819d74
Compare
b819d74
to
d6f4c9d
Compare
@renatoathaydes, please take a look at the new I guess you are going to be one of the prime users of this feature, so if you have any comments, now would be the best time to address them. |
@leonard84 oh I see. I will try to checkout this code and get spock-reports to use the new feature, I suppose that will let me fix renatoathaydes/spock-reports#242 and maybe even renatoathaydes/spock-reports#89? |
This feature allows extension authors to register a IBlockListener for
a feature to observe the execution of a feature in more detail.
This surfaces some of Spock's idiosyncrasies, for example interaction
assertions are actually setup right before entering the preceding
when
-block as well as being evaluated on leaving thewhen
-blockbefore actually entering the
then
-block.The only valid block description is a constant String, although some
users mistakenly try to use a dynamic GString. Using anything other
than a String, will be treated as a separate statement and thus ignored.
fixes #538
fixes #111