Javascript method chaining & pipe operator interop

Hi everyone,
I wanted to recreate some sinon-chai API with rescript and pipe operator. Everything was going great when the last value in a chain was a function. But I’m not able to get something like that to work:

expect(spy).to.be.called

This is my binding function:

@val external expectBinding: (. 'a) => 'a = "expect"
let expect = rule => expectBinding(. rule)
@scope(("to", "be")) @send
external toBeCalled: 'element => unit = "called"

But this compiles down to something like this:

expect(spy).to.be.called()

When I deleted parenthesis at the end everything works great. Unfortunately I don’t if it’s possible to force the compiler to drop final parens.

Or maybe my approach is wrong and I need to write this type of bindings in a different way?

I read through documentation but I couldn’t find anything similar. I was hoping maybe you guys could point me in the right direction :slight_smile:

You can bind using @get https://rescript-lang.org/syntax-lookup#get-decorator

Playground link

3 Likes

You’re right! Thank you!

Hey! Sorry for reviving, but I couldn’t seem to find a solution anywhere and this seems the most related. I’ve been trying to do pretty much the same thing, but wanted to put an external function into the expect statement.

Something like:

external foo: 'a => 'b = "foo"
expect(foo)->toBeCalled

And I would expect to see compiled code like:

expect(foo).to.be.called;

But what I’m seeing is:

expect(function (prim) {
      return foo(prim);
    }).to.be.called;

How can I get rid of this function wrapping for externals?

Playground link

Need to create a binding in uncurried format,

@val external expectBinding: (. 'a) => 'a = "expect"
let expect = rule => expectBinding(. rule)
@scope(("to", "be")) @get
external toBeCalled: 'element => unit = "called"

external foo: (. 'a) => 'b = "foo"
expect(foo)->toBeCalled

Playground link

1 Like