How to call a non-pure function during a unit test suite?

How to use Motoko matchers to code the following pseudocode?

var x = f();
x += g(x);
test_equal(x, 12);

The tricky part is that in Matchers I see no way to call functions like g during test, to prepare a test value.

You can probably do this
test_equal(do { var x = f(); x += g(x); x }, 12 )

But what if:

var x = f();
var y = a1()
x += g(x);
y *= h(x);
test_equal(x, 12);
test_equal(y, 24);

?

How to avoid calling f twice for tests of x and y?

What’s wrong with calling f twice? I doubt trying to optimize the performance of tests is something worth doing. You will gain like 0.0001ms improvement?
I don’t use Motoko matchers, mops test is easier to work with.
But if you really want to make it complicated, these functions are unidirectional while reactive programming isn’t. You can make a reactive library for testing - rxtest, to push values ahead into pipes, split, and match them to knock yourself out :slight_smile:

Actually, there may be an easy way to use the library and do that.

Suite.suite(
  "Combining matchers",
  do {
   var x = f();
   var y = a1()
    [
    Suite.test("anything", 10, Matchers.anything<Nat>()),

    Suite.test("anyOf1", 20, Matchers.anyOf([equals10, equals20])),
    Suite.test(
        "anyOf2",
        15,
        shouldFailWith(Matchers.anyOf([equals10, equals20]), "15 was expected to be 10\nor 15 was expected to be 20"),
    ),
}

you basically have a do that returns an array