Skip to content
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

feat(number): add romanNumeral method #3070

Merged
merged 18 commits into from
Oct 31, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Wrote tests for roman numeral function
  • Loading branch information
AmaanRS committed Aug 30, 2024
commit f0dc31c164b3747b18002642a5699ad8849e99c7
27 changes: 11 additions & 16 deletions src/modules/number/index.ts
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@
* @param options.max Upper bound for generated roman numerals. Defaults to `3999`.
*
* @throws When `min` is greater than `max`.
* @throws When `min`,`max` is not a number.
* @throws When `min`, `max` is not a number.
* @throws When `min` is less than `1`.
* @throws When `max` is greater than `3999`.
*
@@ -470,22 +470,23 @@
const DEFAULT_MIN = 1;
const DEFAULT_MAX = 3999;

let num;
let result = '';

if (typeof options === 'number') {
options = {
max: options,
};
}

let num = DEFAULT_MIN;

const min = Number(options.min ?? DEFAULT_MIN);
const max = Number(options.max ?? DEFAULT_MAX);

if (typeof min !== 'number' || isNaN(min)) {

Check failure on line 485 in src/modules/number/index.ts

GitHub Actions / Lint: node-22, ubuntu-latest

Prefer `Number.isNaN` over `isNaN`
throw new FakerError('Min value must be a valid number.');
}

if (typeof max !== 'number' || isNaN(max)) {

Check failure on line 489 in src/modules/number/index.ts

GitHub Actions / Lint: node-22, ubuntu-latest

Prefer `Number.isNaN` over `isNaN`
throw new FakerError('Max value must be a valid number.');
}

@@ -494,20 +495,16 @@
}

if (max > DEFAULT_MAX) {
throw new FakerError(`Max value ${max} should be 4999 or lesser.`);
throw new FakerError(`Max value ${max} should be 3999 or lesser.`);
}

if (max < min) {
throw new FakerError(`Max ${max} should be larger then min ${min}.`);
}

if (max === min) {
num = min;
} else {
num = this.int({ min, max });
}
num = this.int({ min, max });

const lookup: [string, number][] = [

Check failure on line 507 in src/modules/number/index.ts

GitHub Actions / Lint: node-22, ubuntu-latest

Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead
['M', 1000],
['CM', 900],
['D', 500],
@@ -523,13 +520,11 @@
['I', 1],
];

const intToRomanNumeral = (num: number): string =>
lookup.reduce((acc: string, [k, v]: [string, number]) => {
acc += k.repeat(Math.floor(num / v));
num = num % v;
return acc;
}, '');
for (const [k, v] of lookup) {
result += k.repeat(Math.floor(num / v));
num = num % v;
}

return intToRomanNumeral(num);
return result;
}
}
42 changes: 42 additions & 0 deletions test/modules/__snapshots__/number.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -50,6 +50,20 @@ exports[`number > 42 > octal > with options 1`] = `"4"`;

exports[`number > 42 > octal > with value 1`] = `"0"`;

exports[`number > 42 > romanNumeral > noArgs 1`] = `"MCDXCVIII"`;

exports[`number > 42 > romanNumeral > with max as 3999 1`] = `"MCDXCVIII"`;

exports[`number > 42 > romanNumeral > with min and max 1`] = `"CCL"`;

exports[`number > 42 > romanNumeral > with min as 1 1`] = `"MCDXCVIII"`;

exports[`number > 42 > romanNumeral > with number value 1`] = `"CCCLXXV"`;

exports[`number > 42 > romanNumeral > with only max 1`] = `"LXII"`;

exports[`number > 42 > romanNumeral > with only min 1`] = `"MDI"`;

exports[`number > 1211 > bigInt > noArgs 1`] = `982966736876848n`;

exports[`number > 1211 > bigInt > with big options 1`] = `25442250580110979794946298n`;
@@ -100,6 +114,20 @@ exports[`number > 1211 > octal > with options 1`] = `"12"`;

exports[`number > 1211 > octal > with value 1`] = `"1"`;

exports[`number > 1211 > romanNumeral > noArgs 1`] = `"MMMDCCXIV"`;

exports[`number > 1211 > romanNumeral > with max as 3999 1`] = `"MMMDCCXIV"`;

exports[`number > 1211 > romanNumeral > with min and max 1`] = `"CDLXXIV"`;

exports[`number > 1211 > romanNumeral > with min as 1 1`] = `"MMMDCCXIV"`;

exports[`number > 1211 > romanNumeral > with number value 1`] = `"CMXXIX"`;

exports[`number > 1211 > romanNumeral > with only max 1`] = `"CLIV"`;

exports[`number > 1211 > romanNumeral > with only min 1`] = `"MMMDCCXIV"`;

