mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
node: fix test-util-parse-env.js (#17701)
This commit is contained in:
@@ -7,6 +7,8 @@ const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const ZigString = JSC.ZigString;
|
||||
const uv = bun.windows.libuv;
|
||||
const validators = @import("./util/validators.zig");
|
||||
const envloader = @import("./../../env_loader.zig");
|
||||
|
||||
pub fn internalErrorName(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
|
||||
const arguments = callframe.arguments_old(1).slice();
|
||||
@@ -212,3 +214,24 @@ pub fn normalizeEncoding(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFr
|
||||
if (str.inMapCaseInsensitive(JSC.Node.Encoding.map)) |enc| return enc.toJS(globalThis);
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn parseEnv(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
|
||||
const content = callframe.argument(0);
|
||||
try validators.validateString(globalThis, content, "content", .{});
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(bun.default_allocator);
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
const str = content.asString().toSlice(globalThis, allocator);
|
||||
|
||||
var map = envloader.Map.init(allocator);
|
||||
var p = envloader.Loader.init(&map, allocator);
|
||||
p.loadFromString(str.slice(), true, false);
|
||||
|
||||
var obj = JSC.JSValue.createEmptyObject(globalThis, map.map.count());
|
||||
for (map.map.keys(), map.map.values()) |k, v| {
|
||||
obj.put(globalThis, JSC.ZigString.initUTF8(k), bun.String.createUTF8ForJS(globalThis, v.value));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -538,9 +538,9 @@ pub const Loader = struct {
|
||||
}
|
||||
|
||||
// mostly for tests
|
||||
pub fn loadFromString(this: *Loader, str: string, comptime overwrite: bool) void {
|
||||
pub fn loadFromString(this: *Loader, str: string, comptime overwrite: bool, comptime expand: bool) void {
|
||||
var source = logger.Source.initPathString("test", str);
|
||||
Parser.parse(&source, this.allocator, this.map, overwrite, false);
|
||||
Parser.parse(&source, this.allocator, this.map, overwrite, false, expand);
|
||||
std.mem.doNotOptimizeAway(&source);
|
||||
}
|
||||
|
||||
@@ -803,6 +803,7 @@ pub const Loader = struct {
|
||||
this.map,
|
||||
override,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
@field(this, base) = source;
|
||||
@@ -873,6 +874,7 @@ pub const Loader = struct {
|
||||
this.map,
|
||||
override,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
try this.custom_files_loaded.put(file_path, source);
|
||||
@@ -1097,6 +1099,7 @@ const Parser = struct {
|
||||
map: *Map,
|
||||
comptime override: bool,
|
||||
comptime is_process: bool,
|
||||
comptime expand: bool,
|
||||
) void {
|
||||
var count = map.map.count();
|
||||
while (this.pos < this.src.len) {
|
||||
@@ -1120,7 +1123,7 @@ const Parser = struct {
|
||||
.conditional = false,
|
||||
};
|
||||
}
|
||||
if (comptime !is_process) {
|
||||
if (comptime !is_process and expand) {
|
||||
var it = map.iterator();
|
||||
while (it.next()) |entry| {
|
||||
if (count > 0) {
|
||||
@@ -1142,9 +1145,10 @@ const Parser = struct {
|
||||
map: *Map,
|
||||
comptime override: bool,
|
||||
comptime is_process: bool,
|
||||
comptime expand: bool,
|
||||
) void {
|
||||
var parser = Parser{ .src = source.contents };
|
||||
parser._parse(allocator, map, override, is_process);
|
||||
parser._parse(allocator, map, override, is_process, expand);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ const { promisify } = require("internal/promisify");
|
||||
const { validateString, validateOneOf } = require("internal/validators");
|
||||
|
||||
const internalErrorName = $newZigFunction("node_util_binding.zig", "internalErrorName", 1);
|
||||
const parseEnv = $newZigFunction("node_util_binding.zig", "parseEnv", 1);
|
||||
|
||||
const NumberIsSafeInteger = Number.isSafeInteger;
|
||||
const ObjectKeys = Object.keys;
|
||||
@@ -347,7 +348,7 @@ cjs_exports = {
|
||||
// transferableAbortController,
|
||||
aborted,
|
||||
types,
|
||||
// parseEnv,
|
||||
parseEnv,
|
||||
parseArgs,
|
||||
TextDecoder,
|
||||
TextEncoder,
|
||||
|
||||
1
test/js/node/test/fixtures/dotenv/valid.env
vendored
1
test/js/node/test/fixtures/dotenv/valid.env
vendored
@@ -38,6 +38,7 @@ RETAIN_INNER_QUOTES={"foo": "bar"}
|
||||
RETAIN_INNER_QUOTES_AS_STRING='{"foo": "bar"}'
|
||||
RETAIN_INNER_QUOTES_AS_BACKTICKS=`{"foo": "bar's"}`
|
||||
TRIM_SPACE_FROM_UNQUOTED= some spaced out string
|
||||
SPACE_BEFORE_DOUBLE_QUOTES= "space before double quotes"
|
||||
EMAIL=therealnerdybeast@example.tld
|
||||
SPACED_KEY = parsed
|
||||
EDGE_CASE_INLINE_COMMENTS="VALUE1" # or "VALUE2" or "VALUE3"
|
||||
|
||||
70
test/js/node/test/parallel/test-util-parse-env.js
Normal file
70
test/js/node/test/parallel/test-util-parse-env.js
Normal file
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
const fixtures = require('../../test/common/fixtures');
|
||||
const assert = require('node:assert');
|
||||
const util = require('node:util');
|
||||
const fs = require('node:fs');
|
||||
|
||||
{
|
||||
const validEnvFilePath = fixtures.path('dotenv/valid.env');
|
||||
const validContent = fs.readFileSync(validEnvFilePath, 'utf8');
|
||||
|
||||
assert.deepStrictEqual(util.parseEnv(validContent), {
|
||||
AFTER_LINE: 'after_line',
|
||||
BACKTICKS: 'backticks',
|
||||
BACKTICKS_INSIDE_DOUBLE: '`backticks` work inside double quotes',
|
||||
BACKTICKS_INSIDE_SINGLE: '`backticks` work inside single quotes',
|
||||
BACKTICKS_SPACED: ' backticks ',
|
||||
BASIC: 'basic',
|
||||
DONT_EXPAND_SQUOTED: 'dontexpand\\nnewlines',
|
||||
DONT_EXPAND_UNQUOTED: 'dontexpand\\nnewlines',
|
||||
DOUBLE_AND_SINGLE_QUOTES_INSIDE_BACKTICKS: "double \"quotes\" and single 'quotes' work inside backticks",
|
||||
DOUBLE_QUOTES: 'double_quotes',
|
||||
DOUBLE_QUOTES_INSIDE_BACKTICKS: 'double "quotes" work inside backticks',
|
||||
DOUBLE_QUOTES_INSIDE_SINGLE: 'double "quotes" work inside single quotes',
|
||||
DOUBLE_QUOTES_SPACED: ' double quotes ',
|
||||
DOUBLE_QUOTES_WITH_NO_SPACE_BRACKET: '{ port: $MONGOLAB_PORT}',
|
||||
EDGE_CASE_INLINE_COMMENTS: 'VALUE1',
|
||||
EMAIL: 'therealnerdybeast@example.tld',
|
||||
EMPTY: '',
|
||||
EMPTY_BACKTICKS: '',
|
||||
EMPTY_DOUBLE_QUOTES: '',
|
||||
EMPTY_SINGLE_QUOTES: '',
|
||||
EQUAL_SIGNS: 'equals==',
|
||||
EXPORT_EXAMPLE: 'ignore export',
|
||||
EXPAND_NEWLINES: 'expand\nnew\nlines',
|
||||
INLINE_COMMENTS: 'inline comments',
|
||||
INLINE_COMMENTS_BACKTICKS: 'inline comments outside of #backticks',
|
||||
INLINE_COMMENTS_DOUBLE_QUOTES: 'inline comments outside of #doublequotes',
|
||||
INLINE_COMMENTS_SINGLE_QUOTES: 'inline comments outside of #singlequotes',
|
||||
INLINE_COMMENTS_SPACE: 'inline comments start with a',
|
||||
MULTI_BACKTICKED: 'THIS\nIS\nA\n"MULTILINE\'S"\nSTRING',
|
||||
MULTI_DOUBLE_QUOTED: 'THIS\nIS\nA\nMULTILINE\nSTRING',
|
||||
MULTI_NOT_VALID: 'THIS',
|
||||
MULTI_NOT_VALID_QUOTE: '"',
|
||||
MULTI_SINGLE_QUOTED: 'THIS\nIS\nA\nMULTILINE\nSTRING',
|
||||
RETAIN_INNER_QUOTES: '{"foo": "bar"}',
|
||||
RETAIN_INNER_QUOTES_AS_BACKTICKS: '{"foo": "bar\'s"}',
|
||||
RETAIN_INNER_QUOTES_AS_STRING: '{"foo": "bar"}',
|
||||
SINGLE_QUOTES: 'single_quotes',
|
||||
SINGLE_QUOTES_INSIDE_BACKTICKS: "single 'quotes' work inside backticks",
|
||||
SINGLE_QUOTES_INSIDE_DOUBLE: "single 'quotes' work inside double quotes",
|
||||
SINGLE_QUOTES_SPACED: ' single quotes ',
|
||||
SPACED_KEY: 'parsed',
|
||||
SPACE_BEFORE_DOUBLE_QUOTES: 'space before double quotes',
|
||||
TRIM_SPACE_FROM_UNQUOTED: 'some spaced out string',
|
||||
});
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(util.parseEnv(''), {});
|
||||
assert.deepStrictEqual(util.parseEnv('FOO=bar\nFOO=baz\n'), { FOO: 'baz' });
|
||||
|
||||
// Test for invalid input.
|
||||
assert.throws(() => {
|
||||
for (const value of [null, undefined, {}, []]) {
|
||||
util.parseEnv(value);
|
||||
}
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
});
|
||||
Reference in New Issue
Block a user