aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Hammond <[email protected]>2022-08-29 12:34:07 +0100
committerGitHub <[email protected]>2022-08-29 11:34:07 +0000
commit8fecd58b7cfd07826194e0de5d2c868c07c4d913 (patch)
tree8ce31e2baa185d3a6a53ce1e07b821ccc6b50116
parent7f8b8716ba69e24800e26d6c072c3076c01bfccf (diff)
downloadfaker-8fecd58b7cfd07826194e0de5d2c868c07c4d913.tar.xz
faker-8fecd58b7cfd07826194e0de5d2c868c07c4d913.zip
feat(system): add cron (#897)
-rw-r--r--src/modules/system/index.ts73
-rw-r--r--test/__snapshots__/system.spec.ts.snap36
-rw-r--r--test/system.spec.ts44
3 files changed, 153 insertions, 0 deletions
diff --git a/src/modules/system/index.ts b/src/modules/system/index.ts
index 46a12b19..6d2acca0 100644
--- a/src/modules/system/index.ts
+++ b/src/modules/system/index.ts
@@ -22,6 +22,16 @@ const commonInterfaceSchemas = {
pci: 'p',
} as const;
+const CRON_DAY_OF_WEEK = [
+ 'SUN',
+ 'MON',
+ 'TUE',
+ 'WED',
+ 'THU',
+ 'FRI',
+ 'SAT',
+] as const;
+
/**
* Generates fake data for many computer systems properties.
*/
@@ -264,4 +274,67 @@ export class System {
return `${prefix}${interfaceType}${commonInterfaceSchemas[interfaceSchema]}${suffix}`;
}
+
+ /**
+ * Returns a random cron expression.
+ *
+ * @param options The optional options to use.
+ * @param options.includeYear Whether to include a year in the generated expression. Defaults to `false`.
+ * @param options.includeNonStandard Whether to include a @yearly, @monthly, @daily, etc text labels in the generated expression. Defaults to `false`.
+ *
+ * @example
+ * faker.system.cron() // '45 23 * * 6'
+ * faker.system.cron({ includeYear: true }) // '45 23 * * 6 2067'
+ * faker.system.cron({ includeYear: false }) // '45 23 * * 6'
+ * faker.system.cron({ includeNonStandard: false }) // '45 23 * * 6'
+ * faker.system.cron({ includeNonStandard: true }) // '@yearly'
+ */
+ cron(
+ options: {
+ includeYear?: boolean;
+ includeNonStandard?: boolean;
+ } = {}
+ ): string {
+ const { includeYear = false, includeNonStandard = false } = options;
+
+ // create the arrays to hold the available values for each component of the expression
+ const minutes = [this.faker.datatype.number({ min: 0, max: 59 }), '*'];
+ const hours = [this.faker.datatype.number({ min: 0, max: 23 }), '*'];
+ const days = [this.faker.datatype.number({ min: 1, max: 31 }), '*', '?'];
+ const months = [this.faker.datatype.number({ min: 1, max: 12 }), '*'];
+ const daysOfWeek = [
+ this.faker.datatype.number({ min: 0, max: 6 }),
+ this.faker.helpers.arrayElement(CRON_DAY_OF_WEEK),
+ '*',
+ '?',
+ ];
+ const years = [this.faker.datatype.number({ min: 1970, max: 2099 }), '*'];
+
+ const minute = this.faker.helpers.arrayElement(minutes);
+ const hour = this.faker.helpers.arrayElement(hours);
+ const day = this.faker.helpers.arrayElement(days);
+ const month = this.faker.helpers.arrayElement(months);
+ const dayOfWeek = this.faker.helpers.arrayElement(daysOfWeek);
+ const year = this.faker.helpers.arrayElement(years);
+
+ // create and return the cron expression string
+ let standardExpression = `${minute} ${hour} ${day} ${month} ${dayOfWeek}`;
+ if (includeYear) {
+ standardExpression += ` ${year}`;
+ }
+
+ const nonStandardExpressions = [
+ '@annually',
+ '@daily',
+ '@hourly',
+ '@monthly',
+ '@reboot',
+ '@weekly',
+ '@yearly',
+ ];
+
+ return !includeNonStandard || this.faker.datatype.boolean()
+ ? standardExpression
+ : this.faker.helpers.arrayElement(nonStandardExpressions);
+ }
}
diff --git a/test/__snapshots__/system.spec.ts.snap b/test/__snapshots__/system.spec.ts.snap
index 3cbabb8f..ef22470d 100644
--- a/test/__snapshots__/system.spec.ts.snap
+++ b/test/__snapshots__/system.spec.ts.snap
@@ -8,6 +8,16 @@ exports[`system > 42 > commonFileName > with extension 1`] = `"lavender_shoes.ex
exports[`system > 42 > commonFileType 1`] = `"audio"`;
+exports[`system > 42 > cron > noArgs 1`] = `"* 19 * 3 5"`;
+
+exports[`system > 42 > cron > with includeNonStandard false 1`] = `"* 19 * 3 5"`;
+
+exports[`system > 42 > cron > with includeNonStandard true 1`] = `"@yearly"`;
+
+exports[`system > 42 > cron > with includeYear false 1`] = `"* 19 * 3 5"`;
+
+exports[`system > 42 > cron > with includeYear true 1`] = `"* 19 * 3 5 2047"`;
+
exports[`system > 42 > directoryPath 1`] = `"/opt/bin"`;
exports[`system > 42 > fileExt > noArgs 1`] = `"lrm"`;
@@ -76,6 +86,16 @@ exports[`system > 1211 > commonFileName > with extension 1`] = `"invoice_cyclocr
exports[`system > 1211 > commonFileType 1`] = `"application"`;
+exports[`system > 1211 > cron > noArgs 1`] = `"55 * 28 * 1"`;
+
+exports[`system > 1211 > cron > with includeNonStandard false 1`] = `"55 * 28 * 1"`;
+
+exports[`system > 1211 > cron > with includeNonStandard true 1`] = `"@hourly"`;
+
+exports[`system > 1211 > cron > with includeYear false 1`] = `"55 * 28 * 1"`;
+
+exports[`system > 1211 > cron > with includeYear true 1`] = `"55 * 28 * 1 *"`;
+
exports[`system > 1211 > directoryPath 1`] = `"/var/log"`;
exports[`system > 1211 > fileExt > noArgs 1`] = `"dic"`;
@@ -144,6 +164,16 @@ exports[`system > 1337 > commonFileName > with extension 1`] = `"nesciunt.ext"`;
exports[`system > 1337 > commonFileType 1`] = `"audio"`;
+exports[`system > 1337 > cron > noArgs 1`] = `"15 13 5 * *"`;
+
+exports[`system > 1337 > cron > with includeNonStandard false 1`] = `"15 13 5 * *"`;
+
+exports[`system > 1337 > cron > with includeNonStandard true 1`] = `"@yearly"`;
+
+exports[`system > 1337 > cron > with includeYear false 1`] = `"15 13 5 * *"`;
+
+exports[`system > 1337 > cron > with includeYear true 1`] = `"15 13 5 * * 2029"`;
+
exports[`system > 1337 > directoryPath 1`] = `"/Library"`;
exports[`system > 1337 > fileExt > noArgs 1`] = `"oa3"`;
@@ -210,6 +240,8 @@ exports[`system > seed: 42 > commonFileName() 1`] = `"lavender_shoes.mpe"`;
exports[`system > seed: 42 > commonFileType() 1`] = `"audio"`;
+exports[`system > seed: 42 > cron() 1`] = `"* 19 * 3 5"`;
+
exports[`system > seed: 42 > directoryPath() 1`] = `"/opt/bin"`;
exports[`system > seed: 42 > fileExt() 1`] = `"lrm"`;
@@ -232,6 +264,8 @@ exports[`system > seed: 1211 > commonFileName() 1`] = `"invoice_cyclocross_assau
exports[`system > seed: 1211 > commonFileType() 1`] = `"application"`;
+exports[`system > seed: 1211 > cron() 1`] = `"55 * 28 * 1"`;
+
exports[`system > seed: 1211 > directoryPath() 1`] = `"/var/log"`;
exports[`system > seed: 1211 > fileExt() 1`] = `"dic"`;
@@ -254,6 +288,8 @@ exports[`system > seed: 1337 > commonFileName() 1`] = `"nesciunt.mp2"`;
exports[`system > seed: 1337 > commonFileType() 1`] = `"audio"`;
+exports[`system > seed: 1337 > cron() 1`] = `"15 13 5 * *"`;
+
exports[`system > seed: 1337 > directoryPath() 1`] = `"/Library"`;
exports[`system > seed: 1337 > fileExt() 1`] = `"oa3"`;
diff --git a/test/system.spec.ts b/test/system.spec.ts
index 05e2c53d..fb0ef209 100644
--- a/test/system.spec.ts
+++ b/test/system.spec.ts
@@ -10,6 +10,7 @@ const functionNames = [
'commonFileExt',
'commonFileName',
'commonFileType',
+ 'cron',
'directoryPath',
'fileExt',
'fileName',
@@ -65,6 +66,14 @@ describe('system', () => {
}
}
});
+
+ t.describe('cron', (t) => {
+ t.it('noArgs')
+ .it('with includeYear true', { includeYear: true })
+ .it('with includeYear false', { includeYear: false })
+ .it('with includeNonStandard true', { includeNonStandard: true })
+ .it('with includeNonStandard false', { includeNonStandard: false });
+ });
});
for (const seed of seededRuns) {
@@ -385,6 +394,41 @@ describe('system', () => {
).toMatch(/^enx[a-f\d]{12}$/);
});
});
+
+ describe('cron()', () => {
+ const regex =
+ /^([1-9]|[1-5]\d|\*) ([0-9]|1\d|2[0-3]|\*) ([1-9]|[12]\d|3[01]|\*|\?) ([1-9]|1[0-2]|\*) ([0-6]|\*|\?|[A-Z]{3}) ((19[7-9]d)|20\d{2}|\*)?/;
+
+ const regexElements = regex.toString().replace(/\//g, '').split(' ');
+
+ it.each([
+ [{}, 5],
+ [{ includeYear: false }, 5],
+ [{ includeYear: true }, 6],
+ ])(
+ 'should return cron expression with correct number of valid elements - %o, %d',
+ (options, count: number) => {
+ const cron = faker.system.cron(options).split(' ');
+ expect(cron).toHaveLength(count);
+ cron.forEach((cronElement, i) =>
+ expect(
+ cronElement,
+ `generated cron, ${cronElement} should match regex ${regexElements[i]}`
+ ).toMatch(new RegExp(regexElements[i]))
+ );
+ }
+ );
+
+ it('should return non-standard cron expressions', () => {
+ const validResults = ['1', '2', '5', '*', '@'];
+ expect(
+ faker.system.cron({ includeNonStandard: true })[0],
+ 'generated cron, string should contain non-standard cron labels'
+ ).toSatisfy(
+ (value) => !!validResults.find((result) => value === result)
+ );
+ });
+ });
}
});