diff --git a/src/fake.ts b/src/fake.ts index 854b708a568..617708a6b33 100644 --- a/src/fake.ts +++ b/src/fake.ts @@ -46,32 +46,25 @@ export class Fake { * faker.fake('I flipped the coin an got: {{random.arrayElement(["heads", "tails"])}}') // 'I flipped the coin an got: tails' */ fake(str: string): string { - // setup default response as empty string - let res = ''; - // if incoming str parameter is not provided, return error message if (typeof str !== 'string' || str.length === 0) { throw new Error('string parameter is required!'); } // find first matching {{ and }} - const start = str.search('{{'); - const end = str.search('}}'); + const start = str.search(/{{[a-z]/); + const end = str.indexOf('}}', start); // if no {{ and }} is found, we are done if (start === -1 || end === -1) { return str; } - // console.log('attempting to parse', str); - // extract method name from between the {{ }} that we found // for example: {{name.firstName}} - const token = str.substring(start + 2, end); + const token = str.substring(start + 2, end + 2); let method = token.replace('}}', '').replace('{{', ''); - // console.log('method', method) - // extract method parameters const regExp = /\(([^)]+)\)/; const matches = regExp.exec(method); @@ -111,13 +104,14 @@ export class Fake { let result: string; if (typeof params === 'string' && params.length === 0) { - result = fn(); + result = String(fn()); } else { - result = fn(params); + result = String(fn(params)); } - // replace the found tag with the returned fake value - res = str.replace('{{' + token + '}}', result); + // Replace the found tag with the returned fake value + // We cannot use string.replace here because the result might contain evaluated characters + const res = str.substring(0, start) + result + str.substring(end + 2); if (res === '') { return ''; diff --git a/test/fake.spec.ts b/test/fake.spec.ts index a78940eab70..530d09d2861 100644 --- a/test/fake.spec.ts +++ b/test/fake.spec.ts @@ -50,5 +50,39 @@ describe('fake', () => { it('should be able to return empty strings', () => { expect(faker.fake('{{helpers.repeatString}}')).toBe(''); }); + + it('should be able to handle only {{ brackets', () => { + expect(faker.fake('{{hello')).toBe('{{hello'); + expect(faker.fake('hello{{')).toBe('hello{{'); + }); + + it('should be able to handle only }} brackets', () => { + expect(faker.fake('hello}}')).toBe('hello}}'); + expect(faker.fake('}}hello')).toBe('}}hello'); + }); + + it('should be able to handle reverted brackets', () => { + expect(faker.fake('}}hello{{')).toBe('}}hello{{'); + }); + + it('should be able to handle random }} brackets', () => { + expect(faker.fake('}}hello{{random.alpha}}')).toMatch(/^}}hello[a-z]$/); + }); + + it('should be able to handle connected brackets', () => { + expect(faker.fake('{{{random.alpha}}}')).toMatch(/^{[a-z]}$/); + }); + + it('should be able to handle empty brackets', () => { + expect(faker.fake('{{}}')).toBe('{{}}'); + }); + + it('should be able to handle special replacement patterns', () => { + (faker.random as any).special = () => '$&'; + + expect(faker.fake('{{random.special}}')).toBe('$&'); + + delete (faker.random as any).special; + }); }); });