diff --git a/examples/percentage.ts b/examples/percentage.ts new file mode 100644 index 0000000..2246ff6 --- /dev/null +++ b/examples/percentage.ts @@ -0,0 +1,3 @@ +import { percentage } from "../src/index"; + +console.log(percentage(10, 100)); // 10 \ No newline at end of file diff --git a/examples/randomstring.ts b/examples/randomstring.ts index cbba693..7c500ae 100644 --- a/examples/randomstring.ts +++ b/examples/randomstring.ts @@ -1,4 +1,4 @@ -import { randomString } from "../src/index.ts"; +import { randomString } from "../src/index"; console.log(randomString(10)); // => (random 10-character string) \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index e5d6766..485bcbe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ -export { randomString } from './utils/randomstring.ts'; \ No newline at end of file +export { randomString } from './utils/randomstring'; +export { percentage } from './utils/percentage'; \ No newline at end of file diff --git a/src/utils/percentage.ts b/src/utils/percentage.ts new file mode 100644 index 0000000..d0a6d33 --- /dev/null +++ b/src/utils/percentage.ts @@ -0,0 +1,12 @@ +export function percentage(partial: number, total: number, allowNumNot100 = false) { + if (total === 0) { + throw new Error('Total cannot be 0'); + } + if (partial < 0 || total < 0) { + throw new Error('Partial and total must be non-negative'); + } + if (!allowNumNot100 && partial > total) { + return 100; + } + return (partial / total) * 100; +} \ No newline at end of file diff --git a/tests/percentage.test.ts b/tests/percentage.test.ts new file mode 100644 index 0000000..376274f --- /dev/null +++ b/tests/percentage.test.ts @@ -0,0 +1,30 @@ +// did I overenginner these tests? +import { percentage } from "../src/index"; +import { describe, it, expect } from 'vitest'; + +describe('percentage', () => { + it('should return 50% when 1 is half of 2', () => { + expect(percentage(1, 2)).toBe(50); + }); + it('should return 0% when 0 is half of 2', () => { + expect(percentage(0, 2)).toBe(0); + }); + it('should return 100% when 2 is half of 2', () => { + expect(percentage(2, 2)).toBe(100); + }); + it('should return 100% when 2 is half of 1', () => { + expect(percentage(2, 1)).toBe(100); + }); + it('should return 200% when 2 is half of 1 and allowNumNot100 is true', () => { + expect(percentage(2, 1, true)).toBe(200); + }) + it('should throw an error when total is 0', () => { + expect(() => percentage(1, 0)).toThrow(); + }); + it('should throw an error when partial is negative', () => { + expect(() => percentage(-1, 2)).toThrow(); + }); + it('should throw an error when total is negative', () => { + expect(() => percentage(1, -2)).toThrow(); + }); +}) \ No newline at end of file diff --git a/tests/randomString.test.ts b/tests/randomString.test.ts index 923bfd9..e29bea9 100644 --- a/tests/randomString.test.ts +++ b/tests/randomString.test.ts @@ -1,4 +1,4 @@ -import { randomString } from '../src/index.ts' +import { randomString } from '../src/index' import { describe, it, expect } from 'vitest' describe('randomString', () => { diff --git a/tsconfig.json b/tsconfig.json index e2f56d7..3691b84 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -35,7 +35,7 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + "allowImportingTsExtensions": false, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */