From c26d56c149d4c3f18516b2b082e2b1a330b7a767 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 5 Dec 2023 17:22:30 +0000 Subject: [PATCH 1/2] Add sort option --- src/cli.ts | 7 ++++--- src/contracts/ICliOptions.ts | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 0de5ab3..7902e18 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,4 +1,4 @@ -import { Command } from "commander"; +import { Command, Option } from "commander"; import randomBunny from "./index"; import ICliOptions from "./contracts/ICliOptions"; import { exit } from "process"; @@ -9,13 +9,14 @@ program .name('random-bunny') .description('Get a random image url from a subreddit of your choosing') .version('2.2') - .option('-s, --subreddit ', 'The subreddit to search', 'rabbits'); + .option('-s, --subreddit ', 'The subreddit to search', 'rabbits') + .addOption(new Option('--sort ', 'Sort by').default('hot').choices(['hot', 'new', 'top'])); program.parse(); const options: ICliOptions = program.opts(); -randomBunny(options.subreddit) +randomBunny(options.subreddit, options.sort) .then((response) => { if (response.IsSuccess) { const result = response.Result!; diff --git a/src/contracts/ICliOptions.ts b/src/contracts/ICliOptions.ts index c85971d..0d7353b 100644 --- a/src/contracts/ICliOptions.ts +++ b/src/contracts/ICliOptions.ts @@ -1,3 +1,4 @@ export default interface ICliOptions { subreddit: string, + sort: string, } \ No newline at end of file -- 2.45.2 From 9bca084bc4fb416fd7e13dfdadd0e8b8cc7eed8d Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 5 Dec 2023 17:50:10 +0000 Subject: [PATCH 2/2] Add tests --- src/cli.ts | 6 ++++ src/contracts/ICliOptions.ts | 1 + src/contracts/IReturnResult.ts | 2 ++ src/contracts/QueryResult.ts | 4 +++ src/index.ts | 16 +++++++++ tests/cli.test.ts | 60 +++++++++++++++++++++++++++++++++- 6 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/contracts/QueryResult.ts diff --git a/src/cli.ts b/src/cli.ts index 7902e18..6f0639f 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,6 +10,7 @@ program .description('Get a random image url from a subreddit of your choosing') .version('2.2') .option('-s, --subreddit ', 'The subreddit to search', 'rabbits') + .option('-q, --query-metadata', 'Include query metadata in result') .addOption(new Option('--sort ', 'Sort by').default('hot').choices(['hot', 'new', 'top'])); program.parse(); @@ -32,6 +33,11 @@ randomBunny(options.subreddit, options.sort) outputLines.push(`Upvotes = ${result.Ups}`); outputLines.push(`Url = ${result.Url}`); + if (options.queryMetadata != null) { + outputLines.push(`Query.Subreddit = ${response.Query.subreddit}`); + outputLines.push(`Query.Sort By = ${response.Query.sortBy}`); + } + console.log(outputLines.join("\n")); exit(0); } else { diff --git a/src/contracts/ICliOptions.ts b/src/contracts/ICliOptions.ts index 0d7353b..ce5ada4 100644 --- a/src/contracts/ICliOptions.ts +++ b/src/contracts/ICliOptions.ts @@ -1,4 +1,5 @@ export default interface ICliOptions { subreddit: string, sort: string, + queryMetadata?: boolean, } \ No newline at end of file diff --git a/src/contracts/IReturnResult.ts b/src/contracts/IReturnResult.ts index 780069d..b5f5303 100644 --- a/src/contracts/IReturnResult.ts +++ b/src/contracts/IReturnResult.ts @@ -1,8 +1,10 @@ import IError from "./IError.js"; import IRedditResult from "./IRedditResult.js"; +import QueryResult from "./QueryResult.js"; export default interface IReturnResult { IsSuccess: boolean; + Query: QueryResult; Result?: IRedditResult; Error?: IError; } \ No newline at end of file diff --git a/src/contracts/QueryResult.ts b/src/contracts/QueryResult.ts new file mode 100644 index 0000000..ee97e30 --- /dev/null +++ b/src/contracts/QueryResult.ts @@ -0,0 +1,4 @@ +export default interface QueryResult { + subreddit: string, + sortBy: string, +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 26195c4..29f8ecf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,6 +26,10 @@ export default async function randomBunny(subreddit: string, sortBy: string = 'h if (!result) { return { IsSuccess: false, + Query: { + subreddit: subreddit, + sortBy: sortBy, + }, Error: { Code: ErrorCode.FailedToFetchReddit, Message: ErrorMessages.FailedToFetchReddit, @@ -38,6 +42,10 @@ export default async function randomBunny(subreddit: string, sortBy: string = 'h if (!json) { return { IsSuccess: false, + Query: { + subreddit: subreddit, + sortBy: sortBy, + }, Error: { Code: ErrorCode.UnableToParseJSON, Message: ErrorMessages.UnableToParseJSON, @@ -56,6 +64,10 @@ export default async function randomBunny(subreddit: string, sortBy: string = 'h if (dataWithImages.length == 0) { return { IsSuccess: false, + Query: { + subreddit: subreddit, + sortBy: sortBy, + }, Error: { Code: ErrorCode.NoImageResultsFound, Message: ErrorMessages.NoImageResultsFound, @@ -83,6 +95,10 @@ export default async function randomBunny(subreddit: string, sortBy: string = 'h return { IsSuccess: true, + Query: { + subreddit: subreddit, + sortBy: sortBy, + }, Result: redditResult }; } \ No newline at end of file diff --git a/tests/cli.test.ts b/tests/cli.test.ts index 6d105d3..aa68d3b 100644 --- a/tests/cli.test.ts +++ b/tests/cli.test.ts @@ -88,7 +88,65 @@ describe('subreddit', () => { expect(subreddit).toBe('Horses'); }, 5000); -}) +}); + +describe('sort', () => { + test('GIVEN --sort is not supplird, EXPECT sort to be defaulted', async () => { + const result = await cli(['-q'], '.'); + + const sortBy = result.stdout.split('\n') + .find(x => x && x.length > 0 && x.split(' = ')[0] == 'Query.Sort By')! + .split(' = ')[1]; + + expect(sortBy).toBe('hot'); + }, 5000); + + test('GIVEN --sort is supplied WITH a valid input, EXPECT sort to be used', async () => { + const result = await cli(['-q', '--sort', 'new'], '.'); + + const sortBy = result.stdout.split('\n') + .find(x => x && x.length > 0 && x.split(' = ')[0] == 'Query.Sort By')! + .split(' = ')[1]; + + expect(sortBy).toBe('new'); + }, 5000); + + test('GIVEN --sort is supplied WITH an invalid input, EXPECT error', async () => { + const result = await cli(['-q', '--sort', 'invalid'], '.'); + + expect(result.code).toBe(1); + expect(result.stderr).toBe("error: option '--sort ' argument 'invalid' is invalid. Allowed choices are hot, new, top.\n"); + }); +}); + +describe('query-metadata', () => { + test('GIVEN --query-metadata is not supplied, EXPECT no query metadata returned', async () => { + const result = await cli([], '.'); + + const query = result.stdout.split('\n') + .find(x => x && x.length > 0 && x.split(' = ')[0].startsWith('Query')); + + expect(query).toBeUndefined(); + }, 5000); + + test('GIVEN --query-metadata is not supplied, EXPECT no query metadata returned', async () => { + const result = await cli(['--query-metadata'], '.'); + + const query = result.stdout.split('\n') + .find(x => x && x.length > 0 && x.split(' = ')[0].startsWith('Query')); + + expect(query).toBeDefined(); + }, 5000); + + test('GIVEN -q is not supplied, EXPECT no query metadata returned', async () => { + const result = await cli(['-q'], '.'); + + const query = result.stdout.split('\n') + .find(x => x && x.length > 0 && x.split(' = ')[0].startsWith('Query')); + + expect(query).toBeDefined(); + }, 5000); +}); function cli(args: string[], cwd: string): Promise { return new Promise(resolve => { -- 2.45.2