#prefer-result-matchers
Enforces use of toBeSuccess() / toBeFailure() from @praha/byethrow-testing.
#Rule details
Checking Result.isSuccess(result) and then asserting on the boolean is noisy. The dedicated matchers toBeSuccess() and toBeFailure() are shorter, produce better failure messages, and narrow the type inside an optional callback. This rule auto-fixes violations.
See Testing for setup instructions for @praha/byethrow-testing.
#Incorrect
import { import Result Result } from '@praha/byethrow';
import { const expect: ExpectStatic expect } from 'vitest';
const const result: Result.Result<string, Error> result : import Result Result .type Result<T, E> = Result.Success<T> | Result.Failure<E>A union type representing either a success or a failure.
@typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@exampleimport { Result } from '@praha/byethrow';
const doSomething = (): Result.Result<number, string> => {
return Math.random() > 0.5
? { type: 'Success', value: 10 }
: { type: 'Failure', error: 'Oops' };
};
@categoryCore Types Result <string, Error> = import Result Result .const succeed: <"hello">(value: "hello") => Result.Result<"hello", never> (+1 overload) succeed ('hello');
// ❌ asserting on the boolean return of isSuccess / isFailure
expect<boolean>(actual: boolean, message?: string): Assertion<boolean> (+1 overload) expect (import Result Result .const isSuccess: <Result.Result<string, Error>>(result: Result.Result<string, Error>) => result is Result.Success<string>Type guard to check if a
Result
is a
Success
.
@function@typeParamR - The type of the result to check.@paramresult - The Result to check.@returnstrue if the result is a Success , otherwise false.@exampleimport { Result } from '@praha/byethrow';
const result: Result.Result<number, string> = { type: 'Success', value: 10 };
if (Result.isSuccess(result)) {
console.log(result.value); // Safe access to value
}
@categoryType Guards isSuccess (const result: Result.Result<string, Error> result )).JestAssertion<boolean>.toBe: <boolean>(expected: boolean) => voidChecks that a value is what you expect. It calls Object.is to compare values.
Don't use toBe with floating-point numbers.
@exampleexpect (result).toBe(42);
expect(status).toBe(true); toBe (true);
expect<boolean>(actual: boolean, message?: string): Assertion<boolean> (+1 overload) expect (import Result Result .const isFailure: <Result.Result<string, Error>>(result: Result.Result<string, Error>) => result is Result.Failure<Error>Type guard to check if a
Result
is a
Failure
.
@function@typeParamR - The type of the result to check.@paramresult - The Result to check.@returnstrue if the result is a Failure , otherwise false.@exampleimport { Result } from '@praha/byethrow';
const result: Result.Result<number, string> = { type: 'Failure', error: 'Something went wrong' };
if (Result.isFailure(result)) {
console.error(result.error); // Safe access to error
}
@categoryType Guards isFailure (const result: Result.Result<string, Error> result )).JestAssertion<boolean>.toBeTruthy: () => voidUse when you don't care what a value is, you just want to ensure a value
is true in a boolean context. In JavaScript, there are six falsy values:
false, 0, '', null, undefined, and NaN. Everything else is truthy.
@exampleexpect (user.isActive).toBeTruthy(); toBeTruthy ();
expect<boolean>(actual: boolean, message?: string): Assertion<boolean> (+1 overload) expect (import Result Result .const isSuccess: <Result.Result<string, Error>>(result: Result.Result<string, Error>) => result is Result.Success<string>Type guard to check if a
Result
is a
Success
.
@function@typeParamR - The type of the result to check.@paramresult - The Result to check.@returnstrue if the result is a Success , otherwise false.@exampleimport { Result } from '@praha/byethrow';
const result: Result.Result<number, string> = { type: 'Success', value: 10 };
if (Result.isSuccess(result)) {
console.log(result.value); // Safe access to value
}
@categoryType Guards isSuccess (const result: Result.Result<string, Error> result )).not: Assertion<boolean> not .JestAssertion<boolean>.toBe: <boolean>(expected: boolean) => voidChecks that a value is what you expect. It calls Object.is to compare values.
Don't use toBe with floating-point numbers.
@exampleexpect (result).toBe(42);
expect(status).toBe(true); toBe (false);#Correct
import { import Result Result } from '@praha/byethrow';
import { const expect: ExpectStatic expect } from 'vitest';
const const result: Result.Result<string, Error> result : import Result Result .type Result<T, E> = Result.Success<T> | Result.Failure<E>A union type representing either a success or a failure.
@typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@exampleimport { Result } from '@praha/byethrow';
const doSomething = (): Result.Result<number, string> => {
return Math.random() > 0.5
? { type: 'Success', value: 10 }
: { type: 'Failure', error: 'Oops' };
};
@categoryCore Types Result <string, Error> = import Result Result .const succeed: <"hello">(value: "hello") => Result.Result<"hello", never> (+1 overload) succeed ('hello');
// ✅ using the dedicated matchers
expect<Result.Result<string, Error>>(actual: Result.Result<string, Error>, message?: string): Assertion<Result.Result<string, Error>> (+1 overload) expect (const result: Result.Result<string, Error> result ).ResultMatchers<Result<string, Error>>.toBeSuccess: (callback?: ((value: string) => void) | undefined) => void toBeSuccess ();
expect<Result.Result<string, Error>>(actual: Result.Result<string, Error>, message?: string): Assertion<Result.Result<string, Error>> (+1 overload) expect (const result: Result.Result<string, Error> result ).ResultMatchers<Result<string, Error>>.toBeFailure: (callback?: ((error: Error) => void) | undefined) => void toBeFailure ();With a callback to assert on the inner value:
import { import Result Result } from '@praha/byethrow';
import { const expect: ExpectStatic expect } from 'vitest';
const const result: Result.Result<string, Error> result : import Result Result .type Result<T, E> = Result.Success<T> | Result.Failure<E>A union type representing either a success or a failure.
@typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@exampleimport { Result } from '@praha/byethrow';
const doSomething = (): Result.Result<number, string> => {
return Math.random() > 0.5
? { type: 'Success', value: 10 }
: { type: 'Failure', error: 'Oops' };
};
@categoryCore Types Result <string, Error> = import Result Result .const succeed: <"hello">(value: "hello") => Result.Result<"hello", never> (+1 overload) succeed ('hello');
expect<Result.Result<string, Error>>(actual: Result.Result<string, Error>, message?: string): Assertion<Result.Result<string, Error>> (+1 overload) expect (const result: Result.Result<string, Error> result ).ResultMatchers<Result<string, Error>>.toBeSuccess: (callback?: ((value: string) => void) | undefined) => void toBeSuccess ((value: string value ) => {
expect<string>(actual: string, message?: string): Assertion<string> (+1 overload) expect (value: string value ).JestAssertion<string>.toBe: <number>(expected: number) => voidChecks that a value is what you expect. It calls Object.is to compare values.
Don't use toBe with floating-point numbers.
@exampleexpect (result).toBe(42);
expect(status).toBe(true); toBe (42);
});
expect<Result.Result<string, Error>>(actual: Result.Result<string, Error>, message?: string): Assertion<Result.Result<string, Error>> (+1 overload) expect (const result: Result.Result<string, Error> result ).ResultMatchers<Result<string, Error>>.toBeFailure: (callback?: ((error: Error) => void) | undefined) => void toBeFailure ((error: Error error ) => {
expect<Error>(actual: Error, message?: string): Assertion<Error> (+1 overload) expect (error: Error error ).JestAssertion<Error>.toBeInstanceOf: <ErrorConstructor>(expected: ErrorConstructor) => voidEnsure that an object is an instance of a class.
This matcher uses instanceof underneath.
@exampleexpect (new Date()).toBeInstanceOf(Date); toBeInstanceOf (var Error: ErrorConstructor Error );
});