Skip to content

Commit

Permalink
feat: export interface but not class
Browse files Browse the repository at this point in the history
  • Loading branch information
yifanwww committed Sep 11, 2023
1 parent fcf6c88 commit ad4c787
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 310 deletions.
17 changes: 17 additions & 0 deletions src/__tests__/__snapshots__/factory.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Test fn \`Err\` should create \`Err\` result 1`] = `
RustlikeResult {
"_error": "Some error message",
"_type": "err",
"_value": undefined,
}
`;

exports[`Test fn \`Ok\` should create \`Ok\` result 1`] = `
RustlikeResult {
"_error": undefined,
"_type": "ok",
"_value": 1,
}
`;
24 changes: 4 additions & 20 deletions src/__tests__/__snapshots__/result.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,31 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Test fn \`Err\` should create Err result 1`] = `
Result {
exports[`Test static method \`RustlikeResult.Err\` should create \`Err\` result 1`] = `
RustlikeResult {
"_error": "Some error message",
"_type": "err",
"_value": undefined,
}
`;

exports[`Test fn \`Ok\` should create Ok result 1`] = `
Result {
"_error": undefined,
"_type": "ok",
"_value": 1,
}
`;

exports[`Test static method \`Result.Err\` should create Err result 1`] = `
Result {
"_error": "Some error message",
"_type": "err",
"_value": undefined,
}
`;

exports[`Test static method \`Result.Ok\` should create Ok result 1`] = `
Result {
exports[`Test static method \`RustlikeResult.Ok\` should create \`Ok\` result 1`] = `
RustlikeResult {
"_error": undefined,
"_type": "ok",
"_value": 1,
Expand Down
13 changes: 13 additions & 0 deletions src/__tests__/factory.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Err, Ok } from '../factory';

describe(`Test fn \`${Ok.name}\``, () => {
it('should create `Ok` result', () => {
expect(Ok(1)).toMatchSnapshot();
});
});

describe(`Test fn \`${Err.name}\``, () => {
it('should create `Err` result', () => {
expect(Err('Some error message')).toMatchSnapshot();
});
});
77 changes: 33 additions & 44 deletions src/__tests__/result.test.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,35 @@
import { Err, Ok, Result } from '../result';
import type { IResult } from '../types';
import { Err, Ok } from '../factory';
import { RustlikeResult } from '../result.class';
import type { Result } from '../result.interface';

