Skip to content

Commit

Permalink
feat: 메시지 빌더 구현 (#52)
Browse files Browse the repository at this point in the history
* feat: 메시지 빌더 구현

* refactor: 임포트 순서 수정
  • Loading branch information
Coalery authored Jan 15, 2024
1 parent 267a9d1 commit 7c5a5a2
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/core/message/MessageBuilder.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Test } from '@nestjs/testing';
import { advanceTo, clear } from 'jest-date-mock';

import { MessageBuilder } from '@sight/core/message/MessageBuilder';

describe('MessageBuilder', () => {
let messageBuilder: MessageBuilder;

beforeAll(async () => {
advanceTo(new Date());

const testModule = await Test.createTestingModule({
providers: [MessageBuilder],
}).compile();

messageBuilder = testModule.get(MessageBuilder);
});

afterAll(() => {
clear();
});

test('파라미터가 없는 메시지는 그대로 반환해야 한다', () => {
const GIVEN_MESSAGE = 'Hello, World!';
const expected = GIVEN_MESSAGE;

const actual = messageBuilder.build(GIVEN_MESSAGE, {});

expect(actual).toEqual(expected);
});

test('파라미터 1개 있는 메시지는 파라미터를 포함하여 반환해야 한다', () => {
const GIVEN_MESSAGE = 'Hello, :username:!';
const expected = 'Hello, Lery!';

const actual = messageBuilder.build(GIVEN_MESSAGE, { username: 'Lery' });

expect(actual).toEqual(expected);
});

test('파라미터 5개 있는 메시지는 파라미터를 포함하여 반환해야 한다', () => {
const GIVEN_MESSAGE = ':some1: :some2: :some3: :some4: :some5:';
const expected = `1 2 3 4 5`;

const actual = messageBuilder.build(GIVEN_MESSAGE, {
some1: '1',
some2: '2',
some3: '3',
some4: '4',
some5: '5',
});

expect(actual).toEqual(expected);
});
});
16 changes: 16 additions & 0 deletions src/core/message/MessageBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Injectable } from '@nestjs/common';

type ExtractParams<T extends string> =
T extends `${infer A}:${infer Param}:${infer B}`
? { [key in Param]: string } & ExtractParams<`${A}${B}`>
: unknown;

// eslint-disable-next-line @typescript-eslint/ban-types
type Prettify<T> = {} & { [P in keyof T]: T[P] };

@Injectable()
export class MessageBuilder {
build<T extends string>(message: T, params: Prettify<ExtractParams<T>>) {
return message.replace(/:(\w+):/g, (_, key) => params[key]);
}
}

0 comments on commit 7c5a5a2

Please sign in to comment.