-
Notifications
You must be signed in to change notification settings - Fork 286
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core-kernel): implement pipeline service
- Loading branch information
1 parent
292d9e8
commit be25226
Showing
6 changed files
with
227 additions
and
3 deletions.
There are no files selected for viewing
134 changes: 134 additions & 0 deletions
134
__tests__/unit/core-kernel/services/pipeline/pipeline.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import "jest-extended"; | ||
|
||
import { Application, Container } from "@packages/core-kernel"; | ||
import { Pipeline, Stage } from "@packages/core-kernel/src/services/pipeline"; | ||
|
||
let app: Application; | ||
let pipeline: Pipeline; | ||
beforeEach(() => { | ||
app = new Application(new Container.Container()); | ||
|
||
pipeline = new Pipeline(); | ||
}); | ||
|
||
describe("Pipeline", () => { | ||
describe("Class", () => { | ||
describe("instantiated", () => { | ||
it("should apply all stages (async)", async () => { | ||
class RemoveDash implements Stage { | ||
async process(payload: string) { | ||
return payload.replace("_", ""); | ||
} | ||
} | ||
|
||
class RemoveUnderscore implements Stage { | ||
async process(payload: string) { | ||
return payload.replace("-", " "); | ||
} | ||
} | ||
|
||
const actual: string = await pipeline | ||
.pipe(new RemoveDash()) | ||
.pipe(new RemoveUnderscore()) | ||
.process("_Hello-World"); | ||
|
||
expect(actual).toBe("Hello World"); | ||
}); | ||
|
||
it("should apply all stages (sync)", () => { | ||
class RemoveDash implements Stage { | ||
process(payload: string) { | ||
return payload.replace("_", ""); | ||
} | ||
} | ||
|
||
class RemoveUnderscore implements Stage { | ||
process(payload: string) { | ||
return payload.replace("-", " "); | ||
} | ||
} | ||
|
||
const actual: string = pipeline | ||
.pipe(new RemoveDash()) | ||
.pipe(new RemoveUnderscore()) | ||
.processSync("_Hello-World"); | ||
|
||
expect(actual).toBe("Hello World"); | ||
}); | ||
}); | ||
|
||
describe("resolved", () => { | ||
it("should apply all stages (async)", async () => { | ||
@Container.injectable() | ||
class RemoveDash implements Stage { | ||
async process(payload: string) { | ||
return payload.replace("_", ""); | ||
} | ||
} | ||
|
||
@Container.injectable() | ||
class RemoveUnderscore implements Stage { | ||
async process(payload: string) { | ||
return payload.replace("-", " "); | ||
} | ||
} | ||
|
||
const actual: string = await pipeline | ||
.pipe(app.resolve(RemoveDash)) | ||
.pipe(app.resolve(RemoveUnderscore)) | ||
.process("_Hello-World"); | ||
|
||
expect(actual).toBe("Hello World"); | ||
}); | ||
|
||
it("should apply all stages (sync)", () => { | ||
@Container.injectable() | ||
class RemoveDash implements Stage { | ||
process(payload: string) { | ||
return payload.replace("_", ""); | ||
} | ||
} | ||
|
||
@Container.injectable() | ||
class RemoveUnderscore implements Stage { | ||
process(payload: string) { | ||
return payload.replace("-", " "); | ||
} | ||
} | ||
|
||
const actual: string = pipeline | ||
.pipe(app.resolve(RemoveDash)) | ||
.pipe(app.resolve(RemoveUnderscore)) | ||
.processSync("_Hello-World"); | ||
|
||
expect(actual).toBe("Hello World"); | ||
}); | ||
}); | ||
}); | ||
|
||
describe("Function", () => { | ||
it("should apply all stages (async)", async () => { | ||
const removeDash = async (payload: string) => payload.replace("_", ""); | ||
const removeUnderscore = async (payload: string) => payload.replace("-", " "); | ||
|
||
const actual: string = await pipeline | ||
.pipe(removeDash) | ||
.pipe(removeUnderscore) | ||
.process("_Hello-World"); | ||
|
||
expect(actual).toBe("Hello World"); | ||
}); | ||
|
||
it("should apply all stages (sync)", () => { | ||
const removeDash = (payload: string) => payload.replace("_", ""); | ||
const removeUnderscore = (payload: string) => payload.replace("-", " "); | ||
|
||
const actual: string = pipeline | ||
.pipe(removeDash) | ||
.pipe(removeUnderscore) | ||
.processSync("_Hello-World"); | ||
|
||
expect(actual).toBe("Hello World"); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/** | ||
* @export | ||
* @interface Stage | ||
*/ | ||
export interface Stage { | ||
/** | ||
* Process the payload. | ||
* | ||
* @remarks | ||
* We generally avoid the use of any but with pipeline stages the payload could be any of | ||
* that type until it hits the end of the pipeline where it is returned in its final form. | ||
* | ||
* @param {*} payload | ||
* @memberof Stage | ||
*/ | ||
process(payload: any); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./contracts"; | ||
export * from "./pipeline"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { injectable } from "../../ioc"; | ||
import { Stage } from "./contracts"; | ||
|
||
/** | ||
* @export | ||
* @class Pipeline | ||
*/ | ||
@injectable() | ||
export class Pipeline { | ||
/** | ||
* Creates an instance of Pipeline. | ||
* | ||
* @param {(Array<Function | Stage>)} stages | ||
* @memberof Pipeline | ||
*/ | ||
public constructor(private readonly stages: Array<Function | Stage> = []) {} | ||
|
||
/** | ||
* Create a new pipeline with an appended stage. | ||
* | ||
* @param {Function} stage | ||
* @returns {Pipeline} | ||
* @memberof Pipeline | ||
*/ | ||
public pipe(stage: Function | Stage): Pipeline { | ||
const stages: Array<Function | Stage> = [...this.stages]; | ||
|
||
stages.push(stage); | ||
|
||
return new Pipeline(stages); | ||
} | ||
|
||
/** | ||
* Process the payload. (Asynchronous) | ||
* | ||
* @template T | ||
* @param {T} payload | ||
* @returns {(Promise<T | undefined>)} | ||
* @memberof Pipeline | ||
*/ | ||
public async process<T>(payload: T): Promise<T | undefined> { | ||
for (const stage of this.stages) { | ||
if ("process" in stage) { | ||
payload = await stage.process(payload); | ||
} else if (typeof stage === "function") { | ||
payload = await stage(payload); | ||
} | ||
} | ||
|
||
return payload; | ||
} | ||
|
||
/** | ||
* Process the payload. (Synchronous) | ||
* | ||
* @template T | ||
* @param {T} payload | ||
* @returns {(T | undefined)} | ||
* @memberof Pipeline | ||
*/ | ||
public processSync<T>(payload: T): T | undefined { | ||
for (const stage of this.stages) { | ||
if ("process" in stage) { | ||
payload = stage.process(payload); | ||
} else if (typeof stage === "function") { | ||
payload = stage(payload); | ||
} | ||
} | ||
|
||
return payload; | ||
} | ||
} |