mirror of
https://github.com/usebruno/bruno.git
synced 2024-12-22 14:41:04 +01:00
Merge pull request #1043 from nelup20/bugfix/521-error_accessing_response_property_with_context_as_key
fix(#521): Allow "context" as the name of a key/var in a JS expression
This commit is contained in:
commit
380047e025
@ -18,8 +18,8 @@ const JS_KEYWORDS = `
|
|||||||
* ```js
|
* ```js
|
||||||
* res.data.pets.map(pet => pet.name.toUpperCase())
|
* res.data.pets.map(pet => pet.name.toUpperCase())
|
||||||
*
|
*
|
||||||
* function(context) {
|
* function(__bruno__functionInnerContext) {
|
||||||
* const { res, pet } = context;
|
* const { res, pet } = __bruno__functionInnerContext;
|
||||||
* return res.data.pets.map(pet => pet.name.toUpperCase())
|
* return res.data.pets.map(pet => pet.name.toUpperCase())
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
@ -45,9 +45,11 @@ const compileJsExpression = (expr) => {
|
|||||||
globals: globals.map((name) => ` ${name} = ${name} ?? globalThis.${name};`).join('')
|
globals: globals.map((name) => ` ${name} = ${name} ?? globalThis.${name};`).join('')
|
||||||
};
|
};
|
||||||
|
|
||||||
const body = `let { ${code.vars} } = context; ${code.globals}; return ${expr}`;
|
// param name that is unlikely to show up as a var in an expression
|
||||||
|
const param = `__bruno__functionInnerContext`;
|
||||||
|
const body = `let { ${code.vars} } = ${param}; ${code.globals}; return ${expr}`;
|
||||||
|
|
||||||
return new Function('context', body);
|
return new Function(param, body);
|
||||||
};
|
};
|
||||||
|
|
||||||
const internalExpressionCache = new Map();
|
const internalExpressionCache = new Map();
|
||||||
|
@ -5,7 +5,9 @@ describe('utils', () => {
|
|||||||
describe('expression evaluation', () => {
|
describe('expression evaluation', () => {
|
||||||
const context = {
|
const context = {
|
||||||
res: {
|
res: {
|
||||||
data: { pets: ['bruno', 'max'] }
|
data: { pets: ['bruno', 'max'] },
|
||||||
|
context: 'testContext',
|
||||||
|
__bruno__functionInnerContext: 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,32 +47,32 @@ describe('utils', () => {
|
|||||||
it('should identify top level variables', () => {
|
it('should identify top level variables', () => {
|
||||||
const expr = 'res.data.pets[0].toUpperCase()';
|
const expr = 'res.data.pets[0].toUpperCase()';
|
||||||
evaluateJsExpression(expr, context);
|
evaluateJsExpression(expr, context);
|
||||||
expect(cache.get(expr).toString()).toContain('let { res } = context;');
|
expect(cache.get(expr).toString()).toContain('let { res } = __bruno__functionInnerContext;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not duplicate variables', () => {
|
it('should not duplicate variables', () => {
|
||||||
const expr = 'res.data.pets[0] + res.data.pets[1]';
|
const expr = 'res.data.pets[0] + res.data.pets[1]';
|
||||||
evaluateJsExpression(expr, context);
|
evaluateJsExpression(expr, context);
|
||||||
expect(cache.get(expr).toString()).toContain('let { res } = context;');
|
expect(cache.get(expr).toString()).toContain('let { res } = __bruno__functionInnerContext;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should exclude js keywords like true false from vars', () => {
|
it('should exclude js keywords like true false from vars', () => {
|
||||||
const expr = 'res.data.pets.length > 0 ? true : false';
|
const expr = 'res.data.pets.length > 0 ? true : false';
|
||||||
evaluateJsExpression(expr, context);
|
evaluateJsExpression(expr, context);
|
||||||
expect(cache.get(expr).toString()).toContain('let { res } = context;');
|
expect(cache.get(expr).toString()).toContain('let { res } = __bruno__functionInnerContext;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should exclude numbers from vars', () => {
|
it('should exclude numbers from vars', () => {
|
||||||
const expr = 'res.data.pets.length + 10';
|
const expr = 'res.data.pets.length + 10';
|
||||||
evaluateJsExpression(expr, context);
|
evaluateJsExpression(expr, context);
|
||||||
expect(cache.get(expr).toString()).toContain('let { res } = context;');
|
expect(cache.get(expr).toString()).toContain('let { res } = __bruno__functionInnerContext;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pick variables from complex expressions', () => {
|
it('should pick variables from complex expressions', () => {
|
||||||
const expr = 'res.data.pets.map(pet => pet.length)';
|
const expr = 'res.data.pets.map(pet => pet.length)';
|
||||||
const result = evaluateJsExpression(expr, context);
|
const result = evaluateJsExpression(expr, context);
|
||||||
expect(result).toEqual([5, 3]);
|
expect(result).toEqual([5, 3]);
|
||||||
expect(cache.get(expr).toString()).toContain('let { res, pet } = context;');
|
expect(cache.get(expr).toString()).toContain('let { res, pet } = __bruno__functionInnerContext;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be ok picking extra vars from strings', () => {
|
it('should be ok picking extra vars from strings', () => {
|
||||||
@ -78,7 +80,7 @@ describe('utils', () => {
|
|||||||
const result = evaluateJsExpression(expr, context);
|
const result = evaluateJsExpression(expr, context);
|
||||||
expect(result).toBe('hello bruno');
|
expect(result).toBe('hello bruno');
|
||||||
// extra var hello is harmless
|
// extra var hello is harmless
|
||||||
expect(cache.get(expr).toString()).toContain('let { hello, res } = context;');
|
expect(cache.get(expr).toString()).toContain('let { hello, res } = __bruno__functionInnerContext;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should evaluate expressions referencing globals', () => {
|
it('should evaluate expressions referencing globals', () => {
|
||||||
@ -112,6 +114,20 @@ describe('utils', () => {
|
|||||||
|
|
||||||
expect(result).toBe(startTime);
|
expect(result).toBe(startTime);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow "context" as a var name', () => {
|
||||||
|
const expr = 'res["context"].toUpperCase()';
|
||||||
|
evaluateJsExpression(expr, context);
|
||||||
|
expect(cache.get(expr).toString()).toContain('let { res, context } = __bruno__functionInnerContext;');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error when we use "__bruno__functionInnerContext" as a var name', () => {
|
||||||
|
const expr = 'res["__bruno__functionInnerContext"].toUpperCase()';
|
||||||
|
expect(() => evaluateJsExpression(expr, context)).toThrow(SyntaxError);
|
||||||
|
expect(() => evaluateJsExpression(expr, context)).toThrow(
|
||||||
|
"Identifier '__bruno__functionInnerContext' has already been declared"
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('response parser', () => {
|
describe('response parser', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user