Skip to content

Commit bf6e13a

Browse files
committed
test(env-file): add integration tests for YAML and .bru variable persistence
- Implemented new tests to verify the persistence of typed environment variables to both YAML and .bru files using the --env-file option. - Ensured that typed values are correctly serialized with appropriate annotations in the output files, validating the correct handling of different formats. - Enhanced coverage for the persistence behavior of environment variables, confirming that existing entries remain unchanged while new variables are accurately written.
1 parent 08fbb8f commit bf6e13a

2 files changed

Lines changed: 120 additions & 1 deletion

File tree

packages/bruno-cli/src/utils/persist-variables.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,14 @@ const persistCollectionVars = (collection, scriptCollVars, collectionRootPath) =
371371
* } | null} result - Runtime return value; any field may be null to indicate "unchanged".
372372
* @param {{
373373
* envFile?: { path: string, format: 'json' | 'yml' | 'bru' },
374-
* globalEnvFile?: { path: string, format: 'json' | 'yml' | 'bru' },
374+
* globalEnvFile?: { path: string, format: 'yml' },
375375
* collection: object,
376376
* collectionRootPath: string,
377377
* envVarOverrides?: Set<string>
378378
* }} targets - Where each kind of var should land on disk. `envVarOverrides` lists names
379379
* supplied via CLI `--env-var`; they are never persisted to the active env file.
380+
* `globalEnvFile.format` is yml-only because the CLI's `--global-env <name>` flag looks
381+
* up `<workspace>/environments/<name>.yml` (no JSON/bru equivalent exists today).
380382
* @returns {void}
381383
*
382384
* @example

packages/bruno-cli/tests/integration/run-typed-persistence.spec.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,123 @@ script:post-response {
373373
expect(byName.host).toMatchObject({ uid: 'var-host', custom: 'keep-host' });
374374
}, 60_000);
375375

376+
// End-to-end coverage of resolveEnvFileFormat's extension-detection branching for the
377+
// two non-JSON formats. The persistence behavior for yml / bru is already proven via
378+
// --env (.bru) and --global-env (.yml); these tests prove that --env-file <path>.yml
379+
// and --env-file <path>.bru also wire through correctly — descriptor format inferred
380+
// from the extension, parser/serializer selected accordingly.
381+
it('persists typed env vars to a --env-file YAML file with type/data blocks', async () => {
382+
writeFixtureFile(
383+
path.join(tmpDir, 'bruno.json'),
384+
JSON.stringify({ version: '1', name: 'yml-envfile-collection', type: 'collection' }, null, 2) + '\n'
385+
);
386+
writeFixtureFile(
387+
path.join(tmpDir, 'collection.bru'),
388+
'meta {\n name: yml-envfile-collection\n seq: 1\n}\n'
389+
);
390+
writeFixtureFile(
391+
path.join(tmpDir, 'External.yml'),
392+
`name: External\nvariables:\n - name: host\n value: ${baseUrl}\n enabled: true\n secret: false\n`
393+
);
394+
writeFixtureFile(
395+
path.join(tmpDir, 'set-typed-vars.bru'),
396+
`meta {
397+
name: set-typed-vars
398+
type: http
399+
seq: 1
400+
}
401+
402+
get {
403+
url: {{host}}/ping
404+
body: none
405+
auth: none
406+
}
407+
408+
script:post-response {
409+
bru.setEnvVar("port", 3000);
410+
bru.setEnvVar("enabled", true);
411+
}
412+
`
413+
);
414+
415+
const result = await runCli([
416+
'run', 'set-typed-vars.bru',
417+
'--env-file', 'External.yml',
418+
'--sandbox', 'developer',
419+
'--noproxy'
420+
]);
421+
422+
if (result.code !== 0) {
423+
throw new Error(
424+
`CLI exited with code ${result.code}.\n--- stdout ---\n${result.stdout}\n--- stderr ---\n${result.stderr}`
425+
);
426+
}
427+
428+
// yml serializer encodes typed values as `value: { type, data }` blocks.
429+
const written = fs.readFileSync(path.join(tmpDir, 'External.yml'), 'utf8');
430+
expect(written).toMatch(/name:\s*port[\s\S]*?type:\s*number[\s\S]*?data:\s*['"]?3000/);
431+
expect(written).toMatch(/name:\s*enabled[\s\S]*?type:\s*boolean[\s\S]*?data:\s*['"]?true/);
432+
// String values stay as raw `value: ...` — no type/data block.
433+
expect(written).toMatch(/name:\s*host[\s\S]*?value:\s*['"]?http:\/\/127\.0\.0\.1/);
434+
expect(written).not.toMatch(/name:\s*host[\s\S]*?type:\s*string/);
435+
}, 60_000);
436+
437+
it('persists typed env vars to a --env-file .bru file with @dataType annotations', async () => {
438+
writeFixtureFile(
439+
path.join(tmpDir, 'bruno.json'),
440+
JSON.stringify({ version: '1', name: 'bru-envfile-collection', type: 'collection' }, null, 2) + '\n'
441+
);
442+
writeFixtureFile(
443+
path.join(tmpDir, 'collection.bru'),
444+
'meta {\n name: bru-envfile-collection\n seq: 1\n}\n'
445+
);
446+
writeFixtureFile(
447+
path.join(tmpDir, 'External.bru'),
448+
`vars {\n host: ${baseUrl}\n}\n`
449+
);
450+
writeFixtureFile(
451+
path.join(tmpDir, 'set-typed-vars.bru'),
452+
`meta {
453+
name: set-typed-vars
454+
type: http
455+
seq: 1
456+
}
457+
458+
get {
459+
url: {{host}}/ping
460+
body: none
461+
auth: none
462+
}
463+
464+
script:post-response {
465+
bru.setEnvVar("port", 3000);
466+
bru.setEnvVar("enabled", true);
467+
}
468+
`
469+
);
470+
471+
const result = await runCli([
472+
'run', 'set-typed-vars.bru',
473+
'--env-file', 'External.bru',
474+
'--sandbox', 'developer',
475+
'--noproxy'
476+
]);
477+
478+
if (result.code !== 0) {
479+
throw new Error(
480+
`CLI exited with code ${result.code}.\n--- stdout ---\n${result.stdout}\n--- stderr ---\n${result.stderr}`
481+
);
482+
}
483+
484+
// .bru serializer emits typed values as `@dataType` decorators on the preceding line.
485+
const written = fs.readFileSync(path.join(tmpDir, 'External.bru'), 'utf8');
486+
expect(written).toMatch(/@number\s+port:\s*3000/);
487+
expect(written).toMatch(/@boolean\s+enabled:\s*true/);
488+
// String values get no annotation.
489+
expect(written).not.toMatch(/@string\s+host/);
490+
expect(written).toMatch(/host:\s*http:\/\/127\.0\.0\.1/);
491+
}, 60_000);
492+
376493
// Regression guard at the CLI binary boundary: --env-var values are transient (the CLI
377494
// can't decrypt at-rest secrets, so users pass them in for a single run). Even though a
378495
// script writes an unrelated env var — which dirties the env scope and makes the runtime

0 commit comments

Comments
 (0)