Four behaviour tests guarding the controller's contract with the rest of the editor: - openFlow seeds the graph + clears the dirty flag against the freshly-captured baseline. - graph edits re-emit YAML into the shared CodeController so the text tab stays in lockstep. - graph edits mark the buffer dirty against the baseline; markSaved snaps it back to clean. - selectStep is idempotent: re-selecting the same step doesn't notify listeners (cheap rebuild guard for the properties panel). 11/11 tests pass. Signed-off-by: flemming-it <sf@flemming.it>
93 lines
2.6 KiB
Dart
93 lines
2.6 KiB
Dart
// Behaviour tests for FlowEditorController — the bridge
|
|
// between the YAML buffer + the graph + the layout sidecar.
|
|
// The model tests cover parsing correctness; these cover
|
|
// that the controller wires text -> graph reparsing,
|
|
// graph -> YAML emission, selection bookkeeping, and
|
|
// dirty/saved transitions correctly.
|
|
|
|
import 'package:fai_studio_flow_editor/src/editor_controller.dart';
|
|
import 'package:fai_studio_flow_editor/src/model/flow_graph.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
group('FlowEditorController', () {
|
|
test('openFlow seeds the graph + clears the dirty flag', () {
|
|
final c = FlowEditorController();
|
|
addTearDown(c.dispose);
|
|
c.openFlow('hello', '''
|
|
name: hello
|
|
inputs:
|
|
name: text
|
|
steps:
|
|
- id: greet
|
|
use: debug.echo@^0
|
|
with:
|
|
message: \$inputs.name
|
|
outputs:
|
|
greeting: \$greet.echoed
|
|
''');
|
|
expect(c.activeName, 'hello');
|
|
expect(c.graph.steps, hasLength(1));
|
|
expect(c.graph.steps.single.id, 'greet');
|
|
expect(c.isDirty, isFalse);
|
|
});
|
|
|
|
test('graph edit re-emits YAML into the text buffer', () {
|
|
final c = FlowEditorController();
|
|
addTearDown(c.dispose);
|
|
c.openFlow('demo', '''
|
|
name: demo
|
|
steps:
|
|
- id: a
|
|
use: debug.echo@^0
|
|
outputs: {}
|
|
''');
|
|
final initialText = c.codeController.fullText;
|
|
c.applyGraphEdit(c.graph.withStepAdded(
|
|
const FlowStep(id: 'b', use: 'debug.echo@^0'),
|
|
));
|
|
expect(c.codeController.fullText, isNot(initialText));
|
|
expect(c.codeController.fullText, contains('id: b'));
|
|
expect(c.graph.steps, hasLength(2));
|
|
});
|
|
|
|
test('graph edit marks the buffer dirty against the baseline', () {
|
|
final c = FlowEditorController();
|
|
addTearDown(c.dispose);
|
|
c.openFlow('demo', '''
|
|
steps:
|
|
- id: a
|
|
use: debug.echo@^0
|
|
outputs: {}
|
|
''');
|
|
expect(c.isDirty, isFalse);
|
|
c.applyGraphEdit(c.graph.withStepAdded(
|
|
const FlowStep(id: 'b', use: 'debug.echo@^0'),
|
|
));
|
|
expect(c.isDirty, isTrue);
|
|
c.markSaved();
|
|
expect(c.isDirty, isFalse);
|
|
});
|
|
|
|
test('selectStep notifies listeners only on change', () {
|
|
final c = FlowEditorController();
|
|
addTearDown(c.dispose);
|
|
c.openFlow('demo', '''
|
|
steps:
|
|
- id: only
|
|
use: debug.echo@^0
|
|
outputs: {}
|
|
''');
|
|
var calls = 0;
|
|
c.addListener(() => calls++);
|
|
c.selectStep('only');
|
|
final after = calls;
|
|
// Selecting the same thing again must NOT bump the
|
|
// listener count — the controller short-circuits.
|
|
c.selectStep('only');
|
|
expect(calls, after);
|
|
c.selectStep(null);
|
|
expect(calls, after + 1);
|
|
});
|
|
});
|
|
}
|