function op1(): IResult<number, string> {
function op1(): Result<number, string> {
return Ok(666);
}

function op2(): IResult<number, string> {
function op2(): Result<number, string> {
return Err('sadface');
}

describe(`Test static method \`${Result.name}.${Result.Ok.name}\``, () => {
it('should create Ok result', () => {
expect(Result.Ok(1)).toMatchSnapshot();
describe(`Test static method \`${RustlikeResult.name}.${RustlikeResult.Ok.name}\``, () => {
it('should create `Ok` result', () => {
expect(RustlikeResult.Ok(1)).toMatchSnapshot();
});
});

describe(`Test static method \`${Result.name}.${Result.Err.name}\``, () => {
it('should create Err result', () => {
expect(Result.Err('Some error message')).toMatchSnapshot();
describe(`Test static method \`${RustlikeResult.name}.${RustlikeResult.Err.name}\``, () => {
it('should create `Err` result', () => {
expect(RustlikeResult.Err('Some error message')).toMatchSnapshot();
});
});

describe(`Test fn \`${Ok.name}\``, () => {
it('should create Ok result', () => {
expect(Ok(1)).toMatchSnapshot();
});
});

describe(`Test fn \`${Err.name}\``, () => {
it('should create Err result', () => {
expect(Err('Some error message')).toMatchSnapshot();
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.isOk.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.isOk.name}\``, () => {
it('should return if itself is `Ok`', () => {
expect(Ok(1).isOk()).toBe(true);
expect(Err('Some error message').isOk()).toBe(false);
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.isOkAnd.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.isOkAnd.name}\``, () => {
const fnFactory = () => jest.fn((num: number) => num > 1);

it('should return if itself is `Ok` and the value inside of it matches a predicate', () => {
Expand All @@ -65,14 +54,14 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.isOkAnd.name
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.isErr.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.isErr.name}\``, () => {
it('should return if itself is `Err`', () => {
expect(Ok(1).isErr()).toBe(false);
expect(Err('Some error message').isErr()).toBe(true);
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.isErrAnd.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.isErrAnd.name}\``, () => {
enum ErrorKind {
NOT_FOUND,
PERMISSION_DENIED,
Expand Down Expand Up @@ -102,21 +91,21 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.isErrAnd.nam
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.ok.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.ok.name}\``, () => {
it('should convert itself to an optional value', () => {
expect(Ok(1).ok()).toBe(1);
expect(Err('Some error message').ok()).toBeUndefined();
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.err.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.err.name}\``, () => {
it('should convert itself to an optional error', () => {
expect(Ok(1).err()).toBeUndefined();
expect(Err('Some error message').err()).toBe('Some error message');
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.map.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.map.name}\``, () => {
const mapFactory = () => jest.fn((num: number) => String(num));

it('should map itself to another result', () => {
Expand All @@ -140,7 +129,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.map.name}\``
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.mapOr.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.mapOr.name}\``, () => {
const mapFactory = () => jest.fn((num: number) => num * 2);

it('should map itself to another result', () => {
Expand All @@ -164,7 +153,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.mapOr.name}\
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.mapOrElse.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.mapOrElse.name}\``, () => {
const mapFactory = () => jest.fn(jest.fn((num: number) => String(num)));
const fallbackFactory = () => jest.fn(jest.fn((str: string) => str));

Expand Down Expand Up @@ -198,7 +187,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.mapOrElse.na
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.mapErr.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.mapErr.name}\``, () => {
const mapFactory = () => jest.fn((num: number) => `error code: ${num}`);

it('should map itself to another result', () => {
Expand All @@ -222,35 +211,35 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.mapErr.name}
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.expect.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.expect.name}\``, () => {
it('should unwrap itself to get the contained `Ok` value', () => {
expect(Ok(1).expect('Operation type should be correct')).toBe(1);
expect(() => Err(2).expect('Operation type should be correct')).toThrow('Operation type should be correct: 2');
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.unwrap.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.unwrap.name}\``, () => {
it('should unwrap itself to get the contained `Ok` value', () => {
expect(Ok(1).unwrap()).toBe(1);
expect(() => Err('Some error message').unwrap()).toThrow('Some error message');
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.expectErr.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.expectErr.name}\``, () => {
it('should unwrap itself to get the contained `Err` value', () => {
expect(Err('Some error message').expectErr('Testing expectErr')).toBe('Some error message');
expect(() => Ok(1).expectErr('Testing expectErr')).toThrow('Testing expectErr: 1');
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.unwrapErr.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.unwrapErr.name}\``, () => {
it('should unwrap itself to get the contained `Err` value', () => {
expect(Err('Some error message').unwrapErr()).toBe('Some error message');
expect(() => Ok(1).unwrapErr()).toThrow('1');
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.unwrapOr.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.unwrapOr.name}\``, () => {
it('should unwrap itself to get the contained `Ok` value or the provided value', () => {
const ok = Ok<number, string>(100);
const okErr = Err<number, string>('Err');
Expand All @@ -260,7 +249,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.unwrapOr.nam
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.unwrapOrElse.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.unwrapOrElse.name}\``, () => {
it('should unwrap itself to get the contained `Ok` value or computes it from a closure', () => {
const handler = (msg: string) => {
if (msg === 'I got this.') return 50;
Expand All @@ -275,7 +264,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.unwrapOrElse
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.and.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.and.name}\``, () => {
it('should return `res`', () => {
expect(op1().and(Ok(667)).ok()).toBe(667);
expect(op1().and(Err('bad')).err()).toBe('bad');
Expand All @@ -287,7 +276,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.and.name}\``
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.andThen.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.andThen.name}\``, () => {
it('should return `res`', () => {
expect(
op1()
Expand Down Expand Up @@ -331,7 +320,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.andThen.name
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.or.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.or.name}\``, () => {
it('should return the `Ok` result', () => {
expect(op1().or(Ok(667)).ok()).toBe(666);
expect(op1().or(Err('bad')).ok()).toBe(666);
Expand All @@ -343,7 +332,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.or.name}\``,
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.orElse.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.orElse.name}\``, () => {
it('should return the `Ok` result', () => {
expect(
op1()
Expand Down Expand Up @@ -387,7 +376,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.orElse.name}
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.transpose.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.transpose.name}\``, () => {
it('should transpose itself to an optional of a `Result`', () => {
expect(Ok<number | undefined | null, string>(1).transpose()!.ok()).toBe(1);
expect(Ok<number | undefined | null, string>(undefined).transpose()).toBeUndefined();
Expand All @@ -398,7 +387,7 @@ describe(`Test method \`${Result.name}.prototype.${Result.prototype.transpose.na
});
});

describe(`Test method \`${Result.name}.prototype.${Result.prototype.equal.name}\``, () => {
describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.equal.name}\``, () => {
it('should check if itself equals to another result', () => {
expect(Ok(1).equal(Ok(1))).toBe(true);
expect(Ok(NaN).equal(Ok(NaN))).toBe(true);
Expand Down
26 changes: 26 additions & 0 deletions src/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { RustlikeResult } from './result.class';
import type { Result } from './result.interface';

/**
* Creates a `Result` that contains the success value.
*/
export function Ok<T>(value: T): Result<T, never>;
/**
* Creates a `Result` that contains the success value.
*/
export function Ok<T, E>(value: T): Result<T, E>;
export function Ok<T, E>(value: T): Result<T, E> {
return RustlikeResult.Ok(value);
}

/**
* Creates a `Result` that contains the error value.
*/
export function Err<E>(error: E): Result<never, E>;
/**
* Creates a `Result` that contains the error value.
*/
export function Err<T, E>(error: E): Result<T, E>;
export function Err<T, E>(error: E): Result<T, E> {
return RustlikeResult.Err(error);
}
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './result';
export * from './factory';
export * from './result.interface';
export * from './types';
Loading

0 comments on commit ad4c787

Please sign in to comment.