Skip to content

Commit

Permalink
ensure as processed
Browse files Browse the repository at this point in the history
  • Loading branch information
vladbasin committed Jul 7, 2024
1 parent 968044a commit b6895e8
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"typescript": "^3.9.7"
},
"dependencies": {
"@vladbasin/ts-types": "^1.0.4",
"@vladbasin/ts-types": "^1.0.5",
"lodash": "^4.17.21",
"p-map": "^4.0.0"
}
Expand Down
28 changes: 27 additions & 1 deletion src/Result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ export class Result<T> {
return this.ensureWithError(condition, new Error(error));
}

/**
* Ensures condition is true. Marks failure (if happens) as processed.
* @param condition Condition to check
* @param error Error to store if condition isn't true
* @returns Failed Result in case condition isn't true. Successful Result in case condition is true.
*/
public ensureAsProcessed(condition: (arg: T) => boolean, error: string): Result<T> {
return this.ensureWithErrorAsProcessed(condition, new Error(error));
}

/**
* Ensures condition is true
* @param condition Condition to check
Expand All @@ -65,6 +75,20 @@ export class Result<T> {
return this;
}

/**
* Ensures condition is true. Marks failure (if happens) as processed.
* @param condition Condition to check
* @param error Error to store if condition isn't true
* @returns Failed Result in case condition isn't true. Successful Result in case condition is true.
*/
public ensureWithErrorAsProcessed(condition: (arg: T) => boolean, error: Error): Result<T> {
this._promise = this._promise.then(value =>
condition(value) ? Promise.resolve(value) : Promise.reject(new ProcessedError(error, new Error()))
);

return this;
}

/**
* Ensures condition is true
* @param ensurer Result condition to check to be true
Expand Down Expand Up @@ -470,7 +494,9 @@ export class Result<T> {
* @returns New Result object with failure
*/
static FailAsProcessedWithError<T>(error: Error): Result<T> {
return new Result(Promise.reject(new ProcessedError(error.message, error)));
return new Result(
Promise.reject(error instanceof ProcessedError ? error : new ProcessedError(error.message, error))
);
}

/**
Expand Down
13 changes: 13 additions & 0 deletions tests/Result.FailAsProcessedWithError.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ProcessedError } from '../src';
import { Result } from '../src/Result';
import { executeResult } from './executeResult';

Expand All @@ -13,4 +14,16 @@ describe('.FailAsProcessedWithError()', () => {
})
);
});

test('produces fail that is not overridden from ProcessedError', done => {
executeResult(
done,
Result.FailAsProcessedWithError(new ProcessedError('original', new Error()))
.onSuccess(_ => done('No success expected'))
.withProcessedFail(() => 'overridden')
.onFailure(error => {
expect(error).toBe('original');
})
);
});
});
15 changes: 15 additions & 0 deletions tests/Result.FailWithError.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ProcessedError } from '../src';
import { Result } from '../src/Result';
import { executeResult } from './executeResult';

Expand All @@ -15,4 +16,18 @@ describe('.FailWithError()', () => {
})
);
});

test('handles process fail', done => {
executeResult(
done,
Result.FailWithError(new ProcessedError('processed1', new Error()))
.withProcessedFail(() => 'processed2')
.onFailure(error => {
expect(error).toBe('processed1');
})
.onFailureWithError(error => {
expect(error.message).toBe('processed1');
})
);
});
});
42 changes: 42 additions & 0 deletions tests/Result.ensureAsProcessed.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Result } from '../src/Result';
import { executeResult } from './executeResult';

describe('.ensureAsProcessed()', () => {
test('fails when condition is false', done => {
const record = jest.fn();

executeResult(
done,
Result.Ok(1)
.ensureAsProcessed(payload => payload === 2, 'error')
.withProcessedFail(() => 're-processed')
.onFailure(error => {
expect(error).toBe('error');
record();
})
.onSuccess(_ => done('Success not expected')),
() => {
expect(record).toBeCalledTimes(1);
}
);
});

test('sucess when condition is true', done => {
const record = jest.fn();

executeResult(
done,
Result.Ok(1)
.ensureAsProcessed(payload => payload === 1, 'error')
.withProcessedFail(() => 're-processed')
.onSuccess(payload => {
expect(payload).toBe(1);
record();
})
.onFailure(_ => done('Failure not expected')),
() => {
expect(record).toBeCalledTimes(1);
}
);
});
});
42 changes: 42 additions & 0 deletions tests/Result.ensureWithErrorAsProcessed.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Result } from '../src/Result';
import { executeResult } from './executeResult';

describe('.ensureWithErrorAsProcessed()', () => {
test('fails when condition is false', done => {
const record = jest.fn();

executeResult(
done,
Result.Ok(1)
.ensureWithErrorAsProcessed(payload => payload === 2, new Error('error'))
.withProcessedFail(() => 're-processed')
.onFailure(error => {
expect(error).toBe('error');
record();
})
.onSuccess(_ => done('Success not expected')),
() => {
expect(record).toBeCalledTimes(1);
}
);
});

test('success when condition is true', done => {
const record = jest.fn();

executeResult(
done,
Result.Ok(1)
.ensureWithErrorAsProcessed(payload => payload === 1, new Error('error'))
.withProcessedFail(() => 're-processed')
.onSuccess(payload => {
expect(payload).toBe(1);
record();
})
.onFailure(_ => done('Failure not expected')),
() => {
expect(record).toBeCalledTimes(1);
}
);
});
});
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -758,10 +758,10 @@
"@typescript-eslint/types" "5.8.1"
eslint-visitor-keys "^3.0.0"

"@vladbasin/ts-types@^1.0.4":
version "1.0.4"
resolved "https://registry.npmjs.org/@vladbasin/ts-types/-/ts-types-1.0.4.tgz"
integrity sha512-x+L/zpnaxfhxw3voK8LD/CLD2Dh2svU1j1eGMV7foW9YsC+iFa+en6XNvTAbAs/tvOf87uO1TQzPkb8a1aGHqw==
"@vladbasin/ts-types@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@vladbasin/ts-types/-/ts-types-1.0.5.tgz#c4a363293945049cc76c6d099a597738e91b1f32"
integrity sha512-vUJZ2nGa1ATVT4qJ8q4WgfZ73MPm5i5f5Kf6tEm0Xbk9Xk+TsnvpMfuhBPZhYxeEAtz/9U0r36Lf3Mpch2K21w==

abab@^2.0.3, abab@^2.0.5:
version "2.0.5"
Expand Down

0 comments on commit b6895e8

Please sign in to comment.