Jump to page: 1 2
Thread overview
Unittest Absurdity
Aug 05, 2022
Ruby The Roobster
Aug 05, 2022
Ruby The Roobster
Aug 05, 2022
jfondren
Aug 05, 2022
jfondren
Aug 05, 2022
Ruby The Roobster
Aug 05, 2022
Ruby The Roobster
Aug 05, 2022
Ruby The Roobster
Aug 05, 2022
jfondren
Aug 05, 2022
Paul Backus
Aug 05, 2022
jfondren
Aug 05, 2022
frame
Aug 05, 2022
frame
August 05, 2022

How do I get unittests to actually execute operator overloads?

E.g.:

struct Struct
{
    void opOpAssign(string op)(Struct rhs) //Assume that the operator `/=` is implemented here
    {
        //...
    }
}

unittest
{
   Struct a = Struct(1);

   Struct b = Struct(2);

   a /= b;

   assert(a == Struct(5, 0, -1));
}

The unittest completely ignores the a /= b.

Unittests also ignore swapping a for a/b in the assert statement, and even if I force the operator overloads to give me the correct answers, the assert still fails.

Any function other than an operator overload seems to work fine.

August 05, 2022

On Friday, 5 August 2022 at 01:23:40 UTC, Ruby The Roobster wrote:

>

[SNIP]
Any function other than an operator overload seems to work fine.

Also, this isn't mentioned in the spec.

Additional Information:

Fails for both DMD and LDC on Windows x86_64 for dmd v2.100.1

August 05, 2022

On Friday, 5 August 2022 at 01:25:50 UTC, Ruby The Roobster wrote:

>

On Friday, 5 August 2022 at 01:23:40 UTC, Ruby The Roobster wrote:

>

[SNIP]
Any function other than an operator overload seems to work fine.

Also, this isn't mentioned in the spec.

Additional Information:

Fails for both DMD and LDC on Windows x86_64 for dmd v2.100.1

unittest blocks are just anonymous functions. They're not a special environment and there's nothing you can do here that wouldn't be necessary in any other user of your code. You have some other problem (which could very well be a compiler bug.)

August 05, 2022

On Friday, 5 August 2022 at 01:38:48 UTC, jfondren wrote:

Here's a complete example that passes tests:

struct S {
    int n;
    void opOpAssign(string op)(S rhs) if (op == "/") {
        n++;
    }
}

unittest {
    auto a = S(1), b = S(2);
    a /= b;
    b /= a;
    assert(a.n == 2);
    assert(b.n == 3);
}
August 05, 2022

On Friday, 5 August 2022 at 01:42:23 UTC, jfondren wrote:

>

On Friday, 5 August 2022 at 01:38:48 UTC, jfondren wrote:

Here's a complete example that passes tests:

struct S {
    int n;
    void opOpAssign(string op)(S rhs) if (op == "/") {
        n++;
    }
}

unittest {
    auto a = S(1), b = S(2);
    a /= b;
    b /= a;
    assert(a.n == 2);
    assert(b.n == 3);
}

I found the issue: opOpAssign isn't getting called at all. I have no idea why, though.

August 05, 2022

On Friday, 5 August 2022 at 01:47:07 UTC, Ruby The Roobster wrote:

>

On Friday, 5 August 2022 at 01:42:23 UTC, jfondren wrote:

>

On Friday, 5 August 2022 at 01:38:48 UTC, jfondren wrote:

Here's a complete example that passes tests:

struct S {
    int n;
    void opOpAssign(string op)(S rhs) if (op == "/") {
        n++;
    }
}

unittest {
    auto a = S(1), b = S(2);
    a /= b;
    b /= a;
    assert(a.n == 2);
    assert(b.n == 3);
}

I found the issue: opOpAssign isn't getting called at all. I have no idea why, though.

Even then, I still have a bug, but that is completely unrelated to this issue.

August 05, 2022

On Friday, 5 August 2022 at 01:47:07 UTC, Ruby The Roobster wrote:

>

I found the issue: opOpAssign isn't getting called at all. I have no idea why, though.

Given that the example works, the problem must be in some other part of your code that you haven't posted. If you can post a more complete example that reproduces the problem, we can probably help you fix it.

August 05, 2022

On Friday, 5 August 2022 at 01:51:21 UTC, Ruby The Roobster wrote:

>

On Friday, 5 August 2022 at 01:47:07 UTC, Ruby The Roobster wrote:

>

On Friday, 5 August 2022 at 01:42:23 UTC, jfondren wrote:

>

On Friday, 5 August 2022 at 01:38:48 UTC, jfondren wrote:

Here's a complete example that passes tests:

struct S {
    int n;
    void opOpAssign(string op)(S rhs) if (op == "/") {
        n++;
    }
}

unittest {
    auto a = S(1), b = S(2);
    a /= b;
    b /= a;
    assert(a.n == 2);
    assert(b.n == 3);
}

I found the issue: opOpAssign isn't getting called at all. I have no idea why, though.

Even then, I still have a bug, but that is completely unrelated to this issue.

Nevermind. I have to remove the trailing equals sign.

August 05, 2022

On Friday, 5 August 2022 at 01:53:42 UTC, Ruby The Roobster wrote:

> > > >

On Friday, 5 August 2022 at 01:38:48 UTC, jfondren wrote:

Here's a complete example that passes tests:

struct S {
    int n;
    void opOpAssign(string op)(S rhs) if (op == "/") {
        n++;
    }
}

Nevermind. I have to remove the trailing equals sign.

ah, so you had (op == "/=") instead?

I think this is a problem actually, maybe arguably not a bug, but not desirable. Consider:

struct S {
    int n;
    void opOpAssign(string op)(S rhs) if (op == "/=") {
        n++;
    }
    void opOpAssign(string op)(S rhs) if (op == "/") {
        // do nothing
    }
}

unittest {
    auto a = S(1), b = S(2);
    a /= b;
    b /= a;
    assert(a.n == 2);
    assert(b.n == 3);
}

The test fails because the second definition is used (preventing a "none of the overlords are callable" error) and the first definition never matches because it's wrong. I say this arguably isn't a bug because it can still be used:

    a.opOpAssign!"/="(b);
    b.opOpAssign!"/="(a);

but what's actually wanted is operator overloading and a mistake at the definition is silently allowed.

August 04, 2022

On 8/4/22 9:51 PM, Paul Backus wrote:

>

On Friday, 5 August 2022 at 01:47:07 UTC, Ruby The Roobster wrote:

>

I found the issue:  opOpAssign isn't getting called at all.  I have no idea why, though.

Given that the example works, the problem must be in some other part of your code that you haven't posted. If you can post a more complete example that reproduces the problem, we can probably help you fix it.

Another option: use -vcg-ast, and have the compiler tell you what it's actually calling. It's not ignoring that line, it's just not doing what you think it's doing.

-Steve

« First   ‹ Prev
1 2