game-maker / suite (push) Failing after 3m59s
A shader is an asset carrying a node graph (Texture color, Output, Property, Color, Add/Subtract/Multiply/Divide, Mix, Luminance) that compiles to the GLSL fragment of a Pixi filter. The Shader tab reuses the Behavior canvas; a sprite wears a shader through its Shader picker, and the rows below it are the graph's Property nodes. Property schema, resolution and deviation take the project because a sprite's rows now live in another asset. The built-in registry of the prototype is gone; "Adjust colors" ships as a graph in the fixture and the three example games. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
91 lines
4.3 KiB
TypeScript
91 lines
4.3 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
||
import {
|
||
CreateAssetCommand,
|
||
ResetAssetPropertyCommand,
|
||
SetAssetPropertyCommand,
|
||
} from '../../src/core/commands/assetCommands';
|
||
import { CreateContainerCommand } from '../../src/core/commands/containerCommands';
|
||
import { AddVariableCommand } from '../../src/core/commands/variableCommands';
|
||
import {
|
||
ClearOverrideCommand,
|
||
SetOverrideCommand,
|
||
SetParentCommand,
|
||
} from '../../src/core/commands/sceneObjectCommands';
|
||
import { instanceChildId } from '../../src/core/model/instance';
|
||
import { findAsset } from '../../src/core/model/Project';
|
||
import type { ContainerAsset } from '../../src/core/model/Asset';
|
||
import { assetDeviates, deviationMarks, objectDeviates } from '../../src/core/properties/deviation';
|
||
import { makeProject, makeSpriteScene, place } from '../helpers';
|
||
|
||
describe('deviation marks', () => {
|
||
it('marks an object only once an override really deviates', () => {
|
||
const f = makeSpriteScene();
|
||
const id = place(f, f.spriteId, { x: 0, y: 0 });
|
||
const deviates = () => objectDeviates(f.project, f.sceneOf(), f.object(id));
|
||
expect(deviates()).toBe(false);
|
||
// The asset's own value carried as an override is no deviation.
|
||
f.stack.execute(new SetOverrideCommand(f.sceneId, id, 'width', 100));
|
||
expect(deviates()).toBe(false);
|
||
f.stack.execute(new SetOverrideCommand(f.sceneId, id, 'width', 250));
|
||
expect(deviates()).toBe(true);
|
||
f.stack.execute(new ClearOverrideCommand(f.sceneId, id, 'width'));
|
||
expect(deviates()).toBe(false);
|
||
});
|
||
|
||
it('marks the ancestors of a deviating object, so a folded row still shows it', () => {
|
||
const f = makeSpriteScene();
|
||
const parent = place(f, f.spriteId, { x: 0, y: 0 });
|
||
const child = place(f, f.spriteId, { x: 0, y: 0 });
|
||
f.stack.execute(new SetParentCommand(f.sceneId, child, parent));
|
||
expect(deviationMarks(f.project, f.sceneOf()).size).toBe(0);
|
||
f.stack.execute(new SetOverrideCommand(f.sceneId, child, 'width', 250));
|
||
expect([...deviationMarks(f.project, f.sceneOf())].sort()).toEqual([child, parent].sort());
|
||
});
|
||
|
||
it('marks container content against its template, and the instance above it', () => {
|
||
const f = makeSpriteScene();
|
||
const a = place(f, f.spriteId, { x: 0, y: 0 });
|
||
const create = new CreateContainerCommand(f.sceneId, [a]);
|
||
f.stack.execute(create);
|
||
const template = (findAsset(f.project, create.assetId) as ContainerAsset).objects[0]!.id;
|
||
const content = instanceChildId(create.objectId, template);
|
||
expect(deviationMarks(f.project, f.sceneOf()).size).toBe(0);
|
||
f.stack.execute(new SetOverrideCommand(f.sceneId, content, 'width', 250));
|
||
expect([...deviationMarks(f.project, f.sceneOf())].sort()).toEqual([content, create.objectId].sort());
|
||
});
|
||
});
|
||
|
||
describe('asset deviation', () => {
|
||
const makeAsset = (type: 'sprite' | 'behavior', name: string) => {
|
||
const f = makeProject();
|
||
const create = new CreateAssetCommand(type, name);
|
||
f.stack.execute(create);
|
||
const asset = () => findAsset(f.project, create.asset.id)!;
|
||
expect(asset().type).toBe(type);
|
||
return { ...f, asset, assetId: create.asset.id };
|
||
};
|
||
|
||
it('marks an asset only once a property really differs from its default', () => {
|
||
const f = makeAsset('sprite', 'Box');
|
||
expect(assetDeviates(f.project, f.asset())).toBe(false);
|
||
// Written, but the default value – the inspector shows no gold, so neither does the list.
|
||
f.stack.execute(new SetAssetPropertyCommand(f.assetId, 'width', 100));
|
||
expect(f.asset().props.width).toBe(100);
|
||
expect(assetDeviates(f.project, f.asset())).toBe(false);
|
||
f.stack.execute(new SetAssetPropertyCommand(f.assetId, 'width', 250));
|
||
expect(assetDeviates(f.project, f.asset())).toBe(true);
|
||
f.stack.execute(new ResetAssetPropertyCommand(f.assetId, 'width'));
|
||
expect(assetDeviates(f.project, f.asset())).toBe(false);
|
||
});
|
||
|
||
it('leaves a behavior unmarked for its variables, which the inspector does not mark either', () => {
|
||
const f = makeAsset('behavior', 'Mover');
|
||
f.stack.execute(new AddVariableCommand(f.assetId, 'speed', 'number'));
|
||
f.stack.execute(new SetAssetPropertyCommand(f.assetId, 'speed', 42));
|
||
expect(f.asset().props.speed).toBe(42);
|
||
expect(assetDeviates(f.project, f.asset())).toBe(false);
|
||
f.stack.execute(new SetAssetPropertyCommand(f.assetId, 'enabled', false));
|
||
expect(assetDeviates(f.project, f.asset())).toBe(true);
|
||
});
|
||
});
|