mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-03-08 01:53:30 +01:00
Added sprint protocol
This commit is contained in:
207
packages/noodl-editor/tests/models/ElementConfigRegistry.test.ts
Normal file
207
packages/noodl-editor/tests/models/ElementConfigRegistry.test.ts
Normal file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* STYLE-004: Unit tests for ElementConfigRegistry
|
||||
*
|
||||
* Covers: applyVariant, applySize, getSizeNames, resolveVariant,
|
||||
* getVariantNames, applyDefaults.
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from '@jest/globals';
|
||||
|
||||
import { ElementConfigRegistry, NodeModelLike } from '../../src/editor/src/models/ElementConfigs/ElementConfigRegistry';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function makeNode(): NodeModelLike {
|
||||
return { parameters: {} };
|
||||
}
|
||||
|
||||
const BUTTON_TYPE = 'net.noodl.controls.button';
|
||||
const TEXT_TYPE = 'net.noodl.visual.text';
|
||||
const GROUP_TYPE = 'net.noodl.visual.group';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// applyVariant
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('ElementConfigRegistry.applyVariant', () => {
|
||||
it('stamps base styles onto node parameters', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applyVariant(node, BUTTON_TYPE, 'primary');
|
||||
|
||||
expect(node.parameters['backgroundColor']).toBe('var(--primary)');
|
||||
expect(node.parameters['color']).toBe('var(--primary-foreground)');
|
||||
expect(node.parameters['_variant']).toBe('primary');
|
||||
});
|
||||
|
||||
it('does not include the "states" key in stamped parameters', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applyVariant(node, BUTTON_TYPE, 'primary');
|
||||
|
||||
expect(node.parameters['states']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('updates _variant marker when switching variants', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applyVariant(node, BUTTON_TYPE, 'primary');
|
||||
ElementConfigRegistry.applyVariant(node, BUTTON_TYPE, 'secondary');
|
||||
|
||||
expect(node.parameters['_variant']).toBe('secondary');
|
||||
expect(node.parameters['backgroundColor']).toBe('var(--secondary)');
|
||||
});
|
||||
|
||||
it('is a no-op for an unknown node type', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applyVariant(node, 'unknown.type', 'primary');
|
||||
|
||||
expect(node.parameters).toEqual({});
|
||||
});
|
||||
|
||||
it('is a no-op for an unknown variant name', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applyVariant(node, BUTTON_TYPE, 'nonexistent');
|
||||
|
||||
expect(node.parameters).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// applySize (STYLE-004)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('ElementConfigRegistry.applySize', () => {
|
||||
it('stamps size preset styles onto node parameters', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applySize(node, BUTTON_TYPE, 'sm');
|
||||
|
||||
expect(node.parameters['fontSize']).toBe('var(--text-xs)');
|
||||
expect(node.parameters['_size']).toBe('sm');
|
||||
});
|
||||
|
||||
it('stamps lg preset correctly', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applySize(node, BUTTON_TYPE, 'lg');
|
||||
|
||||
expect(node.parameters['fontSize']).toBe('var(--text-base)');
|
||||
expect(node.parameters['paddingTop']).toBe('var(--space-3)');
|
||||
expect(node.parameters['_size']).toBe('lg');
|
||||
});
|
||||
|
||||
it('is a no-op for a node type with no sizes', () => {
|
||||
const node = makeNode();
|
||||
// Group has no sizes defined
|
||||
ElementConfigRegistry.applySize(node, GROUP_TYPE, 'sm');
|
||||
expect(node.parameters).toEqual({});
|
||||
});
|
||||
|
||||
it('is a no-op for an unknown size name', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applySize(node, BUTTON_TYPE, 'xxl');
|
||||
expect(node.parameters).toEqual({});
|
||||
});
|
||||
|
||||
it('is a no-op for an unknown type', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applySize(node, 'unknown.type', 'md');
|
||||
expect(node.parameters).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// getSizeNames (STYLE-004)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('ElementConfigRegistry.getSizeNames', () => {
|
||||
it('returns size keys in definition order for Button', () => {
|
||||
const sizes = ElementConfigRegistry.getSizeNames(BUTTON_TYPE);
|
||||
expect(sizes).toEqual(['sm', 'md', 'lg', 'xl']);
|
||||
});
|
||||
|
||||
it('returns empty array for node types with no sizes', () => {
|
||||
expect(ElementConfigRegistry.getSizeNames(GROUP_TYPE)).toEqual([]);
|
||||
expect(ElementConfigRegistry.getSizeNames(TEXT_TYPE)).toEqual([]);
|
||||
});
|
||||
|
||||
it('returns empty array for unknown type', () => {
|
||||
expect(ElementConfigRegistry.getSizeNames('unknown.type')).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// getVariantNames
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('ElementConfigRegistry.getVariantNames', () => {
|
||||
it('returns all variant names for Button', () => {
|
||||
const variants = ElementConfigRegistry.getVariantNames(BUTTON_TYPE);
|
||||
expect(variants).toContain('primary');
|
||||
expect(variants).toContain('secondary');
|
||||
expect(variants).toContain('outline');
|
||||
expect(variants).toContain('ghost');
|
||||
expect(variants).toContain('destructive');
|
||||
expect(variants).toContain('link');
|
||||
});
|
||||
|
||||
it('returns empty array for unknown type', () => {
|
||||
expect(ElementConfigRegistry.getVariantNames('unknown.type')).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// resolveVariant
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('ElementConfigRegistry.resolveVariant', () => {
|
||||
it('returns baseStyles and states', () => {
|
||||
const resolved = ElementConfigRegistry.resolveVariant(BUTTON_TYPE, 'primary');
|
||||
expect(resolved).toBeDefined();
|
||||
expect(resolved!.baseStyles['backgroundColor']).toBe('var(--primary)');
|
||||
expect(resolved!.states.hover).toBeDefined();
|
||||
});
|
||||
|
||||
it('does not include "states" key inside baseStyles', () => {
|
||||
const resolved = ElementConfigRegistry.resolveVariant(BUTTON_TYPE, 'primary');
|
||||
expect('states' in resolved!.baseStyles).toBe(false);
|
||||
});
|
||||
|
||||
it('returns undefined for unknown type', () => {
|
||||
expect(ElementConfigRegistry.resolveVariant('unknown.type', 'primary')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns undefined for unknown variant', () => {
|
||||
expect(ElementConfigRegistry.resolveVariant(BUTTON_TYPE, 'nonexistent')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// applyDefaults
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('ElementConfigRegistry.applyDefaults', () => {
|
||||
it('applies default styles and stamps the default variant', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applyDefaults(node, BUTTON_TYPE);
|
||||
|
||||
// Default variant is 'primary', so its styles should be applied
|
||||
expect(node.parameters['_variant']).toBe('primary');
|
||||
expect(node.parameters['backgroundColor']).toBe('var(--primary)');
|
||||
// Base defaults
|
||||
expect(node.parameters['borderRadius']).toBe('var(--radius-md)');
|
||||
expect(node.parameters['cursor']).toBe('pointer');
|
||||
});
|
||||
|
||||
it('does not overwrite already-set parameters', () => {
|
||||
const node = makeNode();
|
||||
node.parameters['cursor'] = 'default';
|
||||
ElementConfigRegistry.applyDefaults(node, BUTTON_TYPE);
|
||||
// Pre-existing value should be preserved
|
||||
expect(node.parameters['cursor']).toBe('default');
|
||||
});
|
||||
|
||||
it('is a no-op for unknown type', () => {
|
||||
const node = makeNode();
|
||||
ElementConfigRegistry.applyDefaults(node, 'unknown.type');
|
||||
expect(node.parameters).toEqual({});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user