kubricate
Version:
A TypeScript framework for building reusable, type-safe Kubernetes infrastructure — without the YAML mess.
400 lines (398 loc) • 10.8 kB
JavaScript
"use strict";
var _vitest = /*#__PURE__*/require("vitest");
var _ResourceComposer = /*#__PURE__*/require("./ResourceComposer.js");
/* eslint-disable @typescript-eslint/no-explicit-any */
class TestClass {
config;
constructor(config) {
this.config = config;
}
}
(0, _vitest.describe)('ResourceComposer', () => {
let composer;
(0, _vitest.beforeEach)(() => {
composer = new _ResourceComposer.ResourceComposer();
});
(0, _vitest.describe)('addClass method', () => {
(0, _vitest.it)('should add a class resource to the composer', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addClass({
id: 'test',
type: TestClass,
config
});
(0, _vitest.expect)(composer['_entries']).toEqual({
test: {
type: TestClass,
config,
entryType: 'class'
}
});
});
});
(0, _vitest.describe)('add method (deprecated)', () => {
(0, _vitest.it)('should add a class resource to the composer using deprecated method', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.add({
id: 'test',
type: TestClass,
config
});
(0, _vitest.expect)(composer['_entries']).toEqual({
test: {
type: TestClass,
config,
entryType: 'class'
}
});
});
});
(0, _vitest.describe)('addObject method', () => {
(0, _vitest.it)('should add an object resource to the composer', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addObject({
id: 'test',
config
});
(0, _vitest.expect)(composer['_entries']).toEqual({
test: {
config,
entryType: 'object'
}
});
});
});
(0, _vitest.describe)('addInstance method (deprecated)', () => {
(0, _vitest.it)('should add an instance resource to the composer using deprecated method', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addInstance({
id: 'test',
config
});
(0, _vitest.expect)(composer['_entries']).toEqual({
test: {
config,
entryType: 'instance'
}
});
});
});
(0, _vitest.describe)('inject method', () => {
(0, _vitest.it)('should inject a value at a path in a class resource', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addClass({
id: 'test',
type: TestClass,
config
});
composer.inject('test', 'metadata.annotations', {
key: 'value'
});
(0, _vitest.expect)(composer._entries['test'].config).toEqual({
metadata: {
name: 'test',
annotations: {
key: 'value'
}
}
});
});
(0, _vitest.it)('should inject a value at a path in an object resource', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addObject({
id: 'test',
config
});
composer.inject('test', 'metadata.annotations', {
key: 'value'
});
(0, _vitest.expect)(composer._entries['test'].config).toEqual({
metadata: {
name: 'test',
annotations: {
key: 'value'
}
}
});
});
(0, _vitest.it)('should throw an error if resource is not found', () => {
(0, _vitest.expect)(() => {
composer.inject('nonexistent', 'metadata.annotations', {
key: 'value'
});
}).toThrow('Cannot inject, resource with ID nonexistent not found.');
});
(0, _vitest.it)('should throw an error if resource is an instance', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addInstance({
id: 'test',
config
});
(0, _vitest.expect)(() => {
composer.inject('test', 'metadata.annotations', {
key: 'value'
});
}).toThrow('Cannot inject, resource with ID test is not an object or class.');
});
});
(0, _vitest.describe)('override method', () => {
(0, _vitest.it)('should store override values', () => {
const overrideValues = {
test: {
metadata: {
labels: {
override: 'true'
}
}
}
};
composer.override(overrideValues);
(0, _vitest.expect)(composer['_override']).toEqual(overrideValues);
});
(0, _vitest.it)('should return the composer instance for chaining', () => {
const result = composer.override({});
(0, _vitest.expect)(result).toBe(composer);
});
});
(0, _vitest.describe)('build method', () => {
(0, _vitest.it)('should build class resources with managed-by labels', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addClass({
id: 'test',
type: TestClass,
config
});
const result = Object.values(composer.build());
(0, _vitest.expect)(result).toHaveLength(1);
(0, _vitest.expect)(result[0]).toBeInstanceOf(TestClass);
});
(0, _vitest.it)('should build object resources with managed-by labels', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addObject({
id: 'test',
config
});
const result = Object.values(composer.build());
(0, _vitest.expect)(result).toHaveLength(1);
(0, _vitest.expect)(result[0]).toEqual({
metadata: {
name: 'test'
}
});
});
(0, _vitest.it)('should build instance resources as-is without modifications', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addInstance({
id: 'test',
config
});
const result = Object.values(composer.build());
(0, _vitest.expect)(result).toHaveLength(1);
(0, _vitest.expect)(result[0]).toEqual(config);
// Should not have labels added
(0, _vitest.expect)(result[0].metadata.labels).toBeUndefined();
});
(0, _vitest.it)('should apply overrides to class resources', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addClass({
id: 'test',
type: TestClass,
config
});
composer.override({
test: {
metadata: {
annotations: {
key: 'value'
}
}
}
});
const result = Object.values(composer.build());
(0, _vitest.expect)(result).toHaveLength(1);
(0, _vitest.expect)(result[0].config.metadata.annotations).toEqual({
key: 'value'
});
// Original name should be preserved
(0, _vitest.expect)(result[0].config.metadata.name).toEqual('test');
});
(0, _vitest.it)('should apply overrides to object resources', () => {
const config = {
metadata: {
name: 'test'
}
};
composer.addObject({
id: 'test',
config
});
composer.override({
test: {
metadata: {
annotations: {
key: 'value'
}
}
}
});
const result = Object.values(composer.build());
(0, _vitest.expect)(result).toHaveLength(1);
(0, _vitest.expect)(result[0].metadata.annotations).toEqual({
key: 'value'
});
// Original name should be preserved
(0, _vitest.expect)(result[0].metadata.name).toEqual('test');
});
(0, _vitest.it)('should handle multiple resources of different types', () => {
const classConfig = {
metadata: {
name: 'class'
}
};
const objectConfig = {
metadata: {
name: 'object'
}
};
const instanceConfig = {
metadata: {
name: 'instance'
}
};
composer.addClass({
id: 'class',
type: TestClass,
config: classConfig
}).addObject({
id: 'object',
config: objectConfig
}).addInstance({
id: 'instance',
config: instanceConfig
});
const result = Object.values(composer.build());
(0, _vitest.expect)(result).toHaveLength(3);
(0, _vitest.expect)(result.some(r => r instanceof TestClass)).toBe(true);
(0, _vitest.expect)(result.some(r => r.metadata?.name === 'object')).toBe(true);
(0, _vitest.expect)(result.some(r => r.metadata?.name === 'instance')).toBe(true);
});
(0, _vitest.it)('should skip resources with null/undefined type when required', () => {
// Add a malformed entry directly to test edge case
composer['_entries']['invalid'] = {
config: {
metadata: {
name: 'invalid'
}
},
entryType: 'class'
// type is missing
};
const result = Object.values(composer.build());
(0, _vitest.expect)(result).toHaveLength(0);
});
(0, _vitest.it)('should deeply merge configs with overrides', () => {
const config = {
metadata: {
name: 'test',
labels: {
original: 'value'
}
}
};
composer.addClass({
id: 'test',
type: TestClass,
config
});
composer.override({
test: {
metadata: {
labels: {
override: 'value'
}
}
}
});
const result = Object.values(composer.build());
// Both original and override labels should be present
(0, _vitest.expect)(result[0].config.metadata.labels).toEqual({
original: 'value',
override: 'value'
});
});
});
(0, _vitest.describe)('Type safety and chaining', () => {
(0, _vitest.it)('should support method chaining', () => {
const composerWithChain = composer.addClass({
id: 'class1',
type: TestClass,
config: {
metadata: {
name: 'class1'
}
}
}).addObject({
id: 'object1',
config: {
metadata: {
name: 'object1'
}
}
}).addInstance({
id: 'instance1',
config: {
metadata: {
name: 'instance1'
}
}
});
(0, _vitest.expect)(composerWithChain).toBe(composer);
(0, _vitest.expect)(Object.keys(composer['_entries'])).toHaveLength(3);
});
});
});
//# sourceMappingURL=ResourceComposer.test.js.map