Skip to content

Commit

Permalink
Make @nestia/e2e to be much functional
Browse files Browse the repository at this point in the history
  • Loading branch information
samchon committed May 2, 2023
1 parent 25ca328 commit 11efe36
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 161 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/decorators/internal/TransformError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
*/
export function TransformError(method: string): Error {
return new Error(
`Error on nestia.core.${method}(): no transform has been configured. Configure "tsconfig.json" file following [Guide Documents](https://github.com/samchon/nestia/wiki/Setup#tsconfigjson).`,
`Error on nestia.core.${method}(): no transform has been configured. Run "npx typia setup" command.`,
);
}
2 changes: 1 addition & 1 deletion packages/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![npm version](https://img.shields.io/npm/v/@nestia/e2e.svg)](https://www.npmjs.com/package/@nestia/e2e)
[![Downloads](https://img.shields.io/npm/dm/@nestia/e2e.svg)](https://www.npmjs.com/package/@nestia/e2e)
[![Build Status](https://github.com/samchon/typia/workflows/build/badge.svg)](https://github.com/samchon/nestia/actions?query=workflow%3Abuild)
[![Guide Documents](https://img.shields.io/badge/wiki-documentation-forestgreen)](https://github.com/samchon/nestia/wiki)
[![Guide Documents](https://img.shields.io/badge/wiki-documentation-forestgreen)](https://typia.io/docs/)

Helper library for E2E testing in NestJS.

Expand Down
2 changes: 1 addition & 1 deletion packages/e2e/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/e2e",
"version": "0.1.8",
"version": "0.2.0",
"description": "E2E test utilify functions",
"main": "lib/index.js",
"scripts": {
Expand Down
149 changes: 71 additions & 78 deletions packages/e2e/src/ArrayUtil.ts
Original file line number Diff line number Diff line change
@@ -1,106 +1,99 @@
/**
* Utility functions for arrays.
*
*
* @author Jeongho Nam - https://github.com/samchon
*/
export namespace ArrayUtil {
export async function asyncFilter<Input>(
elements: readonly Input[],
pred: (
elem: Input,
index: number,
array: readonly Input[],
) => Promise<boolean>,
): Promise<Input[]> {
const ret: Input[] = [];
await asyncForEach(elements, async (elem, index, array) => {
const flag: boolean = await pred(elem, index, array);
if (flag === true) ret.push(elem);
});
return ret;
}

export async function asyncForEach<Input>(
elements: readonly Input[],
closure: (
elem: Input,
index: number,
array: readonly Input[],
) => Promise<any>,
): Promise<void> {
await asyncRepeat(elements.length, (index) =>
closure(elements[index], index, elements),
);
}
export const asyncFilter =
<Input>(elements: readonly Input[]) =>
async (
pred: (
elem: Input,
index: number,
array: readonly Input[],
) => Promise<boolean>,
): Promise<Input[]> => {
const ret: Input[] = [];
await asyncForEach(elements)(async (elem, index, array) => {
const flag: boolean = await pred(elem, index, array);
if (flag === true) ret.push(elem);
});
return ret;
};

export async function asyncMap<Input, Output>(
elements: readonly Input[],
closure: (
elem: Input,
index: number,
array: readonly Input[],
) => Promise<Output>,
): Promise<Output[]> {
const ret: Output[] = [];
await asyncForEach(elements, async (elem, index, array) => {
const output: Output = await closure(elem, index, array);
ret.push(output);
});
return ret;
}
export const asyncForEach =
<Input>(elements: readonly Input[]) =>
async (
closure: (
elem: Input,
index: number,
array: readonly Input[],
) => Promise<any>,
): Promise<void> => {
await asyncRepeat(elements.length)((index) =>
closure(elements[index], index, elements),
);
};

export async function asyncRepeat<T>(
count: number,
closure: (index: number) => Promise<T>,
): Promise<T[]> {
const indexes: number[] = new Array(count)
.fill(1)
.map((_, index) => index);
export const asyncMap =
<Input>(elements: readonly Input[]) =>
async <Output>(
closure: (
elem: Input,
index: number,
array: readonly Input[],
) => Promise<Output>,
): Promise<Output[]> => {
const ret: Output[] = [];
await asyncForEach(elements)(async (elem, index, array) => {
const output: Output = await closure(elem, index, array);
ret.push(output);
});
return ret;
};

const output: T[] = [];
for (const index of indexes) output.push(await closure(index));
export const asyncRepeat =
(count: number) =>
async <T>(closure: (index: number) => Promise<T>): Promise<T[]> => {
const indexes: number[] = new Array(count)
.fill(1)
.map((_, index) => index);

return output;
}
const output: T[] = [];
for (const index of indexes) output.push(await closure(index));

export function has<T>(
elements: readonly T[],
pred: (elem: T) => boolean,
): boolean {
return elements.find(pred) !== undefined;
}
return output;
};

export function repeat<T>(
count: number,
closure: (index: number) => T,
): T[] {
return new Array(count).fill("").map((_, index) => closure(index));
}
export const has =
<T>(elements: readonly T[]) =>
(pred: (elem: T) => boolean): boolean =>
elements.find(pred) !== undefined;

export function last<T>(array: T[]): T {
return array[array.length - 1];
}
export const repeat =
(count: number) =>
<T>(closure: (index: number) => T): T[] =>
new Array(count).fill("").map((_, index) => closure(index));

export function flat<T>(matrix: T[][]): T[] {
return ([] as T[]).concat(...matrix);
}
export const flat = <T>(matrix: T[][]): T[] =>
([] as T[]).concat(...matrix);

export function subsets<T>(array: T[]): T[][] {
export const subsets = <T>(array: T[]): T[][] => {
const check: boolean[] = new Array(array.length).fill(false);
const output: T[][] = [];
const dfs = (depth: number) => {

const dfs = (depth: number): void => {
if (depth === check.length)
output.push(array.filter((_v, idx) => check[idx]));
else {
check[depth] = true;
dfs(depth + 1);

check[depth] = false;
dfs(depth + 1);
}
};
dfs(0);
return output;
}
};
}
75 changes: 31 additions & 44 deletions packages/e2e/src/RandomGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ export namespace RandomGenerator {
* @param length Length of alphabets
* @returns Generated alphabets
*/
export function alphabets(length: number): string {
return new Array(length)
export const alphabets = (length: number): string =>
new Array(length)
.fill("")
.map(() => CHARACTERS[randint(0, CHARACTERS.length - 1)])
.join("");
}

/**
* Generate random alpha-numeric characters.
Expand All @@ -34,22 +33,20 @@ export namespace RandomGenerator {
* @param length Length of characters
* @returns Generated string
*/
export function alphaNumeric(length: number): string {
return new Array(length)
export const alphaNumeric = (length: number): string =>
new Array(length)
.fill("")
.map(() => LETTERS[randint(0, LETTERS.length - 1)])
.join("");
}

/**
* Generate random name.
*
* @param length Length of paragraph, default is 2 or 3
* @returns Generated name
*/
export function name(length: number = randint(2, 3)): string {
return paragraph(length)();
}
export const name = (length: number = randint(2, 3)): string =>
paragraph(length)();

/**
* Generate random paragraph.
Expand Down Expand Up @@ -106,40 +103,29 @@ export namespace RandomGenerator {
* @param content Target content
* @returns Random substring
*/
export function substring(content: string): string {
export const substring = (content: string): string => {
const first: number = randint(0, content.length - 1);
const last: number = randint(first + 1, content.length);

return content.substring(first, last).trim();
}
};

/**
* Generate random mobile number.
*
* @param prefix Prefix string, default is "010"
* @returns Random mobile number
* @example 010-334-0067
*/
export function mobile(prefix: string = "010"): string {
return `${prefix}${digit(3, 4)}${digit(4, 4)}`;
}

/**
* Generate random digit.
*
* Generate random digit that filling front with zero characters
* when value is less than maximum cipher.
*
* @param minC Minimum cipher
* @param maxC Maximum cipher
* @returns
*/
export function digit(minC: number, maxC: number): string {
const val: number = randint(0, Math.pow(10.0, maxC) - 1);
const log10: number = val ? Math.floor(Math.log10(val)) + 1 : 0;
const prefix: string = "0".repeat(Math.max(0, minC - log10));

return prefix + val.toString();
}
export const mobile = (prefix: string = "010"): string =>
[
prefix,
(() => {
const value = randint(0, 9999);
return value.toString().padStart(value < 1_000 ? 3 : 4, "0");
})(),
randint(0, 9999).toString().padStart(4, "0"),
].join("-");

/**
* Generate random date.
Expand All @@ -148,10 +134,10 @@ export namespace RandomGenerator {
* @param range Range of random milliseconds
* @returns Random date
*/
export function date(from: Date, range: number): Date {
const time: number = from.getTime() + randint(0, range);
return new Date(time);
}
export const date =
(from: Date) =>
(range: number): Date =>
new Date(from.getTime() + randint(0, range));

/**
* Pick random elements from an array.
Expand All @@ -160,19 +146,20 @@ export namespace RandomGenerator {
* @param count Number of count to pick
* @returns Sampled array
*/
export function sample<T>(array: T[], count: number): T[] {
const ret: T[] = [];
_Sample(array, back_inserter(ret), count);
return ret;
}
export const sample =
<T>(array: T[]) =>
(count: number): T[] => {
const ret: T[] = [];
_Sample(array, back_inserter(ret), count);
return ret;
};

/**
* Pick random element from an array.
*
* @param array Target array
* @returns picked element
*/
export function pick<T>(array: T[]): T {
return array[randint(0, array.length - 1)];
}
export const pick = <T>(array: T[]): T =>
array[randint(0, array.length - 1)];
}
18 changes: 10 additions & 8 deletions packages/e2e/src/StopWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,25 @@ export namespace StopWatch {
* @param task
* @returns
*/
export async function measure(task: Task): Promise<number> {
export const measure = async (task: Task): Promise<number> => {
const time: number = Date.now();
await task();
return Date.now() - time;
}
};

/**
*
* @param title
* @param task
* @returns
*/
export async function trace(title: string, task: Task): Promise<number> {
process.stdout.write(` - ${title}: `);
const time: number = await measure(task);
export const trace =
(title: string) =>
async (task: Task): Promise<number> => {
process.stdout.write(` - ${title}: `);
const time: number = await measure(task);

console.log(`${time.toLocaleString()} ms`);
return time;
}
console.log(`${time.toLocaleString()} ms`);
return time;
};
}
6 changes: 2 additions & 4 deletions packages/e2e/src/TestValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,8 @@ export namespace TestValidator {
async <Values extends any[]>(
props: ISearchProps<Entity, Values, Request>,
): Promise<void> => {
const samples: Entity[] = RandomGenerator.sample(
total,
sampleCount,
);
const samples: Entity[] =
RandomGenerator.sample(total)(sampleCount);
for (const s of samples) {
const values: Values = props.values(s);
const filtered: Entity[] = total.filter((entity) =>
Expand Down
Loading

0 comments on commit 11efe36

Please sign in to comment.