diff --git a/.gitignore b/.gitignore index 0f55829..e113703 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,4 @@ dist .yarn/install-state.gz .pnp.* +.idea \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index b58b603..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml deleted file mode 100644 index d23208f..0000000 --- a/.idea/jsLibraryMappings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 13ac5f6..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/ts-module-template.iml b/.idea/ts-module-template.iml deleted file mode 100644 index 2cd19fb..0000000 --- a/.idea/ts-module-template.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index 60f72b8..abe36df 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,7 @@ -# ๐Ÿงฉ typescript-module +# ๐Ÿ”ค Hangul -TypeScript๋ฅผ ์‚ฌ์šฉํ•œ ๋ชจ๋“ˆ์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ ๋ ˆํฌ์ง€ํ† ๋ฆฌ. +```js +require('hangul'); -- Bot App: [`๋ฉ”์‹ ์ €๋ด‡R`](https://github.com/MessengerBotTeam/msgbot-old-release/releases/tag/0.7.36a) (0.7.36a ๋ฒ„์ „ ์ด์ƒ) -- CI/CD: [`GitHub Actions`](https://github.com/features/actions) -- Module Bundler: [`Rollup`](https://rollupjs.org/) -- Test: [`Vitest`](https://vitest.dev/) -- Execute: [`TSX`](https://tsx.is/) -- Runtime: [`Node.js`](https://nodejs.org/en) - -## ๐Ÿ“œ features -- `npm run build:all-in-one`: `src` ํด๋”์˜ ๋ชจ๋“  ์†Œ์Šค๋ฅผ ํ•˜๋‚˜์˜ `.js`, `.d.ts` ํŒŒ์ผ๋กœ ๋งŒ๋“ค์–ด `dist/all`์— ๋นŒ๋“œ -- `npm run build:no-all-in-one`: `src` ํด๋”์˜ ๊ฐ ํŒŒ์ผ๋“ค์„ ํŒŒ์ผ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•œ ์ฑ„ `.js`, `.d.ts` ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•ด `dist/preserve`์— ๋นŒ๋“œ -- `package.json`์— `version` ํ‚ค๊ฐ€ ๋ณ€๊ฒฝ๋œ ์ฑ„๋กœ ํ‘ธ์‰ฌํ•˜๋ฉด ์ž๋™์œผ๋กœ ํ•ด๋‹น ๋ฒ„์ „์œผ๋กœ ๋ฆด๋ฆฌ์ฆˆ ์ƒ์„ฑ. (`v1.0.0-alpha` ์ฒ˜๋Ÿผ ์“ฐ๋ฉด prerelease๋กœ ์„ค์ •๋จ) - -> [!NOTE] -> `package.json` ์—์„œ `directories` ํ‚ค๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ๋นŒ๋“œ ํƒ€๊ฒŸ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ - -## โœ… prepare -1. ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์„ค์ •์—์„œ `GitHub Actions` ๊ฐ€ ์ ์ ˆํ•œ ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. - - `Settings > Actions > General` ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. - - `Workflow permissions` ์—์„œ `Read and write permissions` ๋ฅผ ์„ ํƒํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. -2. `package.json` ํŒŒ์ผ์„ ์—ด์–ด `name`, `version`, `description`, `author`, `license` ๋“ฑ์˜ ํ•„๋“œ๋ฅผ ์ ์ ˆํžˆ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. -3. `npm install` ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์˜์กด์„ฑ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. +console.log('๋‹ญ'.์ด๊ฐ€ + ' ๊ผฌ๊ผฌ๋Œ ์šธ๊ณ , ์˜ค๋ฆฌ'.๊ฐ€ + ' ๊ฝฅ๊ฝฅ ์šด๋‹ค.'); +``` diff --git a/examples/index.js b/examples/index.js index d31e478..3b9ac4f 100644 --- a/examples/index.js +++ b/examples/index.js @@ -1 +1,5 @@ -// example code \ No newline at end of file +import '../src'; +import { disassemble } from 'hangul'; + +"์•ˆ๋…•ํ•˜์„ธ์š”".isHangul(); +disassemble("์•ˆ๋…•ํ•˜์„ธ์š”"); diff --git a/package-lock.json b/package-lock.json index edcc276..d3e6312 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "ts-module-template", + "name": "hangul", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "ts-module-template", + "name": "hangul", "version": "1.0.0", "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 50039e3..cafeb5b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "ts-module-template", - "version": "1.0.0", - "description": "template for typescript module", + "name": "hangul", + "version": "0.1.0-beta", + "description": "hangul helper module", "main": "src/index.ts", "directories": { "example": "./examples", diff --git a/src/hangul.ts b/src/hangul.ts new file mode 100644 index 0000000..6192ac9 --- /dev/null +++ b/src/hangul.ts @@ -0,0 +1,22 @@ +export function _isHangul(text: string): boolean { + return text.length > 0 && [...text].every(ch => '๊ฐ€' <= ch && ch <= 'ํžฃ'); +} + +export function isHangul(text: string): boolean { + return /^[๊ฐ€-ํžฃ]+$/.test(text); +} + +// export function disassemble(text: string): string[]; +// export function disassembleGroups(text: string): string[][]; +// export function assemble(letters: string[]): string; + +// export function to์˜ˆ์‚ฌ์†Œ๋ฆฌ(letter: string): string; +// export function to๊ฑฐ์„ผ์†Œ๋ฆฌ(letter: string): string; +// export function to๋œ์†Œ๋ฆฌ(letter: string): string; + +// export function canBe์ดˆ์„ฑ(letter: string): boolean; +// export function canBe์ค‘์„ฑ(letter: string): boolean; +// export function canBe์ข…์„ฑ(letter: string): boolean; + +// export function has๋ฐ›์นจ(); +// ... \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index f01c1c2..a481391 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1 @@ -const bot = BotManager.getCurrentBot(); - -bot.addListener(Event.MESSAGE, msg => { - if (msg.content === '/ping') - msg.reply('pong!'); - else if (msg.content === '/hello') - msg.reply(`Hello, ${msg.author.name}!`); -}); \ No newline at end of file +export * from './josa'; \ No newline at end of file diff --git a/src/josa.test.ts b/src/josa.test.ts new file mode 100644 index 0000000..56573d6 --- /dev/null +++ b/src/josa.test.ts @@ -0,0 +1,233 @@ +import { describe, test, expect } from 'vitest'; + +import { get์กฐ์‚ฌ, apply์กฐ์‚ฌ } from './josa'; +import './josa'; + +describe('josa', () => { + test('์ฃผ๊ฒฉ์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์ƒดํ‘ธ', '์ด/๊ฐ€')).toBe('์ƒดํ‘ธ๊ฐ€'); + expect('์ƒดํ‘ธ'.์ด๊ฐ€).toBe('์ƒดํ‘ธ๊ฐ€'); + expect('์ƒดํ‘ธ'.์ด).toBe('์ƒดํ‘ธ๊ฐ€'); + expect('์ƒดํ‘ธ'.๊ฐ€).toBe('์ƒดํ‘ธ๊ฐ€'); + expect(apply์กฐ์‚ฌ('์นซ์†”', '์ด/๊ฐ€')).toBe('์นซ์†”์ด'); + expect('์นซ์†”'.์ด๊ฐ€).toBe('์นซ์†”์ด'); + expect('์นซ์†”'.์ด).toBe('์นซ์†”์ด'); + expect('์นซ์†”'.๊ฐ€).toBe('์นซ์†”์ด'); + }); + test('๋ชฉ์ ๊ฒฉ์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์ƒดํ‘ธ', '์„/๋ฅผ')).toBe('์ƒดํ‘ธ๋ฅผ'); + expect('์ƒดํ‘ธ'.์„๋ฅผ).toBe('์ƒดํ‘ธ๋ฅผ'); + expect('์ƒดํ‘ธ'.์„).toBe('์ƒดํ‘ธ๋ฅผ'); + expect('์ƒดํ‘ธ'.๋ฅผ).toBe('์ƒดํ‘ธ๋ฅผ'); + expect(apply์กฐ์‚ฌ('์นซ์†”', '์„/๋ฅผ')).toBe('์นซ์†”์„'); + expect('์นซ์†”'.์„๋ฅผ).toBe('์นซ์†”์„'); + expect('์นซ์†”'.์„).toBe('์นซ์†”์„'); + expect('์นซ์†”'.๋ฅผ).toBe('์นซ์†”์„'); + }); + test('๋Œ€์กฐ์˜ ๋ณด์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์ƒดํ‘ธ', '์€/๋Š”')).toBe('์ƒดํ‘ธ๋Š”'); + expect('์ƒดํ‘ธ'.์€๋Š”).toBe('์ƒดํ‘ธ๋Š”'); + expect('์ƒดํ‘ธ'.์€).toBe('์ƒดํ‘ธ๋Š”'); + expect('์ƒดํ‘ธ'.๋Š”).toBe('์ƒดํ‘ธ๋Š”'); + expect(apply์กฐ์‚ฌ('์นซ์†”', '์€/๋Š”')).toBe('์นซ์†”์€'); + expect('์นซ์†”'.์€๋Š”).toBe('์นซ์†”์€'); + expect('์นซ์†”'.์€).toBe('์นซ์†”์€'); + expect('์นซ์†”'.๋Š”).toBe('์นซ์†”์€'); + }); + test('๋ฐฉํ–ฅ์˜ ๊ฒฉ์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('๋ฐ”๊นฅ', '์œผ๋กœ/๋กœ')).toBe('๋ฐ”๊นฅ์œผ๋กœ'); + expect('๋ฐ”๊นฅ'.์œผ๋กœ).toBe('๋ฐ”๊นฅ์œผ๋กœ'); + expect('๋ฐ”๊นฅ'.๋กœ).toBe('๋ฐ”๊นฅ์œผ๋กœ'); + expect(apply์กฐ์‚ฌ('๋‚ด๋ถ€', '์œผ๋กœ/๋กœ')).toBe('๋‚ด๋ถ€๋กœ'); + expect('๋‚ด๋ถ€'.์œผ๋กœ).toBe('๋‚ด๋ถ€๋กœ'); + expect('๋‚ด๋ถ€'.๋กœ).toBe('๋‚ด๋ถ€๋กœ'); + }); + test('๋ฐฉํ–ฅ์˜ ๊ฒฉ์กฐ์‚ฌ ใ„น ๋ฐ›์นจ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(apply์กฐ์‚ฌ('์ง€๋ฆ„๊ธธ', '์œผ๋กœ/๋กœ')).toBe('์ง€๋ฆ„๊ธธ๋กœ'); + expect('์ง€๋ฆ„๊ธธ'.์œผ๋กœ).toBe('์ง€๋ฆ„๊ธธ๋กœ'); + expect('์ง€๋ฆ„๊ธธ'.๋กœ).toBe('์ง€๋ฆ„๊ธธ๋กœ'); + }); + test('๋น„๊ต์˜ ๊ฒฉ์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์ƒดํ‘ธ', '์™€/๊ณผ')).toBe('์ƒดํ‘ธ์™€'); + expect('์ƒดํ‘ธ'.์™€๊ณผ).toBe('์ƒดํ‘ธ์™€'); + expect('์ƒดํ‘ธ'.์™€).toBe('์ƒดํ‘ธ์™€'); + expect('์ƒดํ‘ธ'.๊ณผ).toBe('์ƒดํ‘ธ์™€'); + expect(apply์กฐ์‚ฌ('์นซ์†”', '์™€/๊ณผ')).toBe('์นซ์†”๊ณผ'); + expect('์นซ์†”'.์™€๊ณผ).toBe('์นซ์†”๊ณผ'); + expect('์นซ์†”'.์™€).toBe('์นซ์†”๊ณผ'); + expect('์นซ์†”'.๊ณผ).toBe('์นซ์†”๊ณผ'); + }); + test('์„ ํƒ์˜ ๋ณด์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์ƒดํ‘ธ', '์ด๋‚˜/๋‚˜')).toBe('์ƒดํ‘ธ๋‚˜'); + expect('์ƒดํ‘ธ'.์ด๋‚˜).toBe('์ƒดํ‘ธ๋‚˜'); + expect('์ƒดํ‘ธ'.๋‚˜).toBe('์ƒดํ‘ธ๋‚˜'); + expect(apply์กฐ์‚ฌ('์นซ์†”', '์ด๋‚˜/๋‚˜')).toBe('์นซ์†”์ด๋‚˜'); + expect('์นซ์†”'.์ด๋‚˜).toBe('์นซ์†”์ด๋‚˜'); + expect('์นซ์†”'.๋‚˜).toBe('์นซ์†”์ด๋‚˜'); + }); + test('ํ™”์ œ์˜ ๋ณด์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์ƒดํ‘ธ', '์ด๋ž€/๋ž€')).toBe('์ƒดํ‘ธ๋ž€'); + expect('์ƒดํ‘ธ'.์ด๋ž€).toBe('์ƒดํ‘ธ๋ž€'); + expect('์ƒดํ‘ธ'.๋ž€).toBe('์ƒดํ‘ธ๋ž€'); + expect(apply์กฐ์‚ฌ('์นซ์†”', '์ด๋ž€/๋ž€')).toBe('์นซ์†”์ด๋ž€'); + expect('์นซ์†”'.์ด๋ž€).toBe('์นซ์†”์ด๋ž€'); + expect('์นซ์†”'.๋ž€).toBe('์นซ์†”์ด๋ž€'); + }); + test('ํ˜ธ๊ฒฉ์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์ฒ ์ˆ˜', '์•„/์•ผ')).toBe('์ฒ ์ˆ˜์•ผ'); + expect('์ฒ ์ˆ˜'.์•„์•ผ).toBe('์ฒ ์ˆ˜์•ผ'); + expect('์ฒ ์ˆ˜'.์•„).toBe('์ฒ ์ˆ˜์•ผ'); + expect('์ฒ ์ˆ˜'.์•ผ).toBe('์ฒ ์ˆ˜์•ผ'); + expect(apply์กฐ์‚ฌ('๊ธธ๋™', '์•„/์•ผ')).toBe('๊ธธ๋™์•„'); + expect('๊ธธ๋™'.์•„์•ผ).toBe('๊ธธ๋™์•„'); + expect('๊ธธ๋™'.์•„).toBe('๊ธธ๋™์•„'); + expect('๊ธธ๋™'.์•ผ).toBe('๊ธธ๋™์•„'); + }); + test('์ ‘์†์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('๊ณ ๊ธฐ', '์ด๋ž‘/๋ž‘')).toBe('๊ณ ๊ธฐ๋ž‘'); + expect('๊ณ ๊ธฐ'.์ด๋ž‘).toBe('๊ณ ๊ธฐ๋ž‘'); + expect('๊ณ ๊ธฐ'.๋ž‘).toBe('๊ณ ๊ธฐ๋ž‘'); + expect(apply์กฐ์‚ฌ('๊ณผ์ผ', '์ด๋ž‘/๋ž‘')).toBe('๊ณผ์ผ์ด๋ž‘'); + expect('๊ณผ์ผ'.์ด๋ž‘).toBe('๊ณผ์ผ์ด๋ž‘'); + expect('๊ณผ์ผ'.๋ž‘).toBe('๊ณผ์ผ์ด๋ž‘'); + }); + test('์ฃผ์ œ์˜ ๋ณด์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์˜์‚ฌ', '์ด๋ผ/๋ผ')).toBe('์˜์‚ฌ๋ผ'); + expect('์˜์‚ฌ'.์ด๋ผ).toBe('์˜์‚ฌ๋ผ'); + expect('์˜์‚ฌ'.๋ผ).toBe('์˜์‚ฌ๋ผ'); + expect(apply์กฐ์‚ฌ('์„ ์ƒ๋‹˜', '์ด๋ผ/๋ผ')).toBe('์„ ์ƒ๋‹˜์ด๋ผ'); + expect('์„ ์ƒ๋‹˜'.์ด๋ผ).toBe('์„ ์ƒ๋‹˜์ด๋ผ'); + expect('์„ ์ƒ๋‹˜'.๋ผ).toBe('์„ ์ƒ๋‹˜์ด๋ผ'); + }); + test('์„œ์ˆ ๊ฒฉ์กฐ์‚ฌ์™€ ์ข…๊ฒฐ์–ด๋ฏธ', () => { + expect(apply์กฐ์‚ฌ('์‚ฌ๊ณผ', '์ด์—์š”/์˜ˆ์š”')).toBe('์‚ฌ๊ณผ์˜ˆ์š”'); + expect('์‚ฌ๊ณผ'.์ด์—์š”).toBe('์‚ฌ๊ณผ์˜ˆ์š”'); + expect('์‚ฌ๊ณผ'.์˜ˆ์š”).toBe('์‚ฌ๊ณผ์˜ˆ์š”'); + expect(apply์กฐ์‚ฌ('์ฑ…', '์ด์—์š”/์˜ˆ์š”')).toBe('์ฑ…์ด์—์š”'); + expect('์ฑ…'.์ด์—์š”).toBe('์ฑ…์ด์—์š”'); + expect('์ฑ…'.์˜ˆ์š”).toBe('์ฑ…์ด์—์š”'); + }); + test('์„œ์ˆ ๊ฒฉ์กฐ์‚ฌ์™€ ์ข…๊ฒฐ์–ด๋ฏธ, "์ด" ๋กœ ๋๋‚˜๋Š” ๋‹จ์–ด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(apply์กฐ์‚ฌ('๋•Œ๋ฐ€์ด', '์ด์—์š”/์˜ˆ์š”')).toBe('๋•Œ๋ฐ€์ด์˜ˆ์š”'); + expect('๋•Œ๋ฐ€์ด'.์ด์—์š”).toBe('๋•Œ๋ฐ€์ด์˜ˆ์š”'); + expect('๋•Œ๋ฐ€์ด'.์˜ˆ์š”).toBe('๋•Œ๋ฐ€์ด์˜ˆ์š”'); + }); + test('์ง€์œ„๋‚˜ ์‹ ๋ถ„ ๋˜๋Š” ์ž๊ฒฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์œ„๊ฒฉ์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('ํ•™์ƒ', '์œผ๋กœ์„œ/๋กœ์„œ')).toBe('ํ•™์ƒ์œผ๋กœ์„œ'); + expect('ํ•™์ƒ'.์œผ๋กœ์„œ).toBe('ํ•™์ƒ์œผ๋กœ์„œ'); + expect('ํ•™์ƒ'.๋กœ์„œ).toBe('ํ•™์ƒ์œผ๋กœ์„œ'); + expect(apply์กฐ์‚ฌ('๋ถ€๋ชจ', '์œผ๋กœ์„œ/๋กœ์„œ')).toBe('๋ถ€๋ชจ๋กœ์„œ'); + expect('๋ถ€๋ชจ'.์œผ๋กœ์„œ).toBe('๋ถ€๋ชจ๋กœ์„œ'); + expect('๋ถ€๋ชจ'.๋กœ์„œ).toBe('๋ถ€๋ชจ๋กœ์„œ'); + }); + test('์ง€์œ„๋‚˜ ์‹ ๋ถ„ ๋˜๋Š” ์ž๊ฒฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์œ„๊ฒฉ์กฐ์‚ฌ ใ„น ๋ฐ›์นจ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(apply์กฐ์‚ฌ('๋ผ์ด๋ฒŒ', '์œผ๋กœ์„œ/๋กœ์„œ')).toBe('๋ผ์ด๋ฒŒ๋กœ์„œ'); + expect('๋ผ์ด๋ฒŒ'.์œผ๋กœ์„œ).toBe('๋ผ์ด๋ฒŒ๋กœ์„œ'); + expect('๋ผ์ด๋ฒŒ'.๋กœ์„œ).toBe('๋ผ์ด๋ฒŒ๋กœ์„œ'); + }); + test('์ˆ˜๋‹จ์˜ ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋„๊ตฌ๊ฒฉ์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('ํ† ํฐ', '์œผ๋กœ์จ/๋กœ์จ')).toBe('ํ† ํฐ์œผ๋กœ์จ'); + expect('ํ† ํฐ'.์œผ๋กœ์จ).toBe('ํ† ํฐ์œผ๋กœ์จ'); + expect('ํ† ํฐ'.๋กœ์จ).toBe('ํ† ํฐ์œผ๋กœ์จ'); + expect(apply์กฐ์‚ฌ('ํ•จ์ˆ˜', '์œผ๋กœ์จ/๋กœ์จ')).toBe('ํ•จ์ˆ˜๋กœ์จ'); + expect('ํ•จ์ˆ˜'.์œผ๋กœ์จ).toBe('ํ•จ์ˆ˜๋กœ์จ'); + expect('ํ•จ์ˆ˜'.๋กœ์จ).toBe('ํ•จ์ˆ˜๋กœ์จ'); + }); + test('์ˆ˜๋‹จ์˜ ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋„๊ตฌ๊ฒฉ์กฐ์‚ฌ ใ„น ๋ฐ›์นจ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(apply์กฐ์‚ฌ('๊ฑด๋ฌผ', '์œผ๋กœ์จ/๋กœ์จ')).toBe('๊ฑด๋ฌผ๋กœ์จ'); + expect('๊ฑด๋ฌผ'.์œผ๋กœ์จ).toBe('๊ฑด๋ฌผ๋กœ์จ'); + expect('๊ฑด๋ฌผ'.๋กœ์จ).toBe('๊ฑด๋ฌผ๋กœ์จ'); + }); + test('์–ด๋–ค ํ–‰๋™์˜ ์ถœ๋ฐœ์ ์ด๋‚˜ ๋น„๋กฏ๋˜๋Š” ๋Œ€์ƒ์ž„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒฉ ์กฐ์‚ฌ', () => { + expect(apply์กฐ์‚ฌ('์—ญ์‚ผ๋™', '์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ')).toBe('์—ญ์‚ผ๋™์œผ๋กœ๋ถ€ํ„ฐ'); + expect('์—ญ์‚ผ๋™'.์œผ๋กœ๋ถ€ํ„ฐ).toBe('์—ญ์‚ผ๋™์œผ๋กœ๋ถ€ํ„ฐ'); + expect('์—ญ์‚ผ๋™'.๋กœ๋ถ€ํ„ฐ).toBe('์—ญ์‚ผ๋™์œผ๋กœ๋ถ€ํ„ฐ'); + expect(apply์กฐ์‚ฌ('์ €๊ธฐ', '์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ')).toBe('์ €๊ธฐ๋กœ๋ถ€ํ„ฐ'); + expect('์ €๊ธฐ'.์œผ๋กœ๋ถ€ํ„ฐ).toBe('์ €๊ธฐ๋กœ๋ถ€ํ„ฐ'); + expect('์ €๊ธฐ'.๋กœ๋ถ€ํ„ฐ).toBe('์ €๊ธฐ๋กœ๋ถ€ํ„ฐ'); + }); + test('์–ด๋–ค ํ–‰๋™์˜ ์ถœ๋ฐœ์ ์ด๋‚˜ ๋น„๋กฏ๋˜๋Š” ๋Œ€์ƒ์ž„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒฉ ์กฐ์‚ฌ ใ„น ๋ฐ›์นจ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(apply์กฐ์‚ฌ('๋™๊ตด', '์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ')).toBe('๋™๊ตด๋กœ๋ถ€ํ„ฐ'); + expect('๋™๊ตด'.์œผ๋กœ๋ถ€ํ„ฐ).toBe('๋™๊ตด๋กœ๋ถ€ํ„ฐ'); + expect('๋™๊ตด'.๋กœ๋ถ€ํ„ฐ).toBe('๋™๊ตด๋กœ๋ถ€ํ„ฐ'); + }); + test('๋‹จ์–ด๊ฐ€ ๋นˆ ๋ฌธ์ž์—ด์ผ ๊ฒฝ์šฐ ๋นˆ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.', () => { + expect(apply์กฐ์‚ฌ('', '์ด/๊ฐ€')).toBe(''); + expect(''.์ด๊ฐ€).toBe(''); + expect(''.์ด).toBe(''); + expect(''.๊ฐ€).toBe(''); + }); +}); + +describe('josa.pick', () => { + test('์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋นˆ ๋ฌธ์ž์—ด์ด๋ผ๋ฉด ์˜ต์…˜ ์ค‘ ์ฒซ ๋ฒˆ์งธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.', () => { + expect(get์กฐ์‚ฌ('', '์ด/๊ฐ€')).toBe('์ด'); + }); + test('์ฃผ๊ฒฉ์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('์ƒดํ‘ธ', '์ด/๊ฐ€')).toBe('๊ฐ€'); + expect(get์กฐ์‚ฌ('์นซ์†”', '์ด/๊ฐ€')).toBe('์ด'); + }); + test('๋ชฉ์ ๊ฒฉ์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('์ƒดํ‘ธ', '์„/๋ฅผ')).toBe('๋ฅผ'); + expect(get์กฐ์‚ฌ('์นซ์†”', '์„/๋ฅผ')).toBe('์„'); + }); + test('๋Œ€์กฐ์˜ ๋ณด์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('์ƒดํ‘ธ', '์€/๋Š”')).toBe('๋Š”'); + expect(get์กฐ์‚ฌ('์นซ์†”', '์€/๋Š”')).toBe('์€'); + }); + test('๋ฐฉํ–ฅ์˜ ๊ฒฉ์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('๋ฐ”๊นฅ', '์œผ๋กœ/๋กœ')).toBe('์œผ๋กœ'); + expect(get์กฐ์‚ฌ('๋‚ด๋ถ€', '์œผ๋กœ/๋กœ')).toBe('๋กœ'); + }); + test('๋ฐฉํ–ฅ์˜ ๊ฒฉ์กฐ์‚ฌ ใ„น ๋ฐ›์นจ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(get์กฐ์‚ฌ('์ง€๋ฆ„๊ธธ', '์œผ๋กœ/๋กœ')).toBe('๋กœ'); + }); + test('๋น„๊ต์˜ ๊ฒฉ์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('์ƒดํ‘ธ', '์™€/๊ณผ')).toBe('์™€'); + expect(get์กฐ์‚ฌ('์นซ์†”', '์™€/๊ณผ')).toBe('๊ณผ'); + }); + test('์„ ํƒ์˜ ๋ณด์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('์ƒดํ‘ธ', '์ด๋‚˜/๋‚˜')).toBe('๋‚˜'); + expect(get์กฐ์‚ฌ('์นซ์†”', '์ด๋‚˜/๋‚˜')).toBe('์ด๋‚˜'); + }); + test('ํ™”์ œ์˜ ๋ณด์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('์ƒดํ‘ธ', '์ด๋ž€/๋ž€')).toBe('๋ž€'); + expect(get์กฐ์‚ฌ('์นซ์†”', '์ด๋ž€/๋ž€')).toBe('์ด๋ž€'); + }); + test('ํ˜ธ๊ฒฉ์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('์ฒ ์ˆ˜', '์•„/์•ผ')).toBe('์•ผ'); + expect(get์กฐ์‚ฌ('๊ธธ๋™', '์•„/์•ผ')).toBe('์•„'); + }); + test('์ ‘์†์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('๊ณ ๊ธฐ', '์ด๋ž‘/๋ž‘')).toBe('๋ž‘'); + expect(get์กฐ์‚ฌ('๊ณผ์ผ', '์ด๋ž‘/๋ž‘')).toBe('์ด๋ž‘'); + }); + test('์„œ์ˆ ๊ฒฉ์กฐ์‚ฌ์™€ ์ข…๊ฒฐ์–ด๋ฏธ', () => { + expect(get์กฐ์‚ฌ('์‚ฌ๊ณผ', '์ด์—์š”/์˜ˆ์š”')).toBe('์˜ˆ์š”'); + expect(get์กฐ์‚ฌ('์ฑ…', '์ด์—์š”/์˜ˆ์š”')).toBe('์ด์—์š”'); + }); + test('์„œ์ˆ ๊ฒฉ์กฐ์‚ฌ์™€ ์ข…๊ฒฐ์–ด๋ฏธ, "์ด" ๋กœ ๋๋‚˜๋Š” ๋‹จ์–ด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(get์กฐ์‚ฌ('๋•Œ๋ฐ€์ด', '์ด์—์š”/์˜ˆ์š”')).toBe('์˜ˆ์š”'); + }); + test('์ง€์œ„๋‚˜ ์‹ ๋ถ„ ๋˜๋Š” ์ž๊ฒฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์œ„๊ฒฉ์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('ํ•™์ƒ', '์œผ๋กœ์„œ/๋กœ์„œ')).toBe('์œผ๋กœ์„œ'); + expect(get์กฐ์‚ฌ('๋ถ€๋ชจ', '์œผ๋กœ์„œ/๋กœ์„œ')).toBe('๋กœ์„œ'); + }); + test('์ง€์œ„๋‚˜ ์‹ ๋ถ„ ๋˜๋Š” ์ž๊ฒฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์œ„๊ฒฉ์กฐ์‚ฌ ใ„น ๋ฐ›์นจ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(get์กฐ์‚ฌ('๋ผ์ด๋ฒŒ', '์œผ๋กœ์„œ/๋กœ์„œ')).toBe('๋กœ์„œ'); + }); + test('์ˆ˜๋‹จ์˜ ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋„๊ตฌ๊ฒฉ์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('ํ† ํฐ', '์œผ๋กœ์จ/๋กœ์จ')).toBe('์œผ๋กœ์จ'); + expect(get์กฐ์‚ฌ('ํ•จ์ˆ˜', '์œผ๋กœ์จ/๋กœ์จ')).toBe('๋กœ์จ'); + }); + test('์ˆ˜๋‹จ์˜ ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋„๊ตฌ๊ฒฉ์กฐ์‚ฌ ใ„น ๋ฐ›์นจ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(get์กฐ์‚ฌ('๊ฑด๋ฌผ', '์œผ๋กœ์จ/๋กœ์จ')).toBe('๋กœ์จ'); + }); + test('์–ด๋–ค ํ–‰๋™์˜ ์ถœ๋ฐœ์ ์ด๋‚˜ ๋น„๋กฏ๋˜๋Š” ๋Œ€์ƒ์ž„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒฉ ์กฐ์‚ฌ', () => { + expect(get์กฐ์‚ฌ('์—ญ์‚ผ๋™', '์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ')).toBe('์œผ๋กœ๋ถ€ํ„ฐ'); + expect(get์กฐ์‚ฌ('์ €๊ธฐ', '์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ')).toBe('๋กœ๋ถ€ํ„ฐ'); + }); + test('์–ด๋–ค ํ–‰๋™์˜ ์ถœ๋ฐœ์ ์ด๋‚˜ ๋น„๋กฏ๋˜๋Š” ๋Œ€์ƒ์ž„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒฉ ์กฐ์‚ฌ ใ„น ๋ฐ›์นจ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ', () => { + expect(get์กฐ์‚ฌ('๋™๊ตด', '์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ')).toBe('๋กœ๋ถ€ํ„ฐ'); + }); +}); \ No newline at end of file diff --git a/src/josa.ts b/src/josa.ts new file mode 100644 index 0000000..9eb57a8 --- /dev/null +++ b/src/josa.ts @@ -0,0 +1,117 @@ +type Josa = + | '์ด/๊ฐ€' + | '์„/๋ฅผ' + | '์€/๋Š”' + | '์œผ๋กœ/๋กœ' + | '์™€/๊ณผ' + | '์ด๋‚˜/๋‚˜' + | '์ด๋ž€/๋ž€' + | '์•„/์•ผ' + | '์ด๋ž‘/๋ž‘' + | '์ด์—์š”/์˜ˆ์š”' + | '์œผ๋กœ์„œ/๋กœ์„œ' + | '์œผ๋กœ์จ/๋กœ์จ' + | '์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ' + | '์ด๋ผ/๋ผ'; + +const ๋กœjosa: Josa[] = ['์œผ๋กœ/๋กœ', '์œผ๋กœ์„œ/๋กœ์„œ', '์œผ๋กœ์จ/๋กœ์จ', '์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ']; + +export function has๋ฐ›์นจ(text: string) { + return (text.charCodeAt(text.length - 1) - '๊ฐ€'.charCodeAt(0)) % 28 > 0; +} + +export function get์ข…์„ฑ(text: string): string | null { + const unicode = text.charCodeAt(text.length - 1) - '๊ฐ€'.charCodeAt(0); + const ์ข…์„ฑ = unicode % 28; + return ์ข…์„ฑ > 0 ? String.fromCharCode(0x11a7 + ์ข…์„ฑ) : null; +} + +export function get์กฐ์‚ฌ(text: string, josa: Josa): string { + let [josa1, josa2] = josa.split('/'); + + if (text.length === 0) + return josa1; + + if (josa === '์™€/๊ณผ' || (has๋ฐ›์นจ(text) && ๋กœjosa.includes(josa) && get์ข…์„ฑ(text) === 'แ†ฏ')) + return has๋ฐ›์นจ(text) ? josa2 : josa1; + + if (josa === '์ด์—์š”/์˜ˆ์š”' && text[text.length - 1] === '์ด') + return josa2; + + return has๋ฐ›์นจ(text) ? josa1 : josa2; +} + +// TODO: ์กฐ์‚ฌ ๋’ค์— ๊ณต๋ฐฑ ์ž๋™ ์‚ฝ์ž…? +// console.log('๋‹ญ'.์ด๊ฐ€ + ' ๊ผฌ๊ผฌ๋Œ ์šธ๊ณ , ์˜ค๋ฆฌ'.๊ฐ€ + ' ๊ฝฅ๊ฝฅ ์šด๋‹ค.'); ์—ฌ๊ธฐ์„œ ๊ณต๋ฐฑ ๋•Œ๋ฌธ์— ์˜ˆ๋ป์ง€์ง€ ์•Š ใ…ํ—ค์Œ, ์–ด์ฐจํ”ผ ์กฐ์‚ฌ ๋’ค์— ๊ณต๋ฐฑ์€ ๋ฌด์กฐ๊ฑด ์˜ฌํ…๋ฐ + +export function apply์กฐ์‚ฌ(text: string, josa: Josa) { + if (text.length === 0) + return text; + + return text + get์กฐ์‚ฌ(text, josa); +} + +function add์กฐ์‚ฌMethod(josa: Josa) { + const [josa1, josa2] = josa.split('/'); + + const keys = [josa1, josa2]; + if (!josa1.includes(josa2)) + keys.push(josa1 + josa2); + + keys.forEach(key => Object.defineProperty(String.prototype, key, { + get() { return apply์กฐ์‚ฌ(this, josa); } + })); +} + +add์กฐ์‚ฌMethod('์ด/๊ฐ€'); +add์กฐ์‚ฌMethod('์„/๋ฅผ'); +add์กฐ์‚ฌMethod('์€/๋Š”'); +add์กฐ์‚ฌMethod('์œผ๋กœ/๋กœ'); +add์กฐ์‚ฌMethod('์™€/๊ณผ'); +add์กฐ์‚ฌMethod('์ด๋‚˜/๋‚˜'); +add์กฐ์‚ฌMethod('์ด๋ž€/๋ž€'); +add์กฐ์‚ฌMethod('์•„/์•ผ'); +add์กฐ์‚ฌMethod('์ด๋ž‘/๋ž‘'); +add์กฐ์‚ฌMethod('์ด์—์š”/์˜ˆ์š”'); +add์กฐ์‚ฌMethod('์œผ๋กœ์„œ/๋กœ์„œ'); +add์กฐ์‚ฌMethod('์œผ๋กœ์จ/๋กœ์จ'); +add์กฐ์‚ฌMethod('์œผ๋กœ๋ถ€ํ„ฐ/๋กœ๋ถ€ํ„ฐ'); +add์กฐ์‚ฌMethod('์ด๋ผ/๋ผ'); + +declare global { + interface String { + ์ด: string; + ๊ฐ€: string; + ์ด๊ฐ€: string; + ์„: string; + ๋ฅผ: string; + ์„๋ฅผ: string; + ์€: string; + ๋Š”: string; + ์€๋Š”: string; + ์œผ๋กœ: string; + ๋กœ: string; + ์™€: string; + ๊ณผ: string; + ์™€๊ณผ: string; + ์ด๋‚˜: string; + ๋‚˜: string; + ์ด๋ž€: string; + ๋ž€: string; + ์•„: string; + ์•ผ: string; + ์•„์•ผ: string; + ์ด๋ž‘: string; + ๋ž‘: string; + ์ด์—์š”: string; + ์˜ˆ์š”: string; + ์œผ๋กœ์„œ: string; + ๋กœ์„œ: string; + ์œผ๋กœ์จ: string; + ๋กœ์จ: string; + ์œผ๋กœ๋ถ€ํ„ฐ: string; + ๋กœ๋ถ€ํ„ฐ: string; + ์ด๋ผ: string; + ๋ผ: string; + } +} \ No newline at end of file diff --git a/tests/generate_hangul.ts b/tests/generate_hangul.ts new file mode 100644 index 0000000..a370f01 --- /dev/null +++ b/tests/generate_hangul.ts @@ -0,0 +1,11 @@ +function randomInt(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function makeAnyHangulText(): string { + const len = randomInt(1, 100); + return Array(len).fill(0).map(() => String.fromCharCode(randomInt('๊ฐ€'.charCodeAt(0), 'ํžฃ'.charCodeAt(0)))).join(''); +} + +const hangulTexts = Array(1000).fill(0).map(() => makeAnyHangulText()); +console.log(hangulTexts); diff --git a/tests/ishangul_bench.ts b/tests/ishangul_bench.ts new file mode 100644 index 0000000..95d1ca4 --- /dev/null +++ b/tests/ishangul_bench.ts @@ -0,0 +1,24 @@ +import { _isHangul, isHangul } from "../src/hangul"; + +function randomInt(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function makeAnyHangulText(): string { + const len = randomInt(1, 100); + return Array(len).fill(0).map(() => String.fromCharCode(randomInt('๊ฐ€'.charCodeAt(0), 'ํžฃ'.charCodeAt(0)))).join(''); +} + +const hangulTexts = Array(1000).fill(0).map(() => makeAnyHangulText()); + +console.time('isHangul'); +for (const text of hangulTexts) { + _isHangul(text); +} +console.timeEnd('isHangul'); // 5.654ms + +console.time('isHangul2'); +for (const text of hangulTexts) { + isHangul(text); +} +console.timeEnd('isHangul2'); // 0.612ms \ No newline at end of file