// 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))
library;

import 'dart:async';

import 'package:dwds/src/services/expression_evaluator.dart';
import 'package:dwds_test_common/logging.dart';
import 'package:dwds_test_common/test_sdk_configuration.dart';
import 'package:dwds_test_common/utilities.dart' show dartSdkIsAtLeast;
import 'package:test/test.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,
  bool useDebuggerModuleNames = 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;
  final testPackageProject = TestProject.testPackage(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: provider.verbose);
      await context.setUp(
        testSettings: TestSettings(
          compilationMode: compilationMode,
          moduleFormat: provider.ddcModuleFormat,
          enableExpressionEvaluation: true,
          useDebuggerModuleNames: useDebuggerModuleNames,
          verboseCompiler: provider.verbose,
          canaryFeatures: provider.canaryFeatures,
        ),
      );
    });

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

    setUp(() => setCurrentLogWriter(debug: provider.verbose));

    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(provider.verbose ? 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 (_) {}
      });

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

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

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

      Future<Instance> 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 (final 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('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 (final 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',
          );

          if (dartSdkIsAtLeast('3.10.0-140.0.dev')) {
            expect(result, matchInstanceRefKind('String'));
            expect(
              result,
              matchInstanceRef(contains("NoSuchMethodError: '_field")),
            );
          } else {
            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<void>.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: provider.verbose);
        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 {});

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

      Future<InstanceRef> 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: provider.verbose);
      await context.setUp(
        testSettings: TestSettings(
          compilationMode: compilationMode,
          moduleFormat: provider.ddcModuleFormat,
          enableExpressionEvaluation: false,
          verboseCompiler: provider.verbose,
          canaryFeatures: provider.canaryFeatures,
        ),
      );
    });

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

    setUp(() => setCurrentLogWriter(debug: provider.verbose));

    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 (final 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);
