Skip to content

Commit

Permalink
fix: checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
aabccd021 committed Jan 18, 2023
1 parent bd0da75 commit bfed14d
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 56 deletions.
15 changes: 0 additions & 15 deletions src/arrayTaskValidation.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { console } from 'fp-ts';

import { logErrorsF } from './logErrorsF';
import { logF } from './log';
import { runTests } from './runTests';
import { test } from './test';

export { logErrorsF, runTests, test };
export { logF, runTests, test };

export const logErrors = logErrorsF({ console });
export const log = logF({ console });
8 changes: 4 additions & 4 deletions src/logErrorsF.ts → src/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as std from 'fp-ts-std';
import c from 'picocolors';
import { match } from 'ts-pattern';

import type { Change, TestError, TestFailedResult } from './type';
import type { Change, TestError, TestFailResult } from './type';

const getPrefix = (changeType: Change['type']) =>
match(changeType)
Expand Down Expand Up @@ -57,17 +57,17 @@ const indent = flow(
readonlyArray.intercalate(string.Monoid)('\n')
);

const formatErrorResult = (errorResult: TestFailedResult) => [
const formatErrorResult = (errorResult: TestFailResult) => [
`${c.red(c.bold(c.inverse(' FAIL ')))} ${errorResult.name}`,
c.red(c.bold(`${errorResult.error.code}:`)),
'',
pipe(errorResult.error, formatError, indent),
'',
];

export const logErrorsF =
export const logF =
(env: { readonly console: { readonly log: (str: string) => IO<void> } }) =>
(res: TaskEither<readonly TestFailedResult[], undefined>) =>
(res: TaskEither<readonly TestFailResult[], undefined>) =>
pipe(
res,
taskEither.swap,
Expand Down
77 changes: 55 additions & 22 deletions src/runTests.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { boolean, either, readonlyArray, task, taskEither } from 'fp-ts';
import type { Either } from 'fp-ts/Either';
import { pipe } from 'fp-ts/function';
import { identity, pipe } from 'fp-ts/function';
import type { Task } from 'fp-ts/Task';
import type { TaskEither } from 'fp-ts/TaskEither';
import * as std from 'fp-ts-std';
import * as retry from 'retry-ts';
import { retrying } from 'retry-ts/lib/Task';
import { modify } from 'spectacles-ts';
import { match } from 'ts-pattern';

import * as arrayTaskValidation from './arrayTaskValidation';
import { getDiffs } from './getDiffs';
import type {
Assertion,
Expand All @@ -18,8 +16,10 @@ import type {
MultipleAssertionTest,
Test,
TestConfig,
TestEitherResult,
TestError,
TestFailedResult,
TestPassResult,
TestsResult,
} from './type';

const hasAnyChange = readonlyArray.foldMap(boolean.MonoidAll)((diff: Change) => diff.type === '0');
Expand All @@ -37,8 +37,7 @@ const assertEqual = (result: { readonly expected: unknown; readonly actual: unkn
pipe(
result,
getDiffs,
either.chainW(either.fromPredicate(hasAnyChange, assertionFailed(result))),
either.map(() => undefined)
either.chainW(either.fromPredicate(hasAnyChange, assertionFailed(result)))
);

const unhandledException = (exception: unknown) => ({
Expand All @@ -56,10 +55,9 @@ const runActualAndAssert = (param: {
);

const runWithTimeout =
(assertion: Pick<Assertion, 'timeout'>) =>
(te: TaskEither<TestError, undefined>): TaskEither<TestError, undefined> =>
(assertion: Pick<Assertion, 'timeout'>) => (te: TaskEither<TestError, unknown>) =>
task
.getRaceMonoid<Either<TestError, undefined>>()
.getRaceMonoid<Either<TestError, unknown>>()
.concat(
te,
pipe({ code: 'timed out' as const }, taskEither.left, task.delay(assertion.timeout ?? 5000))
Expand All @@ -70,13 +68,15 @@ const runWithRetry =
<L, R>(te: TaskEither<L, R>) =>
retrying(test.retry ?? retry.limitRetries(0), () => te, either.isLeft);

const runAssertion = (assertion: Assertion) =>
const runAssertion = (assertion: Assertion): Task<TestsResult> =>
pipe(
runActualAndAssert({ actualTask: assertion.act, expectedResult: assertion.assert }),
runWithTimeout({ timeout: assertion.timeout }),
runWithRetry({ retry: assertion.retry }),
taskEither.mapLeft((error) => ({ name: assertion.name, error })),
arrayTaskValidation.lift
taskEither.bimap(
(error) => [either.left({ name: assertion.name, error })],
() => [{ name: assertion.name }]
)
);

const runWithConcurrency = (config: { readonly concurrency?: Concurrency }) =>
Expand All @@ -86,33 +86,66 @@ const runWithConcurrency = (config: { readonly concurrency?: Concurrency }) =>
.with({ type: 'sequential' }, () => readonlyArray.sequence(task.ApplicativeSeq))
.exhaustive();

const runMultipleAssertion = (
test: MultipleAssertionTest
): TaskEither<readonly TestFailedResult[], undefined> =>
const foldTestResult = (r: readonly TestsResult[]): TestsResult =>
pipe(
r,
readonlyArray.reduce(
either.right<readonly TestEitherResult[], readonly TestPassResult[]>([]),
(acc, el) =>
pipe(
acc,
either.chain(
(accr): TestsResult =>
pipe(
el,
either.bimap(
(ell) =>
pipe(accr, readonlyArray.map(either.right), (accra) => [...accra, ...ell]),
(elr) => [...accr, ...elr]
)
)
),
either.mapLeft((accl): readonly TestEitherResult[] =>
pipe(el, either.match(identity, readonlyArray.map(either.right)), (newAcc) => [
...accl,
...newAcc,
])
)
)
)
);

const prependName =
(name: string) =>
<K extends { readonly name: string }>(k: K): K => ({
...k,
name: std.string.prepend(`${name} > `),
});

const runMultipleAssertion = (test: MultipleAssertionTest): Task<TestsResult> =>
pipe(
test.asserts,
readonlyArray.map(runAssertion),
runWithConcurrency({ concurrency: test.concurrency }),
arrayTaskValidation.run,
task.map(foldTestResult),
taskEither.bimap(
readonlyArray.map(modify('name', std.string.prepend(`${test.name} > `))),
() => undefined
readonlyArray.map(either.bimap(prependName(test.name), prependName(test.name))),
readonlyArray.map(prependName(test.name))
)
);

const runTest = (test: Test): TaskEither<readonly TestFailedResult[], undefined> =>
const runTest = (test: Test): Task<TestsResult> =>
match(test)
.with({ assertion: 'single' }, ({ assert }) => runAssertion(assert))
.with({ assertion: 'multiple' }, runMultipleAssertion)
.exhaustive();

export const runTests =
(testsWithConfig: TestConfig) =>
(tests: readonly Test[]): TaskEither<readonly TestFailedResult[], undefined> =>
(tests: readonly Test[]): Task<TestsResult> =>
pipe(
tests,
readonlyArray.map(runTest),
runWithConcurrency({ concurrency: testsWithConfig.concurrency }),
arrayTaskValidation.run,
taskEither.map(() => undefined)
task.map(foldTestResult)
);
11 changes: 10 additions & 1 deletion src/type.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Either } from 'fp-ts/Either';
import type { Task } from 'fp-ts/Task';
import type * as retry from 'retry-ts';

Expand Down Expand Up @@ -55,7 +56,15 @@ export type TestError =
readonly exception: unknown;
};

export type TestFailedResult = {
export type TestFailResult = {
readonly name: string;
readonly error: TestError;
};

export type TestPassResult = {
readonly name: string;
};

export type TestEitherResult = Either<TestFailResult, TestPassResult>;

export type TestsResult = Either<readonly TestEitherResult[], readonly TestPassResult[]>;
12 changes: 3 additions & 9 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@ import { pipe } from 'fp-ts/function';
import * as src from '../src';
import * as srcNode from '../src/node';
import * as exit from './exitF';
import * as logErrors from './logErrorsF';
import * as log from './log';
import * as primitive from './primitive';
import * as timeout from './timeout';

const tests = [logErrors.tests, exit.tests, timeout.tests, primitive.tests];
const tests = [log.tests, exit.tests, timeout.tests, primitive.tests];

export const main = pipe(
tests,
readonlyArray.flatten,
src.runTests({}),
src.logErrors,
srcNode.exit
);
export const main = pipe(tests, readonlyArray.flatten, src.runTests({}), src.log, srcNode.exit);
4 changes: 2 additions & 2 deletions test/logErrorsF.ts → test/log.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ioRef, readonlyArray, string, task } from 'fp-ts';
import { pipe } from 'fp-ts/function';

import { logErrorsF, runTests, test } from '../src';
import { logF, runTests, test } from '../src';
import { testW } from '../src/test';

const green = '\x1b[32m';
Expand Down Expand Up @@ -38,7 +38,7 @@ const caseToTest = (tc: Case) =>
}),
],
runTests({}),
logErrorsF({ console: { log: logRef.write } })
logF({ console: { log: logRef.write } })
)
),
task.chainIOK((logRef) => logRef.read),
Expand Down

0 comments on commit bfed14d

Please sign in to comment.