/** * What `+ Variable` offers on a Variables node. The node's own setting decides: empty means the * behavior it sits in, a Variables asset means that asset's declarations – which is the only way * one graph reaches a value another graph writes. */ import { describe, expect, it } from 'vitest'; import { CreateAssetCommand } from '../../src/core/commands/assetCommands'; import { AddNodeCommand } from '../../src/core/commands/graphCommands'; import { AddVariableCommand } from '../../src/core/commands/variableCommands'; import { VARIABLES, VARIABLES_PARAM } from '../../src/core/graph'; import { variableChoices } from '../../src/editor/inspector/portSection'; import { makeBehavior, makeProject } from '../helpers'; describe('the variables a node offers', () => { const scene = () => { const f = makeProject(); const behavior = makeBehavior(f, 'Counter', ['own']); const shared = new CreateAssetCommand('variables', 'Score'); f.stack.execute(shared); f.stack.execute(new AddVariableCommand(shared.asset.id, 'score', 'number')); const add = (source: string) => { const command = new AddNodeCommand(behavior.id, VARIABLES, 0, 0, { [VARIABLES_PARAM]: source }); f.stack.execute(command); return variableChoices(f.project, behavior.id, command.node).map((def) => def.key); }; return { add, sharedId: shared.asset.id }; }; it('offers the behavior’s own when no asset is named', () => { expect(scene().add('')).toEqual(['own']); }); it('offers the asset’s declarations when one is named, and not the behavior’s', () => { const { add, sharedId } = scene(); expect(add(sharedId)).toEqual(['score']); }); /** Falling back to the behavior would offer names the node cannot reach at runtime. */ it('offers nothing when the named asset is gone', () => { expect(scene().add('no-such-asset')).toEqual([]); }); });