// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@TestOn('vm')
@Timeout(Duration(minutes: 2))
import 'dart:async';

import 'package:dwds/src/services/expression_evaluator.dart';
import 'package:test/test.dart';
import 'package:test_common/logging.dart';
import 'package:test_common/test_sdk_configuration.dart';
import 'package:vm_service/vm_service.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

import 'fixtures/context.dart';
import 'fixtures/project.dart';
import 'fixtures/utilities.dart';

void testAll({
  required TestSdkConfigurationProvider provider,
  CompilationMode compilationMode = CompilationMode.buildDaemon,
  IndexBaseMode indexBaseMode = IndexBaseMode.noBase,
  NullSafety nullSafety = NullSafety.sound,
  bool useDebuggerModuleNames = false,
  bool debug = false,
}) {
  if (compilationMode == CompilationMode.buildDaemon &&
      indexBaseMode == IndexBaseMode.base) {
    throw StateError(
      'build daemon scenario does not support non-empty base in index file',
    );
  }

  final testProject = TestProject.test(nullSafety: nullSafety);
  final testPackageProject =
      TestProject.testPackage(nullSafety: nullSafety, baseMode: indexBaseMode);

  final context = TestContext(testPackageProject, provider);

  Future<void> onBp(
    Stream<Event> stream,
    String isolate,
    ScriptRef script,
    String breakPointId,
    Future<void> Function(Event event) body,
  ) async {
    Breakpoint? bp;
    try {
      final line =
          await context.findBreakpointLine(breakPointId, isolate, script);
      bp = await context.service
          .addBreakpointWithScriptUri(isolate, script.uri!, line);
      final event = await stream.firstWhere(
        (event) => event.kind == EventKind.kPauseBreakpoint,
      );
      await body(event);
    } finally {
      // Remove breakpoint so it doesn't impact other tests or retries.
      if (bp != null) {
        await context.service.removeBreakpoint(isolate, bp.id!);
      }
    }
  }

  group(
    'Shared context with evaluation |',
    () {
      setUpAll(() async {
        setCurrentLogWriter(debug: debug);
        await context.setUp(
          testSettings: TestSettings(
            compilationMode: compilationMode,
            moduleFormat: provider.ddcModuleFormat,
            enableExpressionEvaluation: true,
            useDebuggerModuleNames: useDebuggerModuleNames,
            verboseCompiler: debug,
          ),
        );
      });

      tearDownAll(() async {
        await context.tearDown();
      });

      setUp(() => setCurrentLogWriter(debug: debug));

      group('evaluateInFrame |', () {
        VM vm;
        late Isolate isolate;
        late String isolateId;
        ScriptList scripts;
        late ScriptRef mainScript;
        late ScriptRef libraryScript;
        late ScriptRef testLibraryScript;
        late ScriptRef testLibraryPartScript;
        late Stream<Event> stream;
        late StreamController<String> output;

        setUp(() async {
          output = StreamController<String>.broadcast();
          output.stream.listen(debug ? print : printOnFailure);

          configureLogWriter(
            customLogWriter: (level, message, {error, loggerName, stackTrace}) {
              final e = error == null ? '' : ': $error';
              final s = stackTrace == null ? '' : ':\n$stackTrace';
              if (!output.isClosed) {
                output.add('[$level] $loggerName: $message$e$s');
              }
            },
          );

          vm = await context.service.getVM();
          isolate = await context.service.getIsolate(vm.isolates!.first.id!);
          isolateId = isolate.id!;
          scripts = await context.service.getScripts(isolateId);

          await context.service.streamListen('Debug');
          stream = context.service.onEvent('Debug');

          final testPackage = testPackageProject.packageName;
          final test = testProject.packageName;
          mainScript = scripts.scripts!
              .firstWhere((each) => each.uri!.contains('main.dart'));
          testLibraryScript = scripts.scripts!.firstWhere(
            (each) =>
                each.uri!.contains('package:$testPackage/test_library.dart'),
          );
          testLibraryPartScript = scripts.scripts!.firstWhere(
            (each) =>
                each.uri!.contains('package:$testPackage/src/test_part.dart'),
          );
          libraryScript = scripts.scripts!.firstWhere(
            (each) => each.uri!.contains('package:$test/library.dart'),
          );
        });

        tearDown(() async {
          await output.close();
          try {
            await context.service.resume(isolateId);
          } catch (_) {}
        });

        onBreakPoint(script, bpId, body) => onBp(
              stream,
              isolateId,
              script,
              bpId,
              body,
            );

        evaluateInFrame(frame, expr, {scope}) async =>
            await context.service.evaluateInFrame(
              isolateId,
              frame,
              expr,
              scope: scope,
            );

        getInstanceRef(frame, expr, {scope}) async {
          final result = await evaluateInFrame(
            frame,
            expr,
            scope: scope,
          );
          expect(result, isA<InstanceRef>());
          return result as InstanceRef;
        }

        getInstance(InstanceRef ref) async =>
            await context.service.getObject(isolateId, ref.id!) as Instance;

        test('with scope', () async {
          await onBreakPoint(mainScript, 'printFrame1', (event) async {
            final frame = event.topFrame!.index!;

            final scope = {
              'x1': (await getInstanceRef(frame, '"cat"')).id!,
              'x2': (await getInstanceRef(frame, '2')).id!,
              'x3': (await getInstanceRef(frame, 'MainClass(1,0)')).id!,
            };

            final result = await getInstanceRef(
              frame,
              '"\$x1\$x2 (\$x3) \$testLibraryValue (\$local1)"',
              scope: scope,
            );

            expect(result, matchInstanceRef('cat2 (1, 0) 3 (1)'));
          });
        });

        test('with large scope', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            const N = 20;
            final frame = event.topFrame!.index!;

            final scope = {
              for (var i = 0; i < N; i++)
                'x$i': (await getInstanceRef(frame, '$i')).id!,
            };
            final expression = [
              for (var i = 0; i < N; i++) '\$x$i',
            ].join(' ');
            final expected = [
              for (var i = 0; i < N; i++) '$i',
            ].join(' ');

            final result = await evaluateInFrame(
              frame,
              '"$expression"',
              scope: scope,
            );
            expect(result, matchInstanceRef(expected));
          });
        });

        test('with large code scope', () async {
          await onBreakPoint(mainScript, 'printLargeScope', (event) async {
            const xN = 2;
            const tN = 20;
            final frame = event.topFrame!.index!;

            final scope = {
              for (var i = 0; i < xN; i++)
                'x$i': (await getInstanceRef(frame, '$i')).id!,
            };
            final expression = [
              for (var i = 0; i < xN; i++) '\$x$i',
              for (var i = 0; i < tN; i++) '\$t$i',
            ].join(' ');
            final expected = [
              for (var i = 0; i < xN; i++) '$i',
              for (var i = 0; i < tN; i++) '$i',
            ].join(' ');

            final result = await evaluateInFrame(
              frame,
              '"$expression"',
              scope: scope,
            );
            expect(result, matchInstanceRef(expected));
          });
        });

        test('with scope in caller frame', () async {
          await onBreakPoint(mainScript, 'printFrame1', (event) async {
            final frame = event.topFrame!.index! + 1;

            final scope = {
              'x1': (await getInstanceRef(frame, '"cat"')).id!,
              'x2': (await getInstanceRef(frame, '2')).id!,
              'x3': (await getInstanceRef(frame, 'MainClass(1,0)')).id!,
            };

            final result = await getInstanceRef(
              frame,
              '"\$x1\$x2 (\$x3) \$testLibraryValue (\$local2)"',
              scope: scope,
            );

            expect(result, matchInstanceRef('cat2 (1, 0) 3 (2)'));
          });
        });

        test('with scope and this', () async {
          await onBreakPoint(mainScript, 'toStringMainClass', (event) async {
            final frame = event.topFrame!.index!;

            final scope = {
              'x1': (await getInstanceRef(frame, '"cat"')).id!,
            };

            final result = await getInstanceRef(
              frame,
              '"\$x1 \${this._field} \${this.field}"',
              scope: scope,
            );

            expect(result, matchInstanceRef('cat 1 2'));
          });
        });

        test(
          'extension method scope variables can be evaluated',
          () async {
            await onBreakPoint(mainScript, 'extension', (event) async {
              final stack = await context.service.getStack(isolateId);
              final scope = _getFrameVariables(stack.frames!.first);
              for (var p in scope.entries) {
                final name = p.key;
                final value = p.value as InstanceRef;
                final result =
                    await getInstanceRef(event.topFrame!.index!, name!);

                expect(result, matchInstanceRef(value.valueAsString));
              }
            });
          },
          skip: 'https://github.com/dart-lang/webdev/issues/1371',
        );

        test('uses correct null safety mode', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final isNullSafetyEnabledExpression =
                '() { const sound = !(<Null>[] is List<int>); return sound; } ()';
            final result = await getInstanceRef(
              event.topFrame!.index!,
              isNullSafetyEnabledExpression,
            );
            final expectedResult = '${nullSafety == NullSafety.sound}';
            expect(result, matchInstanceRef(expectedResult));
          });
        });

        test('does not crash if class metadata cannot be found', () async {
          await onBreakPoint(mainScript, 'printStream', (event) async {
            final instanceRef =
                await getInstanceRef(event.topFrame!.index!, 'stream');
            final instance = await getInstance(instanceRef);

            expect(instance, matchInstanceClassName('_AsBroadcastStream<int>'));
          });
        });

        test('local', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'local',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('Type does not show native JavaScript object fields', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final instanceRef =
                await getInstanceRef(event.topFrame!.index!, 'Type');

            // Type
            final instance = await getInstance(instanceRef);
            for (var field in instance.fields!) {
              final name = field.decl!.name;
              final fieldInstance =
                  await getInstance(field.value as InstanceRef);

              expect(
                fieldInstance,
                isA<Instance>().having(
                  (i) => i.classRef!.name,
                  'Type.$name: classRef.name',
                  isNot(
                    isIn([
                      'NativeJavaScriptObject',
                      'JavaScriptObject',
                    ]),
                  ),
                ),
              );
            }
          });
        });

        test('field', () async {
          await onBreakPoint(mainScript, 'printFieldFromLibraryClass',
              (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'instance.field',
            );

            expect(result, matchInstanceRef('1'));
          });
        });

        test('private field from another library', () async {
          await onBreakPoint(mainScript, 'printFieldFromLibraryClass',
              (event) async {
            final result = await evaluateInFrame(
              event.topFrame!.index!,
              'instance._field',
            );

            expect(
              result,
              matchErrorRef(contains("The getter '_field' isn't defined")),
            );
          });
        });

        test('private field from current library', () async {
          await onBreakPoint(mainScript, 'printFieldMain', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'instance._field',
            );

            expect(result, matchInstanceRef('1'));
          });
        });

        test('access instance fields after evaluation', () async {
          await onBreakPoint(mainScript, 'printFieldFromLibraryClass',
              (event) async {
            final instanceRef = await getInstanceRef(
              event.topFrame!.index!,
              'instance',
            );

            final instance = await getInstance(instanceRef);
            final field = instance.fields!.firstWhere(
              (BoundField element) => element.decl!.name == 'field',
            );

            expect(field.value, matchInstanceRef('1'));
          });
        });

        test('global', () async {
          await onBreakPoint(mainScript, 'printGlobal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryValue',
            );

            expect(result, matchInstanceRef('3'));
          });
        });

        test('call core function', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'print(local)',
            );

            expect(result, matchInstanceRef('null'));
          });
        });

        test('call library function with const param', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryFunction(42)',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('call library function with local param', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryFunction(local)',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('call library part function with const param', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryPartFunction(42)',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('call library part function with local param', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'testLibraryPartFunction(local)',
            );

            expect(result, matchInstanceRef('42'));
          });
        });

        test('loop variable', () async {
          await onBreakPoint(mainScript, 'printLoopVariable', (event) async {
            final result = await getInstanceRef(event.topFrame!.index!, 'item');

            expect(result, matchInstanceRef('1'));
          });
        });

        test('evaluate expression in _test_package/test_library', () async {
          await onBreakPoint(testLibraryScript, 'testLibraryFunction',
              (event) async {
            final result =
                await getInstanceRef(event.topFrame!.index!, 'formal');

            expect(result, matchInstanceRef('23'));
          });
        });

        test('evaluate expression in a class constructor in a library',
            () async {
          await onBreakPoint(testLibraryScript, 'testLibraryClassConstructor',
              (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'this.field',
            );

            expect(result, matchInstanceRef('1'));
          });
        });

        test('evaluate expression in a class constructor in a library part',
            () async {
          await onBreakPoint(
              testLibraryPartScript, 'testLibraryPartClassConstructor',
              (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index!,
              'this.field',
            );

            expect(result, matchInstanceRef('1'));
          });
        });

        test('evaluate expression in caller frame', () async {
          await onBreakPoint(testLibraryScript, 'testLibraryFunction',
              (event) async {
            final result = await getInstanceRef(
              event.topFrame!.index! + 1,
              'local',
            );

            expect(result, matchInstanceRef('23'));
          });
        });

        test('evaluate expression in a library', () async {
          await onBreakPoint(libraryScript, 'Concatenate', (event) async {
            final result = await getInstanceRef(event.topFrame!.index!, 'a');

            expect(result, matchInstanceRef('Hello'));
          });
        });

        test('compilation error', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            final error = await evaluateInFrame(event.topFrame!.index!, 'typo');

            expect(
              error,
              matchErrorRef(contains(EvaluationErrorKind.compilation)),
            );
          });
        });

        test('async frame error', () async {
          final maxAttempts = 100;

          Response? error;
          String? breakpointId;
          try {
            // Pause in client.js directly to force pausing in async code.
            breakpointId = await _setBreakpointInInjectedClient(
              context.tabConnection.debugger,
            );

            var attempt = 0;
            do {
              try {
                await context.service.resume(isolateId);
              } catch (_) {}

              final event = stream.firstWhere(
                (event) => event.kind == EventKind.kPauseInterrupted,
              );
              final frame = (await event).topFrame;
              if (frame != null) {
                error = await context.service.evaluateInFrame(
                  isolateId,
                  frame.index!,
                  'true',
                );
              }
              expect(
                attempt,
                lessThan(maxAttempts),
                reason:
                    'Failed to receive and async frame error in $attempt attempts',
              );
              await (Future.delayed(const Duration(milliseconds: 10)));
              attempt++;
            } while (error is! ErrorRef);
          } finally {
            if (breakpointId != null) {
              await context.tabConnection.debugger
                  .removeBreakpoint(breakpointId);
            }
          }

          // Verify we receive an error when evaluating
          // on async frame.
          expect(
            error,
            matchErrorRef(contains(EvaluationErrorKind.asyncFrame)),
          );

          // Verify we don't emit errors or warnings
          // on async frame evaluations.
          output.stream.listen((event) {
            expect(event, isNot(contains('[WARNING]')));
            expect(event, isNot(contains('[SEVERE]')));
          });
        });

        test(
          'module load error',
          () async {
            await onBreakPoint(mainScript, 'printLocal', (event) async {
              final error = await evaluateInFrame(
                event.topFrame!.index!,
                'd.deferredPrintLocal()',
              );

              expect(
                error,
                matchErrorRef(contains(EvaluationErrorKind.loadModule)),
              );
            });
          },
          skip: 'https://github.com/dart-lang/sdk/issues/48587',
        );

        test('cannot evaluate in unsupported isolate', () async {
          await onBreakPoint(mainScript, 'printLocal', (event) async {
            await expectLater(
              context.service
                  .evaluateInFrame('bad', event.topFrame!.index!, 'local'),
              throwsSentinelException,
            );
          });
        });
      });

      group('evaluate |', () {
        VM vm;
        late Isolate isolate;
        late String isolateId;

        setUp(() async {
          setCurrentLogWriter(debug: debug);
          final service = context.service;
          vm = await service.getVM();
          isolate = await service.getIsolate(vm.isolates!.first.id!);
          isolateId = isolate.id!;

          await service.streamListen('Debug');
        });

        tearDown(() async {});

        evaluate(
          targetId,
          expr, {
          scope,
        }) async =>
            await context.service.evaluate(
              isolateId,
              targetId,
              expr,
              scope: scope,
            );

        getInstanceRef(
          targetId,
          expr, {
          scope,
        }) async {
          final result = await evaluate(
            targetId,
            expr,
            scope: scope,
          );
          expect(result, isA<InstanceRef>());
          return result as InstanceRef;
        }

        String getRootLibraryId() {
          expect(isolate.rootLib, isNotNull);
          expect(isolate.rootLib!.id, isNotNull);
          return isolate.rootLib!.id!;
        }

        test(
          'RecordType getters',
          () async {
            final libraryId = getRootLibraryId();

            final type = await getInstanceRef(libraryId, '(0,1).runtimeType');
            final result = await getInstanceRef(type.id, 'hashCode');

            expect(result, matchInstanceRefKind('Double'));
          },
          skip: 'https://github.com/dart-lang/sdk/issues/54609',
        );

        test('Object getters', () async {
          final libraryId = getRootLibraryId();

          final type = await getInstanceRef(libraryId, 'Object()');
          final result = await getInstanceRef(type.id, 'hashCode');

          expect(result, matchInstanceRefKind('Double'));
        });

        test('with scope', () async {
          final libraryId = getRootLibraryId();

          final scope = {
            'x1': (await getInstanceRef(libraryId, '"cat"')).id!,
            'x2': (await getInstanceRef(libraryId, '2')).id!,
            'x3': (await getInstanceRef(libraryId, 'MainClass(1,0)')).id!,
          };

          final result = await getInstanceRef(
            libraryId,
            '"\$x1\$x2 (\$x3) \$testLibraryValue"',
            scope: scope,
          );

          expect(result, matchInstanceRef('cat2 (1, 0) 3'));
        });

        test('with large scope', () async {
          final libraryId = getRootLibraryId();
          const N = 2;

          final scope = {
            for (var i = 0; i < N; i++)
              'x$i': (await getInstanceRef(libraryId, '$i')).id!,
          };
          final expression = [
            for (var i = 0; i < N; i++) '\$x$i',
          ].join(' ');
          final expected = [
            for (var i = 0; i < N; i++) '$i',
          ].join(' ');

          final result = await getInstanceRef(
            libraryId,
            '"$expression"',
            scope: scope,
          );
          expect(result, matchInstanceRef(expected));
        });

        test('in parallel (in a batch)', () async {
          final libraryId = getRootLibraryId();

          final evaluation1 =
              getInstanceRef(libraryId, 'MainClass(1,0).toString()');
          final evaluation2 =
              getInstanceRef(libraryId, 'MainClass(1,1).toString()');

          final results = await Future.wait([evaluation1, evaluation2]);
          expect(results[0], matchInstanceRef('1, 0'));
          expect(results[1], matchInstanceRef('1, 1'));
        });

        test('in parallel (in a batch) handles errors', () async {
          final libraryId = getRootLibraryId();
          final missingLibId = '';

          final evaluation1 =
              evaluate(missingLibId, 'MainClass(1,0).toString()');
          final evaluation2 = evaluate(libraryId, 'MainClass(1,1).toString()');

          final results = await Future.wait([evaluation1, evaluation2]);
          expect(
            results[0],
            matchErrorRef(
              contains('Evaluate is called on an unsupported target'),
            ),
          );
          expect(results[1], matchInstanceRef('1, 1'));
        });

        test('with scope override', () async {
          final libraryId = getRootLibraryId();

          final param = await getInstanceRef(libraryId, 'MainClass(1,0)');
          final result = await getInstanceRef(
            libraryId,
            't.toString()',
            scope: {'t': param.id!},
          );

          expect(result, matchInstanceRef('1, 0'));
        });

        test('uses symbol from the same library', () async {
          final libraryId = getRootLibraryId();

          final result =
              await getInstanceRef(libraryId, 'MainClass(1,0).toString()');

          expect(result, matchInstanceRef('1, 0'));
        });

        test('uses symbol from another library', () async {
          final libraryId = getRootLibraryId();
          final result = await getInstanceRef(
            libraryId,
            'TestLibraryClass(0,1).toString()',
          );

          expect(result, matchInstanceRef('field: 0, _field: 1'));
        });

        test('closure call', () async {
          final libraryId = getRootLibraryId();
          final result = await getInstanceRef(libraryId, '(() => 42)()');

          expect(result, matchInstanceRef('42'));
        });
      });
    },
    timeout: const Timeout.factor(2),
  );

  group('shared context with no evaluation |', () {
    setUpAll(() async {
      setCurrentLogWriter(debug: debug);
      await context.setUp(
        testSettings: TestSettings(
          compilationMode: compilationMode,
          moduleFormat: provider.ddcModuleFormat,
          enableExpressionEvaluation: false,
          verboseCompiler: debug,
        ),
      );
    });

    tearDownAll(() async {
      await context.tearDown();
    });

    setUp(() => setCurrentLogWriter(debug: debug));

    group('evaluateInFrame |', () {
      VM vm;
      late Isolate isolate;
      late String isolateId;
      ScriptList scripts;
      late ScriptRef mainScript;
      late Stream<Event> stream;

      setUp(() async {
        final service = context.service;
        vm = await service.getVM();
        isolate = await service.getIsolate(vm.isolates!.first.id!);
        isolateId = isolate.id!;
        scripts = await service.getScripts(isolateId);

        await service.streamListen('Debug');
        stream = service.onEvent('Debug');

        mainScript = scripts.scripts!
            .firstWhere((each) => each.uri!.contains('main.dart'));
      });

      tearDown(() async {
        await context.service.resume(isolateId);
      });

      test('cannot evaluate expression', () async {
        await onBp(stream, isolateId, mainScript, 'printLocal', (event) async {
          await expectLater(
            context.service
                .evaluateInFrame(isolateId, event.topFrame!.index!, 'local'),
            throwsRPCError,
          );
        });
      });
    });
  });
}

