wiremock-groovy library syntax - groovy

I use library https://github.com/tomjankes/wiremock-groovy for WireMock in Spock tests.
My big concern is that Intellij Idea doesn't understand syntax and so do I.
Exmaple from documentation:
wireMockStub.stub {
request {
method "GET"
url "/some/thing"
}
response {
status 200
body "Some body"
headers {
"Content-Type" "text/plain"
}
}
}
As far as I understand, stub { ... } is a method call with lambda as an argument. That's ok, going further.
request {...} is a method call with two arguments: method and url. Is it correct? Idea points to the static method of the class WireMock, but I'm in doubts, because pointed method has second arg named urlPattern, not just url.
Then we see something similar with response. Idea doesn't recognize it at all, so no hints, no syntax check and so on.
So, there are two main questions:
- What is this syntax?
- How to force idea to understand it?

stub { ... } is a method call with lambda as an argument.
Correct, but the {...} is a Closure, not lambda.
request {...} is a method call with two arguments: method and url. Is it correct?
No, both method and url are method calls. In Groovy parenthesis can be omitted for clarity, so for java developers the block can be rewritten as:
request( {
method( "GET" )
url( "/some/thing" )
} )
or
request(){
...
}
The whole thing is made possible by Groovy DSL support, which may not always be properly recognized be IDEs during compile time, but runs smoothly nevertheless.

Related

Mockito: using when over a mocked Mono with timeout method causes InvalidUseOfMatchersException

I am working on the unit test of a reactive WebClient usage and my problem comes when I try to mock the behavior of Mono with the method timeout(Duration d).
I just want to control the result of a call like:
private Mono<String> withTimeout(Mono<String> myMono) {
return myMono.timeout(Duration.of(globalDuration));
}
So I am using this:
#Test
void test() {
...
Mono<String> monoMock = (Mono<String>) Mockito.mock(Mono.class);
when(monoMock.timeout(Mockito.any(Duration.class))).thenReturn(Mono.just("OK"));
...
}
But it generates a
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaces or misused argument matcher detected here:
-> at service.UserServiceTest.test(UserServiceTest.java:98)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
This message may appear after an NullPointerException if the last matcher is retur....
How should I actually when the result of this Mono.timeout method?
I also just experienced this strange error, in addition to your error I also got java.lang.NullPointerException.
I was able to solve this by importing:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.8.1</version>
</dependency>
After this I was able to simply do this without any issues:
var monoMock = Mockito.mock(Mono.class);
lenient().when(monoMock.timeout((any(Duration.class)))).thenReturn(monoMock);

duktape js - have multiple contexts with own global and reference to one common 'singleton'

We are in the process of embedding JS in our application, and we will use a few dozen scripts each assigned to an event. Inside these scripts we provide a minimal callback api,
function onevent(value)
{ // user javascript code here
}
which is called whenever that event happens. The scripts have to have their own global, since this funtion has always the same name and we access it from cpp code with
duk_get_global_string(js_context_duk, "onevent");
duk_push_number(js_context_duk, val);
if (duk_pcall(js_context_duk, 1) != 0)
{
printf("Duk error: %s\n", duk_safe_to_string(js_context_duk, -1));
}
duk_pop(js_context_duk); /* ignore result */
Then again we want to allow minimal communication between scripts, e.g.
Script 1
var a = 1;
function onevent(val)
{
log(a);
}
Script 2
function onevent(val)
{
a++;
}
Is there a way we achieve this? Maybe by introducing an own 'ueber-' global object, that is defined once and referencable everywhere? It should be possible to add properties to this 'ueber-global object' from any script like
Script 1
function onevent(val)
{
log(ueber.a);
}
Script 2
function onevent(val)
{
ueber.a=1;
}
Instead of simple JS files you could use modules. duktape comes with a code example to implement a module system (including its code isolation) like in Node.js. Having that in place you can export variables that should be sharable.
We have an approach that seems to work now. After creating the new context with
duk_push_thread_new_globalenv(master_ctx);
new_ctx = duk_require_context(master_ctx, -1);
duk_copy_element_reference(master_ctx, new_ctx, "ueber");
we issue this call sequence in for all properties/objects/functions created in the main context:
void duk_copy_element_reference(duk_context* src, duk_context* dst, const char* element)
{
duk_get_global_string(src, element);
duk_require_stack(dst, 1);
duk_xcopy_top(dst, src, 1);
duk_put_global_string(dst, element);
}
It seems to work (because everything is in the same heap and all is single threaded). Maybe someone with deeper insight into duktape can comment on this? Is this a feasible solution with no side effects?
edit: mark this as answer. works as expected, no memory leaks or other issues.

How to handle errors from parallel web requests using Retrofit + RxJava?

I have a situation like this where I make some web requests in parallel. Sometimes I make these calls and all requests see the same error (e.g. no-network):
void main() {
Observable.just("a", "b", "c")
.flatMap(s -> makeNetworkRequest())
.subscribe(
s -> {
// TODO
},
error -> {
// handle error
});
}
Observable<String> makeNetworkRequest() {
return Observable.error(new NoNetworkException());
}
class NoNetworkException extends Exception {
}
Depending on the timing, if one request emits the NoNetworkException before the others can, Retrofit/RxJava will dispose/interrupt** the others. I'll see one of the following logs (not all three) for each request remaining in progress++:
<-- HTTP FAILED: java.io.IOException: Canceled
<-- HTTP FAILED: java.io.InterruptedIOException
<-- HTTP FAILED: java.io.InterruptedIOException: thread interrupted
I'll be able to handle the NoNetworkException error in the subscriber and everything downstream will get disposed of and all is OK.
However based on timing, if two or more web requests emit NoNetworkException, then the first one will trigger the events above, disposing of everything down stream. The second NoNetworkException will have nowhere to go and I'll get the dreaded UndeliverableException. This is the same as example #1 documented here.
In the above article, the author suggested using an error handler. Obviously retry/retryWhen don't make sense if I expect to hear the same errors again. I don't understand how onErrorResumeNext/onErrorReturn help here, unless I map them to something recoverable to be handled downstream:
Observable.just("a", "b", "c")
.flatMap(s ->
makeNetworkRequest()
.onErrorReturn(error -> {
// eat actual error and return something else
return "recoverable error";
}))
.subscribe(
s -> {
if (s.equals("recoverable error")) {
// handle error
} else {
// TODO
}
},
error -> {
// handle error
});
but this seems wonky.
I know another solution is to set a global error handler with RxJavaPlugins.setErrorHandler(). This doesn't seem like a great solution either. I may want to handle NoNetworkException differently in different parts of my app.
So what other options to I have? What do other people do in this case? This must be pretty common.
** I don't fully understand who is interrupting/disposing of who. Is RxJava disposing of all other requests in flatmap which in turn causes Retrofit to cancel requests? Or does Retrofit cancel requests, resulting in each
request in flatmap emitting one of the above IOExceptions? I guess it doesn't really matter to answer the question, just curious.
++ It's possible that not all a, b, and c requests are in flight depending on thread pool.
Have you tried by using flatMap() with delayErrors=true?

NodeJS: Run module method within sandbox

I need one simple thing:
var Base = function(module){
this.outsideMethod = function(arg1)
{
// run method in new context - sandbox
return vm.runInNewContext(module.insideMethod, arg1);
}
}
is something like this possible in nodejs? thx very much
If the insideMethod function does not call or use functions/vlues from outside the context it shall run in, yes.
You can convert any function in Javascript to a string.
Doing vm.runInNewContext('('+module.insideMethod+')('+JSON.stringify(arg1)+"); could be what you want.

Scala receive (actors) not receiving anything?

I've been trying to play around with actors, but I'm running into a problem. When I try to send something back to the caller, it doesn't seem to go through at all, even though it is working with a different case.
My receive in the parent actor looks like this:
receive {
case (x,1) => { // case of html
println("reaches here!")
}
case (url,name,2) => {
println("doesnt reach here!")
}
case _ => println("Error on callback")
}
My actors' (of class Processor) act methods (paraphrased):
First actor's act method will invoke the following code:
{
println()
caller ! (s,1)
println(caller)
val processUrls = new Processor(2, s.toString, caller, map, queue)
processUrls.start()
}
So the one above works. It spawns another actor of the same class, that invokes a different method, but passes it the same caller, so that the original caller will receive the message. It invokes the following method in it's act:
{
...
...
println(caller)
caller ! (url, name.get, 2)
}
Up until this point, the caller is the exact same (printing it out in both places yields the exact same thing.
However, when I try to send that message back in the second method, absolutely nothing prints. It's like the caller doesn't even receive the message. Even the catch-all _ case doesn't get printed. I have no idea what's going on.
Never mind, I didn't have the receive surrounded with a loop...

Resources