UNPKG

ts-app-env

Version:
139 lines (138 loc) 6.49 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const __1 = require("../"); const pino_1 = __importDefault(require("pino")); const AppConfig = { enabled: (0, __1.boolean)(), flag: (0, __1.boolean)({ default: false }), name: (0, __1.string)({ env: "NAME", notNeededIn: "development" }), nameWithDefault: (0, __1.string)({ env: "NAME_NOT_SET", default: "DEFAULT" }), nameOptional: (0, __1.string)({ env: "NAME_NOT_SET", optional: true }), port: (0, __1.number)({ env: "PORT" }), portWithDefault: (0, __1.number)({ env: "PORT_NOT_SET", default: 8081 }), portOptional: (0, __1.number)({ env: "PORT_NOT_SET", optional: true }), nameIsEnvName: (0, __1.string)(), SOME_URL: (0, __1.string)(), }; /* eslint-disable prefer-destructuring */ describe("AppEnv", () => { // default test value const validEnvVars = { ENABLED: "true", NAME: "app", NAME_IS_ENV_NAME: "app2", PORT: "8080", SOME_URL: "url", }; it("can be constructed", () => { const c = (0, __1.newConfig)(AppConfig, validEnvVars); const name = c.name; expect(name).toBe("app"); }); it("cannot be constructed with missing env vars", () => { expect(() => (0, __1.newConfig)(AppConfig, {})).toThrow(__1.ConfigError); }); it("can be constructed with missing env vars if skip is set", () => { const logger = createMockLogger(); const invalidEnvVars = Object.assign({}, validEnvVars); delete invalidEnvVars.NAME; const conf = (0, __1.newConfig)(AppConfig, invalidEnvVars, { ignoreErrors: true, logger }); expect(conf.name).toBeUndefined(); expect(logger.info).toHaveBeenCalledWith("Ignoring errors while instantiating config: NAME is not set"); }); it("can be constructed with missing env vars and also not complain about it", () => { const logger = createMockLogger(); const invalidEnvVars = Object.assign({}, validEnvVars); delete invalidEnvVars.NAME; const conf = (0, __1.newConfig)(AppConfig, invalidEnvVars, { ignoreErrors: true, doNotLogErrors: true, logger }); expect(conf.name).toBeUndefined(); expect(logger.error).toHaveBeenCalledTimes(0); }); it("logs an error if an env var is missing", () => { const logger = createMockLogger(); const invalidEnvVars = Object.assign({}, validEnvVars); delete invalidEnvVars.NAME; delete invalidEnvVars.PORT; expect(() => (0, __1.newConfig)(AppConfig, invalidEnvVars, { logger })).toThrow(); expect(logger.error).toHaveBeenCalledWith("NAME is not set, PORT is not set"); }); it("can log errors with a custom pino logger", () => { const pinoLogger = (0, pino_1.default)(); const pinoErrorSpy = jest.spyOn(pinoLogger, "error"); const invalidEnvVars = Object.assign({}, validEnvVars); delete invalidEnvVars.NAME; delete invalidEnvVars.PORT; expect(() => (0, __1.newConfig)(AppConfig, invalidEnvVars, { logger: pinoLogger })).toThrow(); expect(pinoErrorSpy).toHaveBeenCalledWith("NAME is not set, PORT is not set"); }); it("error message contains the name of all missing env vars", () => { const invalidEnvVars = Object.assign({}, validEnvVars); delete invalidEnvVars.NAME; delete invalidEnvVars.PORT; expect(() => (0, __1.newConfig)(AppConfig, invalidEnvVars)).toThrow("NAME is not set, PORT is not set"); }); it("can ignore unset values in development environments", () => { const devEnvVars = Object.assign({}, validEnvVars); delete devEnvVars.NAME; const conf = (0, __1.newConfig)(AppConfig, devEnvVars, { nodeEnv: "development" }); expect(conf.name).toBeUndefined(); }); it("uses a default value if its given", () => { const nameWithDefault = (0, __1.newConfig)(AppConfig, validEnvVars).nameWithDefault; expect(nameWithDefault).toBe("DEFAULT"); }); it("can use the property name as the env variable name", () => { const name = (0, __1.newConfig)(AppConfig, validEnvVars).nameIsEnvName; expect(name).toBe("app2"); }); it("can use the property name as if already snake cased", () => { const url = (0, __1.newConfig)(AppConfig, validEnvVars).SOME_URL; expect(url).toBe("url"); }); it("allows options to be optional", () => { const config = (0, __1.newConfig)(AppConfig, validEnvVars); const nameOptional = config.nameOptional; expect(nameOptional).toBeUndefined(); }); it("can parse numbers", () => { const port = (0, __1.newConfig)(AppConfig, validEnvVars).port; expect(port).toBe(8080); }); it("can handle invalid numbers", () => { const vars = Object.assign(Object.assign({}, validEnvVars), { PORT: "invalid" }); expect(() => (0, __1.newConfig)(AppConfig, vars)).toThrow("PORT is not a number"); }); it("can get number default value", () => { const portWithDefault = (0, __1.newConfig)(AppConfig, validEnvVars).portWithDefault; expect(portWithDefault).toBe(8081); }); it("can have optional numbers", () => { const config = (0, __1.newConfig)(AppConfig, validEnvVars); const portOptional = config.portOptional; expect(portOptional).toBeUndefined(); }); it("can have booleans", () => { const config = (0, __1.newConfig)(AppConfig, validEnvVars); const enabled = config.enabled; expect(enabled).toBe(true); }); it("can have booleans that default to false", () => { const config = (0, __1.newConfig)(AppConfig, validEnvVars); expect(config.flag).toBe(false); }); it("numbers are allowed to be floats", () => { validEnvVars.PORT = "100.5"; const config = (0, __1.newConfig)(AppConfig, validEnvVars); expect(config.port).toBe(100.5); }); it("is frozen", () => { const config = (0, __1.newConfig)(AppConfig, validEnvVars); expect(() => (config.name = "something else")).toThrow(new TypeError("Cannot assign to read only property 'name' of object '#<Object>'")); }); }); function createMockLogger() { return { info: jest.fn(), warn: jest.fn(), error: jest.fn() }; }