Map<String?, InstanceRef?> _getFrameVariables(Frame frame) {
  return <String?, InstanceRef?>{
    for (var variable in frame.vars!)
      variable.name: variable.value as InstanceRef?,
  };
}

Future<String> _setBreakpointInInjectedClient(WipDebugger debugger) async {
  final client = 'dwds/src/injected/client.js';
  final clientScript =
      debugger.scripts.values.firstWhere((e) => e.url.contains(client));
  final clientSource = await debugger.getScriptSource(clientScript.scriptId);

  final line = clientSource.split('\n').indexWhere(
        (element) => element.contains('convertDartClosureToJS'),
      );

  final result = await debugger.sendCommand(
    'Debugger.setBreakpointByUrl',
    params: {
      'urlRegex': '.*$client',
      'lineNumber': line + 4,
      'columnNumber': 0,
    },
  );
  return result.json['result']['breakpointId'];
}

Matcher matchInstanceRefKind(String kind) =>
    isA<InstanceRef>().having((instance) => instance.kind, 'kind', kind);

Matcher matchInstanceRef(dynamic value) => isA<InstanceRef>()
    .having((instance) => instance.valueAsString, 'valueAsString', value);

Matcher matchInstanceClassName(dynamic className) => isA<Instance>().having(
      (instance) => instance.classRef!.name,
      'class name',
      className,
    );

Matcher matchInstanceRefClassName(dynamic className) =>
    isA<InstanceRef>().having(
      (instance) => instance.classRef!.name,
      'class name',
      className,
    );

Matcher matchErrorRef(dynamic message) => isA<ErrorRef>().having(
      (instance) => instance.message,
      'message',
      message,
    );
