From 9647623a46e06bfc4c4368389a2aa8017f947292 Mon Sep 17 00:00:00 2001 From: Thomas Phillips Date: Tue, 10 Oct 2023 17:31:12 +1300 Subject: [PATCH] feat(internet): Add RFC 5737 testing IPv4 support --- src/modules/internet/index.ts | 26 ++++++++++ .../__snapshots__/internet.spec.ts.snap | 18 +++++++ test/modules/internet.spec.ts | 52 +++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/src/modules/internet/index.ts b/src/modules/internet/index.ts index 6e8f822f22f..7d32db50bab 100644 --- a/src/modules/internet/index.ts +++ b/src/modules/internet/index.ts @@ -1000,6 +1000,32 @@ export class InternetModule { ); } + /** + * Generates a random testing-safe IPv4 address according to RFC 5737. + * + * @param options Optional options object. + * @param options.range The test-net range to use. Defaults to 1. + * + * @example + * faker.internet.ipv4Testing() // '192.0.2.34' + * + * @since 8.1.1 + */ + ipv4Testing( + options: { + /** + * Which TEST-NET range to use + * + * @default 1 (192.0.2.X) + */ + range?: 1 | 2 | 3; + } = {} + ): string { + const { range = 1 } = options; + const ranges = ['192.0.2', '198.51.100', '203.0.113']; + return `${ranges[range - 1]}.${this.faker.number.int(255)}`; + } + /** * Generates a random IPv6 address. * diff --git a/test/modules/__snapshots__/internet.spec.ts.snap b/test/modules/__snapshots__/internet.spec.ts.snap index c8c6d8bbc36..5127ad6c780 100644 --- a/test/modules/__snapshots__/internet.spec.ts.snap +++ b/test/modules/__snapshots__/internet.spec.ts.snap @@ -84,6 +84,12 @@ exports[`internet > 42 > ip 1`] = `"203.243.46.187"`; exports[`internet > 42 > ipv4 1`] = `"95.203.243.46"`; +exports[`internet > 42 > ipv4Testing > noArgs 1`] = `"192.0.2.95"`; + +exports[`internet > 42 > ipv4Testing > with test-net range 2 1`] = `"198.51.100.95"`; + +exports[`internet > 42 > ipv4Testing > with test-net range 3 1`] = `"203.0.113.95"`; + exports[`internet > 42 > ipv6 1`] = `"8be4:abdd:3932:1ad7:d3fe:01ff:ce40:4f4d"`; exports[`internet > 42 > mac > noArgs 1`] = `"5c:f2:bc:99:27:21"`; @@ -226,6 +232,12 @@ exports[`internet > 1211 > ip 1`] = `"adb4:2f0e:3f4a:973f:ab0a:eefc:e96d:fcf4"`; exports[`internet > 1211 > ipv4 1`] = `"237.117.228.199"`; +exports[`internet > 1211 > ipv4Testing > noArgs 1`] = `"192.0.2.237"`; + +exports[`internet > 1211 > ipv4Testing > with test-net range 2 1`] = `"198.51.100.237"`; + +exports[`internet > 1211 > ipv4Testing > with test-net range 3 1`] = `"203.0.113.237"`; + exports[`internet > 1211 > ipv6 1`] = `"eadb:42f0:e3f4:a973:fab0:aeef:ce96:dfcf"`; exports[`internet > 1211 > mac > noArgs 1`] = `"e7:ec:32:f0:a2:a3"`; @@ -368,6 +380,12 @@ exports[`internet > 1337 > ip 1`] = `"143.40.54.71"`; exports[`internet > 1337 > ipv4 1`] = `"67.143.40.54"`; +exports[`internet > 1337 > ipv4Testing > noArgs 1`] = `"192.0.2.67"`; + +exports[`internet > 1337 > ipv4Testing > with test-net range 2 1`] = `"198.51.100.67"`; + +exports[`internet > 1337 > ipv4Testing > with test-net range 3 1`] = `"203.0.113.67"`; + exports[`internet > 1337 > ipv6 1`] = `"5c34:6ba0:75bd:57f5:a62b:82d7:2af3:9cbb"`; exports[`internet > 1337 > mac > noArgs 1`] = `"48:23:48:70:53:89"`; diff --git a/test/modules/internet.spec.ts b/test/modules/internet.spec.ts index 79d329de3ea..e1dfa37eabe 100644 --- a/test/modules/internet.spec.ts +++ b/test/modules/internet.spec.ts @@ -154,6 +154,12 @@ describe('internet', () => { protocol: 'http', }); }); + + t.describe('ipv4Testing', (t) => { + t.it('noArgs') + .it('with test-net range 2', { range: 2 }) + .it('with test-net range 3', { range: 3 }); + }); }); describe.each(times(NON_SEEDED_BASED_RUN).map(() => faker.seed()))( @@ -616,6 +622,52 @@ describe('internet', () => { }); }); + describe('ipv4Testing()', () => { + it('should return a random testing-safe IPv4 with four parts', () => { + const ip = faker.internet.ipv4Testing(); + + expect(ip).toBeTruthy(); + expect(ip).toBeTypeOf('string'); + expect(ip).toSatisfy((value: string) => validator.isIP(value, 4)); + + const parts = ip.split('.'); + + expect(parts).toHaveLength(4); + expect(parts.slice(0, 3).join('.')).toBe('192.0.2'); + expect(parts[3]).toMatch(/^\d+$/); + expect(+parts[3]).toBeGreaterThanOrEqual(0); + expect(+parts[3]).toBeLessThanOrEqual(255); + }); + it('should return a random testing-safe IPv4 with four parts, from test-net range 2', () => { + const ip = faker.internet.ipv4Testing({ range: 2 }); + + expect(ip).toBeTruthy(); + expect(ip).toBeTypeOf('string'); + expect(ip).toSatisfy((value: string) => validator.isIP(value, 4)); + + const parts = ip.split('.'); + + expect(parts.slice(0, 3).join('.')).toBe('198.51.100'); + expect(parts[3]).toMatch(/^\d+$/); + expect(+parts[3]).toBeGreaterThanOrEqual(0); + expect(+parts[3]).toBeLessThanOrEqual(255); + }); + it('should return a random testing-safe IPv4 with four parts, from test-net range 3', () => { + const ip = faker.internet.ipv4Testing({ range: 3 }); + + expect(ip).toBeTruthy(); + expect(ip).toBeTypeOf('string'); + expect(ip).toSatisfy((value: string) => validator.isIP(value, 4)); + + const parts = ip.split('.'); + + expect(parts.slice(0, 3).join('.')).toBe('203.0.113'); + expect(parts[3]).toMatch(/^\d+$/); + expect(+parts[3]).toBeGreaterThanOrEqual(0); + expect(+parts[3]).toBeLessThanOrEqual(255); + }); + }); + describe('ipv6()', () => { it('should return a random IPv6 address with eight parts', () => { const ipv6 = faker.internet.ipv6();