mirror of
https://github.com/usebruno/bruno.git
synced 2025-08-12 13:47:58 +02:00
Feature: implemented bru.interpolate (#4122)
* feat: enhance variable highlighting in CodeMirror and update interpolation method * feat: add interpolate function to bru shim and corresponding tests - Implemented the `interpolate` function in the bru shim to handle variable interpolation. - Added a new test case for the `interpolate` function to verify its functionality with mock variables. * feat: enhance interpolate function to support object interpolation * feat: add translation support for pm.variables.replaceIn to bru.interpolate * revert: eslint config changes * revert: eslint config changes * fix: update method call to use correct interpolation function in Bru class * refactor: added jsdoc to codemirror highlighting code * fix: higlighting for multiline editor
This commit is contained in:
@ -38,4 +38,4 @@ module.exports = defineConfig([
|
|||||||
"no-undef": "error",
|
"no-undef": "error",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
]);
|
]);
|
@ -71,4 +71,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -87,7 +87,8 @@ if (!SERVER_RENDERED) {
|
|||||||
'bru.runner',
|
'bru.runner',
|
||||||
'bru.runner.setNextRequest(requestName)',
|
'bru.runner.setNextRequest(requestName)',
|
||||||
'bru.runner.skipRequest()',
|
'bru.runner.skipRequest()',
|
||||||
'bru.runner.stopExecution()'
|
'bru.runner.stopExecution()',
|
||||||
|
'bru.interpolate(str)'
|
||||||
];
|
];
|
||||||
CodeMirror.registerHelper('hint', 'brunoJS', (editor, options) => {
|
CodeMirror.registerHelper('hint', 'brunoJS', (editor, options) => {
|
||||||
const cursor = editor.getCursor();
|
const cursor = editor.getCursor();
|
||||||
@ -365,7 +366,7 @@ export default class CodeEditor extends React.Component {
|
|||||||
let variables = getAllVariables(this.props.collection, this.props.item);
|
let variables = getAllVariables(this.props.collection, this.props.item);
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
|
|
||||||
defineCodeMirrorBrunoVariablesMode(variables, mode);
|
defineCodeMirrorBrunoVariablesMode(variables, mode, false, this.props.enableVariableHighlighting);
|
||||||
this.editor.setOption('mode', 'brunovariables');
|
this.editor.setOption('mode', 'brunovariables');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ class MultiLineEditor extends Component {
|
|||||||
|
|
||||||
addOverlay = (variables) => {
|
addOverlay = (variables) => {
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
defineCodeMirrorBrunoVariablesMode(variables, 'text/plain');
|
defineCodeMirrorBrunoVariablesMode(variables, 'text/plain', false, true);
|
||||||
this.editor.setOption('mode', 'brunovariables');
|
this.editor.setOption('mode', 'brunovariables');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ const GraphQLVariables = ({ variables, item, collection }) => {
|
|||||||
mode="javascript"
|
mode="javascript"
|
||||||
onRun={onRun}
|
onRun={onRun}
|
||||||
onSave={onSave}
|
onSave={onSave}
|
||||||
|
enableVariableHighlighting={true}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -49,7 +49,7 @@ const RequestBody = ({ item, collection }) => {
|
|||||||
<StyledWrapper className="w-full">
|
<StyledWrapper className="w-full">
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
collection={collection}
|
collection={collection}
|
||||||
item={item}
|
item={item}
|
||||||
theme={displayedTheme}
|
theme={displayedTheme}
|
||||||
font={get(preferences, 'font.codeFont', 'default')}
|
font={get(preferences, 'font.codeFont', 'default')}
|
||||||
fontSize={get(preferences, 'font.codeFontSize')}
|
fontSize={get(preferences, 'font.codeFontSize')}
|
||||||
@ -58,13 +58,14 @@ const RequestBody = ({ item, collection }) => {
|
|||||||
onRun={onRun}
|
onRun={onRun}
|
||||||
onSave={onSave}
|
onSave={onSave}
|
||||||
mode={codeMirrorMode[bodyMode]}
|
mode={codeMirrorMode[bodyMode]}
|
||||||
|
enableVariableHighlighting={true}
|
||||||
/>
|
/>
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bodyMode === 'file') {
|
if (bodyMode === 'file') {
|
||||||
return <FileBody item={item} collection={collection}/>
|
return <FileBody item={item} collection={collection} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bodyMode === 'formUrlEncoded') {
|
if (bodyMode === 'formUrlEncoded') {
|
||||||
@ -77,4 +78,4 @@ const RequestBody = ({ item, collection }) => {
|
|||||||
|
|
||||||
return <StyledWrapper className="w-full">No Body</StyledWrapper>;
|
return <StyledWrapper className="w-full">No Body</StyledWrapper>;
|
||||||
};
|
};
|
||||||
export default RequestBody;
|
export default RequestBody;
|
||||||
|
@ -146,7 +146,7 @@ class SingleLineEditor extends Component {
|
|||||||
|
|
||||||
addOverlay = (variables) => {
|
addOverlay = (variables) => {
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
defineCodeMirrorBrunoVariablesMode(variables, 'text/plain', this.props.highlightPathParams);
|
defineCodeMirrorBrunoVariablesMode(variables, 'text/plain', this.props.highlightPathParams, true);
|
||||||
this.editor.setOption('mode', 'brunovariables');
|
this.editor.setOption('mode', 'brunovariables');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,11 +74,11 @@ export class MaskedEditor {
|
|||||||
} else {
|
} else {
|
||||||
for (let line = 0; line < lineCount; line++) {
|
for (let line = 0; line < lineCount; line++) {
|
||||||
const lineLength = this.editor.getLine(line).length;
|
const lineLength = this.editor.getLine(line).length;
|
||||||
const maskedNode = document.createTextNode('*'.repeat(lineLength));
|
const maskedNode = document.createTextNode('*'.repeat(lineLength));
|
||||||
this.editor.markText(
|
this.editor.markText(
|
||||||
{ line, ch: 0 },
|
{ line, ch: 0 },
|
||||||
{ line, ch: lineLength },
|
{ line, ch: lineLength },
|
||||||
{ replacedWith: maskedNode, handleMouseEvents: false }
|
{ replacedWith: maskedNode, handleMouseEvents: false }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,7 +86,18 @@ export class MaskedEditor {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defineCodeMirrorBrunoVariablesMode = (_variables, mode, highlightPathParams) => {
|
/**
|
||||||
|
* Defines a custom CodeMirror mode for Bruno variables highlighting.
|
||||||
|
* This function creates a specialized mode that can highlight both Bruno template
|
||||||
|
* variables (in the format {{variable}}) and URL path parameters (in the format /:param).
|
||||||
|
*
|
||||||
|
* @param {Object} _variables - The variables object containing data to validate against
|
||||||
|
* @param {string} mode - The base CodeMirror mode to extend (e.g., 'javascript', 'application/json')
|
||||||
|
* @param {boolean} highlightPathParams - Whether to highlight URL path parameters
|
||||||
|
* @param {boolean} highlightVariables - Whether to highlight template variables
|
||||||
|
* @returns {void} - Registers the mode with CodeMirror for later use
|
||||||
|
*/
|
||||||
|
export const defineCodeMirrorBrunoVariablesMode = (_variables, mode, highlightPathParams, highlightVariables) => {
|
||||||
CodeMirror.defineMode('brunovariables', function (config, parserConfig) {
|
CodeMirror.defineMode('brunovariables', function (config, parserConfig) {
|
||||||
const { pathParams = {}, ...variables } = _variables || {};
|
const { pathParams = {}, ...variables } = _variables || {};
|
||||||
const variablesOverlay = {
|
const variablesOverlay = {
|
||||||
@ -139,13 +150,15 @@ export const defineCodeMirrorBrunoVariablesMode = (_variables, mode, highlightPa
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let baseMode = CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || mode), variablesOverlay);
|
let baseMode = CodeMirror.getMode(config, parserConfig.backdrop || mode);
|
||||||
|
|
||||||
if (highlightPathParams) {
|
if (highlightVariables) {
|
||||||
return CodeMirror.overlayMode(baseMode, urlPathParamsOverlay);
|
baseMode = CodeMirror.overlayMode(baseMode, variablesOverlay);
|
||||||
} else {
|
|
||||||
return baseMode;
|
|
||||||
}
|
}
|
||||||
|
if (highlightPathParams) {
|
||||||
|
baseMode = CodeMirror.overlayMode(baseMode, urlPathParamsOverlay);
|
||||||
|
}
|
||||||
|
return baseMode;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ const replacements = {
|
|||||||
'pm\\.environment\\.set\\(': 'bru.setEnvVar(',
|
'pm\\.environment\\.set\\(': 'bru.setEnvVar(',
|
||||||
'pm\\.variables\\.get\\(': 'bru.getVar(',
|
'pm\\.variables\\.get\\(': 'bru.getVar(',
|
||||||
'pm\\.variables\\.set\\(': 'bru.setVar(',
|
'pm\\.variables\\.set\\(': 'bru.setVar(',
|
||||||
|
'pm\\.variables\\.replaceIn\\(': 'bru.interpolate(',
|
||||||
'pm\\.collectionVariables\\.get\\(': 'bru.getVar(',
|
'pm\\.collectionVariables\\.get\\(': 'bru.getVar(',
|
||||||
'pm\\.collectionVariables\\.set\\(': 'bru.setVar(',
|
'pm\\.collectionVariables\\.set\\(': 'bru.setVar(',
|
||||||
'pm\\.collectionVariables\\.has\\(': 'bru.hasVar(',
|
'pm\\.collectionVariables\\.has\\(': 'bru.hasVar(',
|
||||||
|
@ -52,7 +52,7 @@ const simpleTranslations = {
|
|||||||
'pm.variables.get': 'bru.getVar',
|
'pm.variables.get': 'bru.getVar',
|
||||||
'pm.variables.set': 'bru.setVar',
|
'pm.variables.set': 'bru.setVar',
|
||||||
'pm.variables.has': 'bru.hasVar',
|
'pm.variables.has': 'bru.hasVar',
|
||||||
|
'pm.variables.replaceIn': 'bru.interpolate',
|
||||||
// Collection variables
|
// Collection variables
|
||||||
'pm.collectionVariables.get': 'bru.getVar',
|
'pm.collectionVariables.get': 'bru.getVar',
|
||||||
'pm.collectionVariables.set': 'bru.setVar',
|
'pm.collectionVariables.set': 'bru.setVar',
|
||||||
|
@ -16,8 +16,8 @@ describe('postmanTranslations - comment handling', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should comment non-translated pm commands', () => {
|
test('should comment non-translated pm commands', () => {
|
||||||
const inputScript = "pm.test('random test', () => postman.variables.replaceIn('{{$guid}}'));";
|
const inputScript = "pm.test('random test', () => pm.cookies.get('cookieName'));";
|
||||||
const expectedOutput = "// test('random test', () => pm.variables.replaceIn('{{$guid}}'));";
|
const expectedOutput = "// test('random test', () => pm.cookies.get('cookieName'));";
|
||||||
expect(postmanTranslation(inputScript)).toBe(expectedOutput);
|
expect(postmanTranslation(inputScript)).toBe(expectedOutput);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,55 +5,104 @@ describe('Variables Translation', () => {
|
|||||||
it('should translate pm.variables.get', () => {
|
it('should translate pm.variables.get', () => {
|
||||||
const code = 'pm.variables.get("test");';
|
const code = 'pm.variables.get("test");';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.getVar("test");');
|
expect(translatedCode).toBe('bru.getVar("test");');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should translate pm.variables.set', () => {
|
it('should translate pm.variables.set', () => {
|
||||||
const code = 'pm.variables.set("test", "value");';
|
const code = 'pm.variables.set("test", "value");';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.setVar("test", "value");');
|
expect(translatedCode).toBe('bru.setVar("test", "value");');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should translate pm.variables.has', () => {
|
it('should translate pm.variables.has', () => {
|
||||||
const code = 'pm.variables.has("userId");';
|
const code = 'pm.variables.has("userId");';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.hasVar("userId");');
|
expect(translatedCode).toBe('bru.hasVar("userId");');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should translate pm.variables.replaceIn', () => {
|
||||||
|
const code = 'pm.variables.replaceIn("Hello {{name}}");';
|
||||||
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
|
expect(translatedCode).toBe('bru.interpolate("Hello {{name}}");');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should translate pm.variables.replaceIn with variables and expressions', () => {
|
||||||
|
const code = 'const greeting = pm.variables.replaceIn("Hello {{name}}, your user id is {{userId}}");';
|
||||||
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
|
expect(translatedCode).toBe('const greeting = bru.interpolate("Hello {{name}}, your user id is {{userId}}");');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should translate pm.variables.replaceIn within complex expressions', () => {
|
||||||
|
const code = 'const url = baseUrl + pm.variables.replaceIn("/users/{{userId}}/profile");';
|
||||||
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
|
expect(translatedCode).toBe('const url = baseUrl + bru.interpolate("/users/{{userId}}/profile");');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should translate pm.variables.replaceIn with multiple nested variable references', () => {
|
||||||
|
const code = 'const template = pm.variables.replaceIn("{{prefix}}-{{env}}-{{suffix}}");';
|
||||||
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
|
expect(translatedCode).toBe('const template = bru.interpolate("{{prefix}}-{{env}}-{{suffix}}");');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should translate aliased variables.replaceIn', () => {
|
||||||
|
const code = `
|
||||||
|
const variables = pm.variables;
|
||||||
|
const message = variables.replaceIn("Welcome, {{username}}!");
|
||||||
|
`;
|
||||||
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
|
expect(translatedCode).toBe(`
|
||||||
|
const message = bru.interpolate("Welcome, {{username}}!");
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
// Collection variables tests
|
// Collection variables tests
|
||||||
it('should translate pm.collectionVariables.get', () => {
|
it('should translate pm.collectionVariables.get', () => {
|
||||||
const code = 'pm.collectionVariables.get("apiUrl");';
|
const code = 'pm.collectionVariables.get("apiUrl");';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.getVar("apiUrl");');
|
expect(translatedCode).toBe('bru.getVar("apiUrl");');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should translate pm.collectionVariables.set', () => {
|
it('should translate pm.collectionVariables.set', () => {
|
||||||
const code = 'pm.collectionVariables.set("token", jsonData.token);';
|
const code = 'pm.collectionVariables.set("token", jsonData.token);';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.setVar("token", jsonData.token);');
|
expect(translatedCode).toBe('bru.setVar("token", jsonData.token);');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should translate pm.collectionVariables.has', () => {
|
it('should translate pm.collectionVariables.has', () => {
|
||||||
const code = 'pm.collectionVariables.has("authToken");';
|
const code = 'pm.collectionVariables.has("authToken");';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.hasVar("authToken");');
|
expect(translatedCode).toBe('bru.hasVar("authToken");');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should translate pm.collectionVariables.unset', () => {
|
it('should translate pm.collectionVariables.unset', () => {
|
||||||
const code = 'pm.collectionVariables.unset("tempVar");';
|
const code = 'pm.collectionVariables.unset("tempVar");';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.deleteVar("tempVar");');
|
expect(translatedCode).toBe('bru.deleteVar("tempVar");');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle pm.globals.get', () => {
|
it('should handle pm.globals.get', () => {
|
||||||
const code = 'pm.globals.get("test");';
|
const code = 'pm.globals.get("test");';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.getGlobalEnvVar("test");');
|
expect(translatedCode).toBe('bru.getGlobalEnvVar("test");');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle pm.globals.set', () => {
|
it('should handle pm.globals.set', () => {
|
||||||
const code = 'pm.globals.set("test", "value");';
|
const code = 'pm.globals.set("test", "value");';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.setGlobalEnvVar("test", "value");');
|
expect(translatedCode).toBe('bru.setGlobalEnvVar("test", "value");');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -66,6 +115,7 @@ describe('Variables Translation', () => {
|
|||||||
const get = vars.get("test");
|
const get = vars.get("test");
|
||||||
`;
|
`;
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe(`
|
expect(translatedCode).toBe(`
|
||||||
const has = bru.hasVar("test");
|
const has = bru.hasVar("test");
|
||||||
const set = bru.setVar("test", "value");
|
const set = bru.setVar("test", "value");
|
||||||
@ -83,6 +133,7 @@ describe('Variables Translation', () => {
|
|||||||
const unset = collVars.unset("test");
|
const unset = collVars.unset("test");
|
||||||
`;
|
`;
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe(`
|
expect(translatedCode).toBe(`
|
||||||
const has = bru.hasVar("test");
|
const has = bru.hasVar("test");
|
||||||
const set = bru.setVar("test", "value");
|
const set = bru.setVar("test", "value");
|
||||||
@ -98,6 +149,7 @@ describe('Variables Translation', () => {
|
|||||||
const set = globals.set("test", "value");
|
const set = globals.set("test", "value");
|
||||||
`;
|
`;
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe(`
|
expect(translatedCode).toBe(`
|
||||||
const get = bru.getGlobalEnvVar("test");
|
const get = bru.getGlobalEnvVar("test");
|
||||||
const set = bru.setGlobalEnvVar("test", "value");
|
const set = bru.setGlobalEnvVar("test", "value");
|
||||||
@ -108,6 +160,7 @@ describe('Variables Translation', () => {
|
|||||||
it('should handle conditional expressions with variable calls', () => {
|
it('should handle conditional expressions with variable calls', () => {
|
||||||
const code = 'const userStatus = pm.variables.has("userId") ? "logged-in" : "guest";';
|
const code = 'const userStatus = pm.variables.has("userId") ? "logged-in" : "guest";';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('const userStatus = bru.hasVar("userId") ? "logged-in" : "guest";');
|
expect(translatedCode).toBe('const userStatus = bru.hasVar("userId") ? "logged-in" : "guest";');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -148,6 +201,7 @@ describe('Variables Translation', () => {
|
|||||||
it('should handle more complex nested expressions with variables', () => {
|
it('should handle more complex nested expressions with variables', () => {
|
||||||
const code = 'pm.collectionVariables.set("fullPath", pm.environment.get("baseUrl") + pm.variables.get("endpoint"));';
|
const code = 'pm.collectionVariables.set("fullPath", pm.environment.get("baseUrl") + pm.variables.get("endpoint"));';
|
||||||
const translatedCode = translateCode(code);
|
const translatedCode = translateCode(code);
|
||||||
|
|
||||||
expect(translatedCode).toBe('bru.setVar("fullPath", bru.getEnvVar("baseUrl") + bru.getVar("endpoint"));');
|
expect(translatedCode).toBe('bru.setVar("fullPath", bru.getEnvVar("baseUrl") + bru.getVar("endpoint"));');
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,5 +1,5 @@
|
|||||||
const { cloneDeep } = require('lodash');
|
const { cloneDeep } = require('lodash');
|
||||||
const { interpolate } = require('@usebruno/common');
|
const { interpolate: _interpolate } = require('@usebruno/common');
|
||||||
|
|
||||||
const variableNameRegex = /^[\w-.]*$/;
|
const variableNameRegex = /^[\w-.]*$/;
|
||||||
|
|
||||||
@ -28,10 +28,10 @@ class Bru {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_interpolate = (str) => {
|
interpolate = (strOrObj) => {
|
||||||
if (!str || !str.length || typeof str !== 'string') {
|
if (!strOrObj) return strOrObj;
|
||||||
return str;
|
const isObj = typeof strOrObj === 'object';
|
||||||
}
|
const strToInterpolate = isObj ? JSON.stringify(strOrObj) : strOrObj;
|
||||||
|
|
||||||
const combinedVars = {
|
const combinedVars = {
|
||||||
...this.globalEnvironmentVariables,
|
...this.globalEnvironmentVariables,
|
||||||
@ -48,7 +48,8 @@ class Bru {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return interpolate(str, combinedVars);
|
const interpolatedStr = _interpolate(strToInterpolate, combinedVars);
|
||||||
|
return isObj ? JSON.parse(interpolatedStr) : interpolatedStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
cwd() {
|
cwd() {
|
||||||
@ -68,7 +69,7 @@ class Bru {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getEnvVar(key) {
|
getEnvVar(key) {
|
||||||
return this._interpolate(this.envVariables[key]);
|
return this.interpolate(this.envVariables[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setEnvVar(key, value) {
|
setEnvVar(key, value) {
|
||||||
@ -84,7 +85,7 @@ class Bru {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getGlobalEnvVar(key) {
|
getGlobalEnvVar(key) {
|
||||||
return this._interpolate(this.globalEnvironmentVariables[key]);
|
return this.interpolate(this.globalEnvironmentVariables[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setGlobalEnvVar(key, value) {
|
setGlobalEnvVar(key, value) {
|
||||||
@ -96,7 +97,7 @@ class Bru {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getOauth2CredentialVar(key) {
|
getOauth2CredentialVar(key) {
|
||||||
return this._interpolate(this.oauth2CredentialVariables[key]);
|
return this.interpolate(this.oauth2CredentialVariables[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasVar(key) {
|
hasVar(key) {
|
||||||
@ -111,7 +112,7 @@ class Bru {
|
|||||||
if (variableNameRegex.test(key) === false) {
|
if (variableNameRegex.test(key) === false) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Variable name: "${key}" contains invalid characters!` +
|
`Variable name: "${key}" contains invalid characters!` +
|
||||||
' Names must only contain alpha-numeric characters, "-", "_", "."'
|
' Names must only contain alpha-numeric characters, "-", "_", "."'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,11 +123,11 @@ class Bru {
|
|||||||
if (variableNameRegex.test(key) === false) {
|
if (variableNameRegex.test(key) === false) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Variable name: "${key}" contains invalid characters!` +
|
`Variable name: "${key}" contains invalid characters!` +
|
||||||
' Names must only contain alpha-numeric characters, "-", "_", "."'
|
' Names must only contain alpha-numeric characters, "-", "_", "."'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._interpolate(this.runtimeVariables[key]);
|
return this.interpolate(this.runtimeVariables[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteVar(key) {
|
deleteVar(key) {
|
||||||
@ -142,15 +143,15 @@ class Bru {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCollectionVar(key) {
|
getCollectionVar(key) {
|
||||||
return this._interpolate(this.collectionVariables[key]);
|
return this.interpolate(this.collectionVariables[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFolderVar(key) {
|
getFolderVar(key) {
|
||||||
return this._interpolate(this.folderVariables[key]);
|
return this.interpolate(this.folderVariables[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRequestVar(key) {
|
getRequestVar(key) {
|
||||||
return this._interpolate(this.requestVariables[key]);
|
return this.interpolate(this.requestVariables[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setNextRequest(nextRequest) {
|
setNextRequest(nextRequest) {
|
||||||
|
@ -98,7 +98,7 @@ class ScriptRuntime {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(runRequestByItemPathname) {
|
if (runRequestByItemPathname) {
|
||||||
context.bru.runRequest = runRequestByItemPathname;
|
context.bru.runRequest = runRequestByItemPathname;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ class ScriptRuntime {
|
|||||||
chai,
|
chai,
|
||||||
'node-fetch': fetch,
|
'node-fetch': fetch,
|
||||||
'crypto-js': CryptoJS,
|
'crypto-js': CryptoJS,
|
||||||
'xml2js': xml2js,
|
xml2js: xml2js,
|
||||||
cheerio,
|
cheerio,
|
||||||
tv4,
|
tv4,
|
||||||
...whitelistedModules,
|
...whitelistedModules,
|
||||||
@ -235,7 +235,7 @@ class ScriptRuntime {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(runRequestByItemPathname) {
|
if (runRequestByItemPathname) {
|
||||||
context.bru.runRequest = runRequestByItemPathname;
|
context.bru.runRequest = runRequestByItemPathname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,12 @@ const addBruShimToContext = (vm, bru) => {
|
|||||||
vm.setProp(bruObject, 'getProcessEnv', getProcessEnv);
|
vm.setProp(bruObject, 'getProcessEnv', getProcessEnv);
|
||||||
getProcessEnv.dispose();
|
getProcessEnv.dispose();
|
||||||
|
|
||||||
|
let interpolate = vm.newFunction('interpolate', function (str) {
|
||||||
|
return marshallToVm(bru.interpolate(vm.dump(str)), vm);
|
||||||
|
});
|
||||||
|
vm.setProp(bruObject, 'interpolate', interpolate);
|
||||||
|
interpolate.dispose();
|
||||||
|
|
||||||
let hasEnvVar = vm.newFunction('hasEnvVar', function (key) {
|
let hasEnvVar = vm.newFunction('hasEnvVar', function (key) {
|
||||||
return marshallToVm(bru.hasEnvVar(vm.dump(key)), vm);
|
return marshallToVm(bru.hasEnvVar(vm.dump(key)), vm);
|
||||||
});
|
});
|
||||||
@ -157,7 +163,8 @@ const addBruShimToContext = (vm, bru) => {
|
|||||||
|
|
||||||
let getTestResults = vm.newFunction('getTestResults', () => {
|
let getTestResults = vm.newFunction('getTestResults', () => {
|
||||||
const promise = vm.newPromise();
|
const promise = vm.newPromise();
|
||||||
bru.getTestResults()
|
bru
|
||||||
|
.getTestResults()
|
||||||
.then((results) => {
|
.then((results) => {
|
||||||
promise.resolve(marshallToVm(cleanJson(results), vm));
|
promise.resolve(marshallToVm(cleanJson(results), vm));
|
||||||
})
|
})
|
||||||
@ -178,7 +185,8 @@ const addBruShimToContext = (vm, bru) => {
|
|||||||
|
|
||||||
let getAssertionResults = vm.newFunction('getAssertionResults', () => {
|
let getAssertionResults = vm.newFunction('getAssertionResults', () => {
|
||||||
const promise = vm.newPromise();
|
const promise = vm.newPromise();
|
||||||
bru.getAssertionResults()
|
bru
|
||||||
|
.getAssertionResults()
|
||||||
.then((results) => {
|
.then((results) => {
|
||||||
promise.resolve(marshallToVm(cleanJson(results), vm));
|
promise.resolve(marshallToVm(cleanJson(results), vm));
|
||||||
})
|
})
|
||||||
@ -199,7 +207,8 @@ const addBruShimToContext = (vm, bru) => {
|
|||||||
|
|
||||||
let runRequestHandle = vm.newFunction('runRequest', (args) => {
|
let runRequestHandle = vm.newFunction('runRequest', (args) => {
|
||||||
const promise = vm.newPromise();
|
const promise = vm.newPromise();
|
||||||
bru.runRequest(vm.dump(args))
|
bru
|
||||||
|
.runRequest(vm.dump(args))
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const { status, headers, data, dataBuffer, size, statusText } = response || {};
|
const { status, headers, data, dataBuffer, size, statusText } = response || {};
|
||||||
promise.resolve(marshallToVm(cleanJson({ status, statusText, headers, data, dataBuffer, size }), vm));
|
promise.resolve(marshallToVm(cleanJson({ status, statusText, headers, data, dataBuffer, size }), vm));
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
meta {
|
||||||
|
name: interpolate
|
||||||
|
type: http
|
||||||
|
seq: 13
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: {{host}}/ping
|
||||||
|
body: none
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
tests {
|
||||||
|
test("should interpolate envs", function() {
|
||||||
|
const interpolated = bru.interpolate("url: {{host}}")
|
||||||
|
expect(interpolated).to.equal("url: https://testbench-sanity.usebruno.com");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should interpolate random variables", function() {
|
||||||
|
const a = bru.interpolate("{{$randomInt}}")
|
||||||
|
const b = bru.interpolate("{{$randomInt}}")
|
||||||
|
expect(a).to.not.equal(b)
|
||||||
|
});
|
||||||
|
|
||||||
|
const randomObj = {
|
||||||
|
host: "{{host}}",
|
||||||
|
int: "{{$randomInt}}",
|
||||||
|
timestamp: "{{$timestamp}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
test("should interpolate objects with vars, random vars", function() {
|
||||||
|
const objA = bru.interpolate(randomObj)
|
||||||
|
const objB = bru.interpolate(randomObj)
|
||||||
|
|
||||||
|
expect(objA).to.be.an("object")
|
||||||
|
expect(objB).to.be.an("object")
|
||||||
|
expect(objA).to.not.deep.eql(objB)
|
||||||
|
});
|
||||||
|
}
|
Reference in New Issue
Block a user