Expecting Error value wrapped in an Exit would not be equal using @effect/vitest
What version of Effect is running?
3.2.3
What steps can reproduce the bug?
import * as it from "@effect/vitest";
it.addEqualityTesters();
import { Schema } from "@effect/schema";
import { Exit } from "effect";
class SchemaTaggedError extends Schema.TaggedError<SchemaTaggedError>()(
"SchemaTaggedError",
{
msg: Schema.String,
other: Schema.String,
}
) {}
it.it("test error", () => {
it.expect(new SchemaTaggedError({ msg: "a", other: "other" })).toEqual(
new SchemaTaggedError({ msg: "a", other: "other" })
);
});
it.it("test exit with string value", () => {
it.expect(Exit.fail("d")).toEqual(Exit.fail("d"));
});
//This pass, however error values are not the same
it.it("test exit with error value", () => {
it.expect(
Exit.fail(new SchemaTaggedError({ msg: "a", other: "other" }))
).toEqual(Exit.fail(new SchemaTaggedError({ msg: "b", other: "other" })));
});
What is the expected behavior?
The 3rd test should fail.
What do you see instead?
The 3rd test pass.
Additional information
I'm using latest version as follow:
- vitest 1.6.0
- @effect/vitest 0.5.3
- effect 3.2.3
Looks like a vitest bug, the following passes (wrongly):
import * as it from "@effect/vitest"
import { Schema } from "@effect/schema"
import { Exit } from "effect"
class SchemaTaggedError extends Schema.TaggedError<SchemaTaggedError>()(
"SchemaTaggedError",
{
msg: Schema.String
}
) {}
it.it("test exit with error value", () => {
it.expect(Exit.fail(new SchemaTaggedError({ msg: "a" })))
.toEqual(Exit.fail(new SchemaTaggedError({ msg: "b" })))
})
And the following fails:
import * as it from "@effect/vitest"
import { Schema } from "@effect/schema"
import { Exit } from "effect"
class SchemaTaggedError extends Schema.TaggedError<SchemaTaggedError>()(
"SchemaTaggedError",
{
message: Schema.String
}
) {}
it.it("test exit with error value", () => {
it.expect(Exit.fail(new SchemaTaggedError({ message: "a" })))
.toEqual(Exit.fail(new SchemaTaggedError({ message: "b" })))
})
The reason seems to be how vitest decides to compare instances of Error, it seems that only the message gets considered
Even though something is deeply odd because the following correctly fails:
import * as it from "@effect/vitest"
import { Schema } from "@effect/schema"
import { Exit } from "effect"
class SchemaTaggedError extends Schema.TaggedError<SchemaTaggedError>()(
"SchemaTaggedError",
{
msg: Schema.String
}
) {
}
it.it("test exit with error value", () => {
it.expect(new SchemaTaggedError({ msg: "a" }))
.toEqual(new SchemaTaggedError({ msg: "b" }))
})
cc @sukovanej @tim-smart
Thanks @mikearnaldi to check it out this issue. Few month ago, I already reported an issue on vitest repo, and I was using a custom matcher that properly compare Error instances (by not only considering the msg property). Likewise, I asked this morning to the same thread https://github.com/vitest-dev/vitest/issues/5244
even adding a custom matcher for errors doesn't work, it looks like it is ignored...
even adding a custom matcher for errors doesn't work, it looks like it is ignored...
Yes. Also, there is a recent issue related to the cause prop on Error instances reported on https://github.com/vitest-dev/vitest/issues/5697 not sure it's related.
Looks like this was fixed in vitest 3 https://github.com/vitest-dev/vitest/pull/5876