Files
triggerdotdev--trigger.dev/packages/core/test/flattenAttributes.test.ts
Eric Allam f9ec66c562 v3: new build system (#1265)
* upgrade @opentelemetry packages to the latest versions

* remove v2 only packages, will be moved to a dedicated repo

* remove more v2 code and run pnpm install

* use the npm yalt package in the webapp

* convert @trigger.dev/core to tshy

* Switch from jest to vitest in @trigger.dev/core

* Fixed core test

* move core-backend code into core subpath export

* convert @trigger.dev/sdk to tshy

* Removed hono

* move core-apps to core/v3/apps, remove core-apps, start converting cli-v3

* Fix up some of the commands

* cli now building and loadable

* using package-json-from-dist to get package version now in core and cli

* dev command WIP

* cleaned up some repetition and structure of the entry point stuff

* bringing back the background worker stuff

* Indexing of the v3 catalog

* getting closer to executing dev runs...

* centralize dev logging using event emitter

* Move indexing to it’s own entry point, simplify code

* dev runs working

* Get instrumentation to work with openai

* debugging achieved internally

* provide worker files as part of the worker creation on the server

* support for cjs and esm javascript

* Fixed timeout

* worker manifest now has the config path

* auto-upgrade config to non-deprecated alternatives

* Adding package preview release

* deployment WIP

* improve the syncEnvVars output and adapt resolveEnvVars

* WIP bun runtime

* WIP bun support

* seed tasks with the machine preset if listed in the config

* deploy run executions WIP, extracted TaskRunProcess into 1 place

* deployed tasks running and executing 🎉

* support for waits and better flushing & process cleanup

* Fixed the heartbeating

* Better warning messages

* Improve and unify the indexing between dev and deploy

* Support for external deps that need node-gyp to build

* build extensions can now install custom packages and run instructions in the image. Also prisma extension now works and also works with multiple schema files

* Add back in the main/types/module to sdk

* dev no longer is Ink/React, grace period for disconnections in dev

* Fix the changeset config

* More changeset fixes

* Remove config packages

* More changeset fixes

* Fixed typescript issues (needed to revert back to zod 3.22.3

* Fix pr_checks workflow

* Remove the prepare script

* Fixed tests and package versions

* Remove cli test script

* Remove packages from tailwind watch paths

* Add repo to public packages

* Just commit the generated files and do the building at dev time

* Try and get pkg.pr.new working

* Try again

* Fix emitDecoratorMetadata importing named export from typescript

* config file backwards compat with export const config

* Fixed issue where import errors weren’t coming through

* p-retry is a prod dep

* typescript needs to be a prod dependency for emitDecoratorMetadata

* Add better debug logging to help track down import-in-the-middle bug

* An external is only considered resolvable if it resolves to the same path as the collected external

* Fix runtime checks to allow >=18.20

* Move extensions to a new build package

* Fixed building packages in dockerfile

* Remove the e2e test from publish workflow for now

* Don’t treat pkg.pr.new versions has needing upgrading

* making sure config handleError works, and discovered path aliases don’t work in config files

* Strip empty string env vars so they accidentally override real values

* Couple of things

* Update version to use preview instead of beta

* Hopefully fix re-attempts with >30s delay

* Match socket emit messages to current latest in main

* Initial guide

* Go back to beta

* Go back to the preview, and update guide to use pr preview tags

* Go back to beta

---------

Co-authored-by: Matt Aitken <matt@mattaitken.com>
2024-08-23 13:10:15 +01:00

213 lines
6.1 KiB
TypeScript

import { flattenAttributes, unflattenAttributes } from "../src/v3/utils/flattenAttributes.js";
describe("flattenAttributes", () => {
it("handles null correctly", () => {
expect(flattenAttributes(null)).toEqual({ "": "$@null((" });
expect(unflattenAttributes({ "": "$@null((" })).toEqual(null);
expect(flattenAttributes(null, "$output")).toEqual({ $output: "$@null((" });
expect(flattenAttributes({ foo: null })).toEqual({ foo: "$@null((" });
expect(unflattenAttributes({ foo: "$@null((" })).toEqual({ foo: null });
expect(flattenAttributes({ foo: [null] })).toEqual({ "foo.[0]": "$@null((" });
expect(unflattenAttributes({ "foo.[0]": "$@null((" })).toEqual({ foo: [null] });
expect(flattenAttributes([null])).toEqual({ "[0]": "$@null((" });
expect(unflattenAttributes({ "[0]": "$@null((" })).toEqual([null]);
});
it("flattens string attributes correctly", () => {
const result = flattenAttributes("testString");
expect(result).toEqual({ "": "testString" });
expect(unflattenAttributes(result)).toEqual("testString");
});
it("flattens number attributes correctly", () => {
const result = flattenAttributes(12345);
expect(result).toEqual({ "": 12345 });
expect(unflattenAttributes(result)).toEqual(12345);
});
it("flattens boolean attributes correctly", () => {
const result = flattenAttributes(true);
expect(result).toEqual({ "": true });
expect(unflattenAttributes(result)).toEqual(true);
});
it("flattens boolean attributes correctly", () => {
const result = flattenAttributes(true, "$output");
expect(result).toEqual({ $output: true });
expect(unflattenAttributes(result)).toEqual({ $output: true });
});
it("flattens array attributes correctly", () => {
const input = [1, 2, 3];
const result = flattenAttributes(input);
expect(result).toEqual({ "[0]": 1, "[1]": 2, "[2]": 3 });
expect(unflattenAttributes(result)).toEqual(input);
});
it("flattens complex objects correctly", () => {
const obj = {
level1: {
level2: {
value: "test",
},
array: [1, 2, 3],
},
};
const expected = {
"level1.level2.value": "test",
"level1.array.[0]": 1,
"level1.array.[1]": 2,
"level1.array.[2]": 3,
};
expect(flattenAttributes(obj)).toEqual(expected);
});
it("applies prefixes correctly", () => {
const obj = { key: "value" };
const expected = { "prefix.key": "value" };
expect(flattenAttributes(obj, "prefix")).toEqual(expected);
});
it("handles arrays of objects correctly", () => {
const obj = {
array: [{ key: "value" }, { key: "value" }, { key: "value" }],
};
const expected = {
"array.[0].key": "value",
"array.[1].key": "value",
"array.[2].key": "value",
};
expect(flattenAttributes(obj)).toEqual(expected);
});
it("handles arrays of objects correctly with prefixing correctly", () => {
const obj = {
array: [{ key: "value" }, { key: "value" }, { key: "value" }],
};
const expected = {
"prefix.array.[0].key": "value",
"prefix.array.[1].key": "value",
"prefix.array.[2].key": "value",
};
expect(flattenAttributes(obj, "prefix")).toEqual(expected);
});
it("handles objects of objects correctly", () => {
const obj = {
level1: {
level2: {
key: "value",
},
},
};
const expected = { "level1.level2.key": "value" };
expect(flattenAttributes(obj)).toEqual(expected);
});
it("handles objects of objects correctly with prefixing", () => {
const obj = {
level1: {
level2: {
key: "value",
},
},
};
const expected = { "prefix.level1.level2.key": "value" };
expect(flattenAttributes(obj, "prefix")).toEqual(expected);
});
it("handles retry.byStatus correctly", () => {
const obj = {
"500": {
strategy: "backoff",
maxAttempts: 2,
factor: 2,
minTimeoutInMs: 1_000,
maxTimeoutInMs: 30_000,
randomize: false,
},
};
const expected = {
"retry.byStatus.500.strategy": "backoff",
"retry.byStatus.500.maxAttempts": 2,
"retry.byStatus.500.factor": 2,
"retry.byStatus.500.minTimeoutInMs": 1_000,
"retry.byStatus.500.maxTimeoutInMs": 30_000,
"retry.byStatus.500.randomize": false,
};
expect(flattenAttributes(obj, "retry.byStatus")).toEqual(expected);
});
});
describe("unflattenAttributes", () => {
it("returns the original object for primitive types", () => {
// @ts-expect-error
expect(unflattenAttributes("testString")).toEqual("testString");
// @ts-expect-error
expect(unflattenAttributes(12345)).toEqual(12345);
// @ts-expect-error
expect(unflattenAttributes(true)).toEqual(true);
});
it("correctly reconstructs an object from flattened attributes", () => {
const flattened = {
"level1.level2.value": "test",
"level1.array.[0]": 1,
"level1.array.[1]": 2,
"level1.array.[2]": 3,
};
const expected = {
level1: {
level2: {
value: "test",
},
array: [1, 2, 3],
},
};
expect(unflattenAttributes(flattened)).toEqual(expected);
});
it("handles complex nested objects with mixed types", () => {
const flattened = {
"user.details.name": "John Doe",
"user.details.age": 30,
"user.preferences.colors.[0]": "blue",
"user.preferences.colors.[1]": "green",
"user.active": true,
};
const expected = {
user: {
details: {
name: "John Doe",
age: 30,
},
preferences: {
colors: ["blue", "green"],
},
active: true,
},
};
expect(unflattenAttributes(flattened)).toEqual(expected);
});
it("correctly identifies arrays vs objects", () => {
const flattened = {
"array.[0]": 1,
"array.[1]": 2,
"object.key": "value",
};
const expected = {
array: [1, 2],
object: {
key: "value",
},
};
expect(unflattenAttributes(flattened)).toEqual(expected);
});
});