On Tuesday, 31 July 2018 at 08:28:01 UTC, Ky-Anh Huynh wrote:
Hi,

Can I define a new quick function to use inside a unittest block?

I have the following code:

[code]
auto foo(string[] sta) {
  return sta;
}

auto bar(string[] sta) {
  return sta;
}

auto h(string[] sta) {
  return sta.foo.bar;
}

unittest {
  import std.format;

  auto f = (string[] sta) => sta.foo.bar;
  auto g(string[] sta) {
    return sta.foo.bar;
  }

  assert(f(["test"]) == ["test"]);
  assert(g(["test"]) == ["test"]);
  assert(["test"].h == ["test"]);
  assert(["test"].g == ["test"]);
}
[/code]

(Src: https://gist.github.com/icy/64ec1838929d448d9f874d1e8261e56a)

The last test will fail: Error: no property g for type string[]

Please advise.

From https://dlang.org/spec/function.html#pseudo-member:
"A free function can be called with a syntax that looks as if the function were a member function of its first parameter type."

A function defined in a function scope (which a unittest block is), is not a free function, and so does not benefit from UFCS. There is an explanation for why at the bottom of the above page: "The reason why local symbols are not considered by UFCS, is to avoid unexpected name conflicts."

If you need a function that's available for UFCS in a unittest but is not there in a non-unittest context, use a version block:

    version (unittest) {
        auto fun(string[] s) { return s }
    }

And if you need something with a context:

    version (unittest) {
        string delegate (string) test;
    }
    unittest {
        string s1 = "foo";
        test = s => s ~ s1;
        "foo".test;
    }

--
  Simen

Reply via email to