exports[`number > 1337 > bigInt > noArgs 1`] = `212435297136194n`;

exports[`number > 1337 > bigInt > with big options 1`] = `27379244885156992800029992n`;
@@ -149,3 +177,17 @@ exports[`number > 1337 > octal > noArgs 1`] = `"2"`;
exports[`number > 1337 > octal > with options 1`] = `"2"`;

exports[`number > 1337 > octal > with value 1`] = `"0"`;

exports[`number > 1337 > romanNumeral > noArgs 1`] = `"MXLVIII"`;

exports[`number > 1337 > romanNumeral > with max as 3999 1`] = `"MXLVIII"`;

exports[`number > 1337 > romanNumeral > with min and max 1`] = `"CCV"`;

exports[`number > 1337 > romanNumeral > with min as 1 1`] = `"MXLVIII"`;

exports[`number > 1337 > romanNumeral > with number value 1`] = `"CCLXIII"`;

exports[`number > 1337 > romanNumeral > with only max 1`] = `"XLIV"`;

exports[`number > 1337 > romanNumeral > with only min 1`] = `"MLI"`;
84 changes: 84 additions & 0 deletions test/modules/number.spec.ts
Original file line number Diff line number Diff line change
@@ -47,6 +47,16 @@
max: 32465761264574654845432354n,
});
});

t.describe('romanNumeral', (t) => {
t.it('noArgs')
.it('with number value', 1000)
.it('with only min', { min: 5 })
.it('with only max', { max: 165 })
.it('with min as 1', { min: 1 })
.it('with max as 3999', { max: 3999 })
.it('with min and max', { min: 100, max: 502 });
});
});

describe(`random seeded tests for seed ${faker.seed()}`, () => {
@@ -625,6 +635,80 @@
);
});
});

describe('romanNumeral', () => {
it('should generate a Roman numeral within default range', () => {
const roman = faker.number.romanNumeral();
expect(roman).toBeTypeOf('string');
expect(roman).toMatch(/^[IVXLCDM]+$/);
});

it('should generate a Roman numeral with max value of 1000', () => {
const roman = faker.number.romanNumeral(1000);
expect(roman).toMatch(/^[IVXLCDM]+$/);
});

it('should generate a Roman numeral between 1 and 10', () => {
const values = {
1: 'I',
2: 'II',
3: 'III',
4: 'IV',
5: 'V',
6: 'VI',
7: 'VII',
8: 'VIII',
9: 'IX',
10: 'X',
};

const roman = faker.number.romanNumeral({ min: 1, max: 10 });

expect(Object.values(values)).toContain(roman);
});

it('should throw when min is not a number', () => {
expect(() => {
faker.number.romanNumeral({ min: '2q' as any });

Check failure on line 672 in test/modules/number.spec.ts

GitHub Actions / Lint: node-22, ubuntu-latest

Unexpected any. Specify a different type
}).toThrow(new FakerError('Min value must be a valid number.'));
});

it('should throw when min is NaN', () => {
expect(() => {
faker.number.romanNumeral({ min: NaN });

Check failure on line 678 in test/modules/number.spec.ts

GitHub Actions / Lint: node-22, ubuntu-latest

Prefer `Number.NaN` over `NaN`
}).toThrow(new FakerError('Min value must be a valid number.'));
});

it('should throw when max is not a number', () => {
expect(() => {
faker.number.romanNumeral({ max: '2q' as any });

Check failure on line 684 in test/modules/number.spec.ts

GitHub Actions / Lint: node-22, ubuntu-latest

Unexpected any. Specify a different type
}).toThrow(new FakerError('Max value must be a valid number.'));
});

it('should throw when max is NaN', () => {
expect(() => {
faker.number.romanNumeral({ max: NaN });

Check failure on line 690 in test/modules/number.spec.ts

GitHub Actions / Lint: node-22, ubuntu-latest

Prefer `Number.NaN` over `NaN`
}).toThrow(new FakerError('Max value must be a valid number.'));
});

it('should throw when min value is less than 1', () => {
expect(() => {
faker.number.romanNumeral({ min: 0 });
}).toThrow(new FakerError('Min value 0 should be 1 or greater.'));
});

it('should throw when max value is greater than 3999', () => {
expect(() => {
faker.number.romanNumeral({ max: 4000 });
}).toThrow(new FakerError('Max value 4000 should be 3999 or lesser.'));
});

it('should throw when max value is less than min value', () => {
expect(() => {
faker.number.romanNumeral({ min: 500, max: 100 });
}).toThrow(new FakerError('Max 100 should be larger then min 500.'));
});
});
});

describe('value range tests', () => {
Loading
Oops, something went wrong.