// Behavioural tests for FlowAnalyzer — the YAML-aware // AbstractAnalyzer that feeds the flow editor's gutter + the // custom CodeController's wavy-underline overrides. import 'package:fai_studio_flow_editor/src/flow_analyzer.dart'; import 'package:flutter_code_editor/flutter_code_editor.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:highlight/languages/yaml.dart'; Code _wrap(String text) => Code(text: text, language: yaml); void main() { group('FlowAnalyzer', () { test('empty buffer reports no issues', () async { final a = FlowAnalyzer(availableCapabilities: () => const []); final r = await a.analyze(_wrap('')); expect(r.issues, isEmpty); }); test('valid hello flow reports no issues', () async { final a = FlowAnalyzer( availableCapabilities: () => const ['debug.echo'], ); final r = await a.analyze(_wrap(''' name: hello inputs: name: text steps: - id: greet use: debug.echo@^0 with: message: \$inputs.name outputs: greeting: \$greet.echoed ''')); expect(r.issues, isEmpty); }); test('flags unknown capability on the use line', () async { final a = FlowAnalyzer( availableCapabilities: () => const ['debug.echo'], ); final r = await a.analyze(_wrap(''' name: hello inputs: msg: text steps: - id: t use: text.translate@^1 outputs: {} ''')); expect(r.issues, hasLength(1)); expect(r.issues.first.message, contains('text.translate')); expect(r.issues.first.type, IssueType.error); }); test('flags unknown input type', () async { final a = FlowAnalyzer(availableCapabilities: () => const []); final r = await a.analyze(_wrap(''' name: hello inputs: pdf: byes steps: [] outputs: {} ''')); expect(r.issues, hasLength(1)); expect(r.issues.first.message, contains('byes')); expect(r.issues.first.type, IssueType.warning); }); test('YAML parse error pins to the offending line', () async { final a = FlowAnalyzer(availableCapabilities: () => const []); // Unterminated quoted string — a real parse error rather // than a structural oddity YAML happens to tolerate. final r = await a.analyze(_wrap('name: "unterminated\n')); expect(r.issues, hasLength(1)); expect(r.issues.first.type, IssueType.error); expect(r.issues.first.message, startsWith('YAML:')); }); test('matches the bare capability id ignoring @version', () async { final a = FlowAnalyzer( availableCapabilities: () => const ['text.echo'], ); final r = await a.analyze(_wrap(''' name: x steps: - id: e use: text.echo@^2 ''')); expect(r.issues, isEmpty); }); test('empty installed list silences capability checks', () async { // When the host hasn't supplied a list (Studio still // booting, or running in CLI-only mode), we deliberately // don't false-positive every `use:` row. final a = FlowAnalyzer(availableCapabilities: () => const []); final r = await a.analyze(_wrap(''' steps: - id: e use: text.echo@^2 ''')); expect(r.issues, isEmpty); }); }); }