-
Notifications
You must be signed in to change notification settings - Fork 0
Add range() & getRandomString(), and improve quality for getRandomInt() (formaly random())
#66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e2f76c5
efd7fd0
8eebd5f
ea6df37
064422b
1aed875
6f72b7f
b9c93f3
91e2493
5e1c646
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { ok } from "node:assert"; | ||
| import { describe, expect, test } from "vitest"; | ||
| import { pseudoRandomInt } from "./pseudo-random-int.ts"; | ||
|
|
||
| describe("pseudoRandomInt()", () => { | ||
| test("returns a number within valid range", () => { | ||
| const generatedNumber = pseudoRandomInt(100); | ||
|
|
||
| expect(generatedNumber).toBeLessThanOrEqual(100); | ||
| expect(generatedNumber).toBeGreaterThanOrEqual(0); | ||
| expect(typeof generatedNumber).toBe("number"); | ||
| }); | ||
|
|
||
| test("returns an integer (no decimals)", () => { | ||
| const generatedNumber = pseudoRandomInt(100); | ||
| ok(Number.isInteger(generatedNumber)); | ||
| }); | ||
|
|
||
| test("handles max value of 0 (returns 0)", () => { | ||
| const generatedNumber = pseudoRandomInt(0); | ||
| expect(generatedNumber).toBe(0); | ||
| }); | ||
|
|
||
| test("returns 0 or 1 for max value of 1", () => { | ||
| const generatedNumber = pseudoRandomInt(1); | ||
| expect([ 0, 1 ]).toContain(generatedNumber); | ||
| }); | ||
|
|
||
| test("returns values in expected range for small max", () => { | ||
| const max = 10; | ||
| const results = new Set<number>(); | ||
|
|
||
| // Generate multiple random numbers to test distribution | ||
| for (let i = 0; i < 100; i++) { | ||
| const generatedNumber = pseudoRandomInt(max); | ||
| results.add(generatedNumber); | ||
| expect(generatedNumber).toBeGreaterThanOrEqual(0); | ||
| expect(generatedNumber).toBeLessThanOrEqual(max); | ||
| expect(Number.isInteger(generatedNumber)).toBe(true); | ||
| } | ||
|
|
||
| // Should generate at least some variety in 100 attempts | ||
| expect(results.size).toBeGreaterThan(1); | ||
| }); | ||
|
|
||
| test("returns values in expected range for large max", () => { | ||
| const max = 1000000; | ||
|
|
||
| for (let i = 0; i < 100; i++) { | ||
| const generatedNumber = pseudoRandomInt(max); | ||
| expect(generatedNumber).toBeGreaterThanOrEqual(0); | ||
| expect(generatedNumber).toBeLessThanOrEqual(max); | ||
| expect(Number.isInteger(generatedNumber)).toBe(true); | ||
| } | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||||||
| /** | ||||||||||
| * Generates pseudo-random non-negative integer number. | ||||||||||
| * Don't use this function for security purpose. (e.g., generating password) | ||||||||||
| * @param max - max number of the generated random number | ||||||||||
|
phanect marked this conversation as resolved.
|
||||||||||
| * @returns pseudo-random non-negative integer number | ||||||||||
| */ | ||||||||||
| export const pseudoRandomInt = (max: number): number => { | ||||||||||
| if (!Number.isFinite(max) || max < 0) { | ||||||||||
| throw new RangeError("max must be a finite, non-negative number"); | ||||||||||
|
Comment on lines
+8
to
+9
|
||||||||||
| if (!Number.isFinite(max) || max < 0) { | |
| throw new RangeError("max must be a finite, non-negative number"); | |
| if (!Number.isFinite(max) || !Number.isInteger(max) || max < 0) { | |
| throw new RangeError("max must be a finite, non-negative integer number"); |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test coverage for the validation logic. The function throws a RangeError when max is negative or not finite, but there are no tests verifying this behavior. Add tests for these edge cases, such as passing negative numbers, NaN, or Infinity.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| export const chars = [ | ||
| "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", | ||
| "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", | ||
| "U", "V", "W", "X", "Y", "Z", | ||
| "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", | ||
| "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", | ||
| "u", "v", "w", "x", "y", "z", | ||
| "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", | ||
| ] as const; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| import { describe, expect, test } from "vitest"; | ||
| import { pseudoRandomInt } from "./pseudo-random-int.ts"; | ||
| import { pseudoRandomString } from "./pseudo-random-string.ts"; | ||
|
|
||
| describe("pseudoRandomString()", () => { | ||
| test("returns a string with the correct length", () => { | ||
| const generatedString = pseudoRandomString(10); | ||
|
|
||
| expect(generatedString).toHaveLength(10); | ||
| expect(typeof generatedString).toBe("string"); | ||
| }); | ||
|
|
||
| test("returns different strings on multiple calls", () => { | ||
| const generatedString1 = pseudoRandomString(20); | ||
| const generatedString2 = pseudoRandomString(20); | ||
| const generatedString3 = pseudoRandomString(20); | ||
|
|
||
| expect(generatedString1).not.toBe(generatedString2); | ||
| expect(generatedString2).not.toBe(generatedString3); | ||
| expect(generatedString1).not.toBe(generatedString3); | ||
| }); | ||
|
|
||
| test("throws an Error when length is 0", () => | ||
| expect(() => pseudoRandomString(0)).toThrowError() | ||
| ); | ||
|
|
||
| test("throws an Error when length is a negative number", () => | ||
| expect(() => pseudoRandomString(-4)).toThrowError() | ||
| ); | ||
|
|
||
| test("generates string with only valid characters (alphanumeric)", () => { | ||
| const generatedString = pseudoRandomString(100); | ||
| expect(generatedString).toMatch(/^[A-Za-z0-9]+$/); | ||
| }); | ||
|
|
||
| test("works with different length values", () => { | ||
| for (const length of Array.from({ length: 5 }, () => pseudoRandomInt(500) + 1)) { | ||
| const generatedString = pseudoRandomString(length); | ||
| expect(generatedString).toHaveLength(length); | ||
| expect(typeof generatedString).toBe("string"); | ||
| } | ||
| }); | ||
|
|
||
| test("generates strings with good distribution of characters", () => { | ||
| // Generate a long string and check that multiple different characters appear | ||
| const generatedString = pseudoRandomString(1000); | ||
| const uniqueChars = new Set(generatedString.split("")); | ||
|
|
||
| // With 1000 characters, we should see a good variety | ||
| // (at least 40 different characters out of 62 possible) | ||
| expect(uniqueChars.size).toBeGreaterThan(40); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import { pseudoRandomInt } from "./pseudo-random-int.ts"; | ||
| import { chars } from "./pseudo-random-string-chars.ts"; | ||
|
|
||
| /** | ||
| * Generates pseudo-random string. | ||
| * Don't use this function for security purpose. (e.g., generating password) | ||
| * @param length - length of the generated string | ||
| * @returns pseudo-random string | ||
| */ | ||
| export const pseudoRandomString = (length: number): string => { | ||
| if (!Number.isInteger(length) || length <= 0) { | ||
| throw new Error(`\`length\` must be a natural number, but \`${ length }\` is given.`); | ||
|
phanect marked this conversation as resolved.
Comment on lines
+11
to
+12
|
||
| } | ||
|
|
||
| return Array.from({ length }, () => { | ||
| const index = pseudoRandomInt(chars.length - 1); | ||
| return chars[index]; | ||
| }).join(""); | ||
| }; | ||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.