test(editor): controller tests for graph<->text round-trip
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>
This commit is contained in:
parent
870cbc29f7
commit
e7cd9ca13c
1 changed files with 93 additions and 0 deletions
93
test/editor_controller_test.dart
Normal file
93
test/editor_controller_test.dart
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
// 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);
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue