Skip to content

Commit

Permalink
JavaScript (v3): libs - Refactor and add new utility. (#5492)
Browse files Browse the repository at this point in the history
* JavaScript (v3): libs - Move Prompter.logSeparator to Logger.logSeparator.

* JavaScript (v3): Add scenario runner.
  • Loading branch information
cpyle0819 authored and ford-at-aws committed Dec 15, 2023
1 parent 5864ef3 commit 6c9b6b8
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class TopicsQueuesWkflw {
* @param {import('@aws-sdk/client-sns').SNSClient} snsClient
* @param {import('@aws-sdk/client-sqs').SQSClient} sqsClient
* @param {import('../../libs/prompter.js').Prompter} prompter
* @param {import('../../libs/slow-logger.js').Logger} logger
* @param {import('../../libs/logger.js').Logger} logger
*/
constructor(snsClient, sqsClient, prompter, logger) {
this.snsClient = snsClient;
Expand All @@ -72,7 +72,7 @@ export class TopicsQueuesWkflw {
});

if (this.isFifo) {
this.prompter.logSeparator(MESSAGES.headerDedup);
this.logger.logSeparator(MESSAGES.headerDedup);
await this.logger.log(MESSAGES.deduplicationNotice);
await this.logger.log(MESSAGES.deduplicationDescription);
this.autoDedup = await this.prompter.confirm({
Expand All @@ -88,7 +88,7 @@ export class TopicsQueuesWkflw {
});
if (this.isFifo) {
this.topicName += ".fifo";
this.prompter.logSeparator(MESSAGES.headerFifoNaming);
this.logger.logSeparator(MESSAGES.headerFifoNaming);
await this.logger.log(MESSAGES.appendFifoNotice);
}

Expand Down Expand Up @@ -184,7 +184,7 @@ export class TopicsQueuesWkflw {
);

if (index !== 0) {
this.prompter.logSeparator();
this.logger.logSeparator();
}

await this.logger.log(MESSAGES.attachPolicyNotice);
Expand Down Expand Up @@ -399,21 +399,21 @@ export class TopicsQueuesWkflw {
console.clear();

try {
this.prompter.logSeparator(MESSAGES.headerWelcome);
this.logger.logSeparator(MESSAGES.headerWelcome);
await this.welcome();
this.prompter.logSeparator(MESSAGES.headerFifo);
this.logger.logSeparator(MESSAGES.headerFifo);
await this.confirmFifo();
this.prompter.logSeparator(MESSAGES.headerCreateTopic);
this.logger.logSeparator(MESSAGES.headerCreateTopic);
await this.createTopic();
this.prompter.logSeparator(MESSAGES.headerCreateQueues);
this.logger.logSeparator(MESSAGES.headerCreateQueues);
await this.createQueues();
this.prompter.logSeparator(MESSAGES.headerAttachPolicy);
this.logger.logSeparator(MESSAGES.headerAttachPolicy);
await this.attachQueueIamPolicies();
this.prompter.logSeparator(MESSAGES.headerSubscribeQueues);
this.logger.logSeparator(MESSAGES.headerSubscribeQueues);
await this.subscribeQueuesToTopic();
this.prompter.logSeparator(MESSAGES.headerPublishMessage);
this.logger.logSeparator(MESSAGES.headerPublishMessage);
await this.publishMessages();
this.prompter.logSeparator(MESSAGES.headerReceiveMessages);
this.logger.logSeparator(MESSAGES.headerReceiveMessages);
await this.receiveAndDeleteMessages();
} catch (err) {
console.error(err);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const SNSClientMock = {

const LoggerMock = {
log: vi.fn(),
logSeparator: vi.fn(),
};

describe("TopicsQueuesWkflw", () => {
Expand Down Expand Up @@ -111,7 +112,6 @@ describe("TopicsQueuesWkflw", () => {
new SQSClient({}),
{
confirm: () => Promise.resolve(true),
logSeparator: vi.fn(),
},
LoggerMock,
);
Expand Down Expand Up @@ -151,7 +151,6 @@ describe("TopicsQueuesWkflw", () => {
{
confirm: () => Promise.resolve(true),
input: () => Promise.resolve("user-input"),
logSeparator: vi.fn(),
},
LoggerMock,
);
Expand Down Expand Up @@ -197,7 +196,6 @@ describe("TopicsQueuesWkflw", () => {
it("should attach a policy to each of the SQS queues", async () => {
const PrompterMock = {
confirm: vi.fn(() => Promise.resolve(true)),
logSeparator: vi.fn(() => {}),
};

const topicsQueuesWkflw = new TopicsQueuesWkflw(
Expand Down
37 changes: 37 additions & 0 deletions javascriptv3/example_code/libs/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

export class Logger {
/**
* @param {string} message
*/
log(message) {
console.log(message);
return Promise.resolve();
}

/**
* Log a horizontal rule to the console. If a message is provided,
* log a section header.
* @param {string?} message
*/
logSeparator(message) {
if (!message) {
console.log("\n", "*".repeat(80), "\n");
} else {
console.log(
"\n",
"*".repeat(80),
"\n",
"** ",
message,
" ".repeat(80 - message.length - 8),
"**\n",
"*".repeat(80),
"\n",
);
}
}
}
25 changes: 1 addition & 24 deletions javascriptv3/example_code/libs/prompter.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class Prompter {
checkContinue = async (prompt = "") => {
const prefix = prompt && prompt + " ";
let ok = await this.confirm({
message: `${prefix}Continue?"}`,
message: `${prefix}Continue?`,
});
if (!ok) throw new Error("Exiting...");
};
Expand All @@ -46,29 +46,6 @@ export class Prompter {
return confirm(options);
}

/**
* Log a horizontal rule to the console. If a message is provided,
* log a section header.
* @param {string?} message
*/
logSeparator(message) {
if (!message) {
console.log("\n", "*".repeat(80), "\n");
} else {
console.log(
"\n",
"*".repeat(80),
"\n",
"** ",
message,
" ".repeat(80 - message.length - 8),
"**\n",
"*".repeat(80),
"\n",
);
}
}

/**
* @param {{ message: string, choices: { name: string, value: string }[]}} options
*/
Expand Down
115 changes: 115 additions & 0 deletions javascriptv3/example_code/libs/scenario.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

import { Prompter } from "./prompter.js";
import { Logger } from "./logger.js";
import { SlowLogger } from "./slow-logger.js";

class Step {
/**
* @param {string} name
*/
constructor(name) {
this.name = name;
}
}

export class ScenarioOutput extends Step {
/**
* @param {string} name
* @param {string | (context: Record<string, any>) => string} value
* @param {{ slow: boolean }} options
*/
constructor(name, value, options = { slow: true }) {
super(name);
this.value = value;
this.options = options;
this.slowLogger = new SlowLogger(20);
this.logger = new Logger();
}

/**
* @param {Record<string, any>} context
*/
async handle(context) {
const output =
typeof this.value === "function" ? this.value(context) : this.value;
const logger = this.options.slow ? this.slowLogger : this.logger;
await logger.log(JSON.stringify(output));
}
}

export class ScenarioInput extends Step {
/**
* @param {string} name
* @param {string} prompt
* @param {{ type: "input" | "multi-select" | "select", choices: { name: string, value: string }[]} options
*/
constructor(name, prompt, options) {
super(name);
this.prompt = prompt;
this.options = options;
this.prompter = new Prompter();
}

/**
* @param {Record<string, any>} context
*/
async handle(context) {
if (this.options.type === "multi-select") {
context[this.name] = await this.prompter.checkbox({
message: this.prompt,
choices: this.options.choices,
});
} else if (this.options.type === "select") {
context[this.name] = await this.prompter.select({
message: this.prompt,
choices: this.options.choices,
});
} else if (this.options.type === "input") {
context[this.name] = await this.prompter.input({ message: this.prompt });
} else {
throw new Error(
`Error handling ScenarioInput, ${this.options.type} is not supported.`,
);
}
}
}

export class ScenarioAction extends Step {
/**
*
* @param {string} name
* @param {(context: Record<string, any>) => Promise<void>} action
*/
constructor(name, action) {
super(name);
this.action = action;
}

async handle(context) {
await this.action(context);
}
}

export class Scenario {
/**
* @type {Record<string, any>}
*/
context = {};

/**
* @param {(ScenarioOutput | ScenarioInput | ScenarioAction)[]} steps
*/
constructor(steps = []) {
this.steps = steps;
}

async run() {
for (const step of this.steps) {
await step.handle(this.context);
}
}
}
22 changes: 7 additions & 15 deletions javascriptv3/example_code/libs/slow-logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,27 @@
* SPDX-License-Identifier: Apache-2.0
*/

// snippet-start:[javascript.v3.wkflw.topicsandqueues.logger]
export class Logger {
/**
* @param {string} message
*/
log(message) {
console.log(message);
return Promise.resolve();
}
}
import { Logger } from "./logger.js";

// snippet-start:[javascript.v3.wkflw.topicsandqueues.logger]
export class SlowLogger extends Logger {
constructor(delayInMs) {
super();
this.delay = delayInMs;
}

sleep() {
_sleep() {
return new Promise((resolve) => setTimeout(resolve, this.delay));
}

/**
* @param {string} message
*/
async logSlow(message) {
async _logSlow(message) {
const chars = message.split("");
for (const c of chars) {
process.stdout.write(c);
await this.sleep();
await this._sleep();
}
process.stderr.write("\n");
}
Expand All @@ -49,12 +41,12 @@ export class SlowLogger extends Logger {
let line = "";
for (const word of words) {
if (line.length + word.length > maxWidth) {
await this.logSlow(line);
await this._logSlow(line);
line = "";
}
line += word + " ";
}
await this.logSlow(line);
await this._logSlow(line);
}
}
// snippet-end:[javascript.v3.wkflw.topicsandqueues.logger]
Loading

0 comments on commit 6c9b6b8

Please sign in to comment.