aboutsummaryrefslogtreecommitdiff
path: root/test/modules
diff options
context:
space:
mode:
Diffstat (limited to 'test/modules')
-rw-r--r--test/modules/__snapshots__/person.spec.ts.snap2
-rw-r--r--test/modules/helpers-eval.spec.ts162
-rw-r--r--test/modules/helpers.spec.ts37
3 files changed, 182 insertions, 19 deletions
diff --git a/test/modules/__snapshots__/person.spec.ts.snap b/test/modules/__snapshots__/person.spec.ts.snap
index 6f3e0963..a85f4ccb 100644
--- a/test/modules/__snapshots__/person.spec.ts.snap
+++ b/test/modules/__snapshots__/person.spec.ts.snap
@@ -50,7 +50,7 @@ exports[`person > 42 > suffix > with sex 1`] = `"III"`;
exports[`person > 42 > zodiacSign 1`] = `"Gemini"`;
-exports[`person > 1211 > bio 1`] = `"infrastructure supporter, photographer 🙆‍♀️"`;
+exports[`person > 1211 > bio 1`] = `"teletype lover, dreamer 👄"`;
exports[`person > 1211 > firstName > noArgs 1`] = `"Tito"`;
diff --git a/test/modules/helpers-eval.spec.ts b/test/modules/helpers-eval.spec.ts
new file mode 100644
index 00000000..40612c37
--- /dev/null
+++ b/test/modules/helpers-eval.spec.ts
@@ -0,0 +1,162 @@
+import { describe, expect, it, vi } from 'vitest';
+import { faker, FakerError } from '../../src';
+import { fakeEval } from '../../src/modules/helpers/eval';
+
+describe('fakeEval()', () => {
+ it('does not allow empty string input', () => {
+ expect(() => fakeEval('', faker)).toThrowError(
+ new FakerError('Eval expression cannot be empty.')
+ );
+ });
+
+ it('does not allow empty entrypoints', () => {
+ expect(() => fakeEval('foobar', faker, [])).toThrowError(
+ new FakerError('Eval entrypoints cannot be empty.')
+ );
+ });
+
+ it('supports single pattern part invocations', () => {
+ const actual = fakeEval('string', faker);
+ expect(actual).toBeTypeOf('object');
+ expect(actual).toBe(faker.string);
+ });
+
+ it('supports simple method calls', () => {
+ const spy = vi.spyOn(faker.string, 'numeric');
+ const actual = fakeEval('string.numeric', faker);
+ expect(spy).toHaveBeenCalledWith();
+ expect(actual).toBeTypeOf('string');
+ expect(actual).toMatch(/^\d$/);
+ });
+
+ it('supports method calls without arguments', () => {
+ const spy = vi.spyOn(faker.string, 'numeric');
+ const actual = fakeEval('string.numeric()', faker);
+ expect(spy).toHaveBeenCalledWith();
+ expect(actual).toBeTypeOf('string');
+ expect(actual).toMatch(/^\d$/);
+ });
+
+ it('supports method calls with simple arguments', () => {
+ const spy = vi.spyOn(faker.string, 'numeric');
+ const actual = fakeEval('string.numeric(5)', faker);
+ expect(spy).toHaveBeenCalledWith(5);
+ expect(actual).toBeTypeOf('string');
+ expect(actual).toMatch(/^\d{5}$/);
+ });
+
+ it('supports method calls with complex arguments', () => {
+ const spy = vi.spyOn(faker.string, 'numeric');
+ const actual = fakeEval(
+ 'string.numeric({ "length": 5, "allowLeadingZeros": true, "exclude": ["5"] })',
+ faker
+ );
+ expect(spy).toHaveBeenCalledWith({
+ length: 5,
+ allowLeadingZeros: true,
+ exclude: ['5'],
+ });
+ expect(actual).toBeTypeOf('string');
+ expect(actual).toMatch(/^[0-46-9]{5}$/);
+ });
+
+ it('supports method calls with multiple arguments', () => {
+ const spy = vi.spyOn(faker.helpers, 'mustache');
+ const actual = fakeEval(
+ 'helpers.mustache("{{foo}}", { "foo": "bar" })',
+ faker
+ );
+ expect(spy).toHaveBeenCalledWith('{{foo}}', { foo: 'bar' });
+ expect(actual).toBeTypeOf('string');
+ expect(actual).toBe('bar');
+ });
+
+ it('supports method calls with unquoted string argument', () => {
+ const spy = vi.spyOn(faker.helpers, 'slugify');
+ const actual = fakeEval('helpers.slugify(This Works)', faker);
+ expect(spy).toHaveBeenCalledWith('This Works');
+ expect(actual).toBeTypeOf('string');
+ expect(actual).toBe('This-Works');
+ });
+
+ it('supports method calls with wrongly quoted argument', () => {
+ const spy = vi.spyOn(faker.helpers, 'slugify');
+ const actual = fakeEval("helpers.slugify('')", faker);
+ expect(spy).toHaveBeenCalledWith("''");
+ expect(actual).toBeTypeOf('string');
+ expect(actual).toBe('');
+ });
+
+ it('should be able to return empty strings', () => {
+ const actual = fakeEval('string.alphanumeric(0)', faker);
+ expect(actual).toBeTypeOf('string');
+ expect(actual).toBe('');
+ });
+
+ it('supports returning complex objects', () => {
+ const actual = fakeEval('airline.airline', faker);
+ expect(actual).toBeTypeOf('object');
+ expect(faker.definitions.airline.airline).toContain(actual);
+ });
+
+ it('supports patterns after a function call', () => {
+ const actual = fakeEval('airline.airline().name', faker);
+ expect(actual).toBeTypeOf('string');
+ expect(faker.definitions.airline.airline.map(({ name }) => name)).toContain(
+ actual
+ ); // function().name
+ });
+
+ it('supports patterns after a function reference', () => {
+ const actual = fakeEval('airline.airline.iataCode', faker);
+ expect(actual).toBeTypeOf('string');
+ expect(
+ faker.definitions.airline.airline.map(({ iataCode }) => iataCode)
+ ).toContain(actual);
+ });
+
+ it('requires a dot after a function call', () => {
+ expect(() => fakeEval('airline.airline()iataCode', faker)).toThrowError(
+ new FakerError(
+ "Expected dot ('.'), open parenthesis ('('), or nothing after function call but got 'i'"
+ )
+ );
+ });
+
+ it('requires a function for parameters', () => {
+ // TODO @ST-DDT 2023-12-11: Replace in v9
+ // expect(faker.definitions.person.first_name).toBeDefined();
+ //expect(() => fakeEval('person.first_name()', faker)).toThrow(
+ // new FakerError(`Cannot resolve expression 'person.first_name'`)
+ // );
+ const actual = fakeEval('person.first_name()', faker);
+ expect(faker.definitions.person.first_name).toContain(actual);
+ });
+
+ it('requires a valid expression (missing value)', () => {
+ expect(() => fakeEval('foo.bar', faker)).toThrow(
+ new FakerError(`Cannot resolve expression 'foo.bar'`)
+ );
+ });
+
+ it('requires a valid expression (trailing dot)', () => {
+ expect(() => fakeEval('airline.airline.', faker)).toThrowError(
+ new FakerError("Found dot without property name in 'airline.'")
+ );
+ expect(() => fakeEval('airline.airline.()', faker)).toThrowError(
+ new FakerError("Found dot without property name in 'airline.()'")
+ );
+ expect(() => fakeEval('airline.airline.().iataCode', faker)).toThrowError(
+ new FakerError("Found dot without property name in 'airline.().iataCode'")
+ );
+ });
+
+ it('requires a valid expression (unclosed parenthesis)', () => {
+ expect(() => fakeEval('airline.airline(', faker)).toThrowError(
+ new FakerError("Missing closing parenthesis in '('")
+ );
+ expect(() => fakeEval('airline.airline(.iataCode', faker)).toThrowError(
+ new FakerError("Missing closing parenthesis in '(.iataCode'")
+ );
+ });
+});
diff --git a/test/modules/helpers.spec.ts b/test/modules/helpers.spec.ts
index 1a1db9c5..1b9ba3ae 100644
--- a/test/modules/helpers.spec.ts
+++ b/test/modules/helpers.spec.ts
@@ -1027,34 +1027,35 @@ describe('helpers', () => {
it('does not allow invalid module name', () => {
expect(() => faker.helpers.fake('{{foo.bar}}')).toThrow(
- new FakerError(`Invalid module method or definition: foo.bar
-- faker.foo.bar is not a function
-- faker.definitions.foo.bar is not an array`)
+ new FakerError(`Cannot resolve expression 'foo.bar'`)
);
});
- it('does not allow missing method name', () => {
- expect(() => faker.helpers.fake('{{location}}')).toThrow(
- new FakerError(`Invalid module method or definition: location
-- faker.location is not a function
-- faker.definitions.location is not an array`)
- );
+ it('does allow missing method name', () => {
+ const actual = faker.helpers.fake('{{location}}');
+ expect(actual).toBe('[object Object]');
});
it('does not allow invalid method name', () => {
expect(() => faker.helpers.fake('{{location.foo}}')).toThrow(
- new FakerError(`Invalid module method or definition: location.foo
-- faker.location.foo is not a function
-- faker.definitions.location.foo is not an array`)
+ new FakerError(`Cannot resolve expression 'location.foo'`)
);
});
- it('does not allow invalid definitions data', () => {
- expect(() => faker.helpers.fake('{{finance.credit_card}}')).toThrow(
- new FakerError(`Invalid module method or definition: finance.credit_card
-- faker.finance.credit_card is not a function
-- faker.definitions.finance.credit_card is not an array`)
- );
+ it('should support complex data', () => {
+ const actual = faker.helpers.fake('{{science.unit}}');
+ expect(actual).toBe('[object Object]');
+ });
+
+ it('should support resolving a value in a complex object', () => {
+ const complex = faker.helpers.fake('{{airline.airline}}');
+ expect(complex).toBe('[object Object]');
+
+ const actual = faker.helpers.fake('{{airline.airline.iataCode}}');
+ expect(actual).toBeTypeOf('string');
+ expect(
+ faker.definitions.airline.airline.map(({ iataCode }) => iataCode)
+ ).toContain(actual);
});
it('should be able to return empty strings', () => {