content: import 'package:test/test.dart';
  import 'package:d4rt/d4rt.dart';
  
  Matcher throwsRuntimeError(dynamic messageMatcher) {
    return throwsA(
        isA<RuntimeError>().having((e) => e.message, 'message', messageMatcher));
  }
  
  dynamic execute(String source, {Object? args}) {
    final d4rt = D4rt()..setDebug(false);
    return d4rt.execute(
        library: 'package:test/main.dart',
        args: args,
        sources: {'package:test/main.dart': source});
  }
  
  // Async version that awaits Future results for complex await tests
  Future<dynamic> executeAsync(String source, {Object? args}) async {
    final d4rt = D4rt()..setDebug(false);
    final result = d4rt.execute(
        library: 'package:test/main.dart',
        args: args,
        sources: {'package:test/main.dart': source});
  
    // If the result is a Future, await it
    if (result is Future) {
      return await result;
    }
    return result;
  }
  
  void main() {
    group('Basic Interpreter', () {
      test('Variable declaration and retrieval', () {
        final source = '''
          main() {
            var x = 10;
            return x;
          }
        ''';
        expect(execute(source), equals(10));
      });
  
      test('Variable assignment', () {
        final source = '''
          main() {
            var y = 5;
            y = 20;
            return y;
          }
        ''';
        expect(execute(source), equals(20));
      });
  
      test('Simple binary expression', () {
        // Note: Top-level var declaration is handled before main
        final source = '''
          var z = 10 + 5 * 2; 
          main() {
             return z;
          }
        ''';
        expect(execute(source), equals(20));
      });
  
      test('Variable usage in expression', () {
        final source = '''
          main() {
            var a = 7;
            var b = 3;
            return a - b;
          }
        ''';
        expect(execute(source), equals(4));
      });
  
      test('Null handling', () {
        final source = '''
          main() {
            var n = null; 
            return n;
          }
        ''';
        expect(execute(source), isNull);
      });
  
      test('Null assignment', () {
        final source = '''
          main() {
            var val = 100;
            val = null;
            return val;
          }
        ''';
        expect(execute(source), isNull);
      });
  
      test('Undefined variable (get)', () {
        final code = '''
         main() {
             var x = nonDefini;
          }
        ''';
        // expect(execute(code), isA<RuntimeError>());
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains('Undefined variable: nonDefini'),
            )));
      });
  
      test('Undefined variable (assign)', () {
        final code = '''
         main() {
             nonDefini = 5;
          }
        ''';
        // expect(execute(code), isA<RuntimeError>());
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains("Assigning to undefined variable 'nonDefini'"),
            )));
      });
  
      test('String concatenation', () {
        final source = '''
          main() {
            var debut = "Bonjour";
            var fin = " monde";
            return debut + fin;
          }
        ''';
        expect(execute(source), equals('Bonjour monde'));
      });
  
      test('Main function with arguments', () {
        final source = '''
          main(List<String> args) {
            return args.length.toString() + ":" + args[0];
          }
        ''';
        final result = execute(
          source,
          args: ['arg1', 'test', 'more'], // Pass arguments
        );
        expect(result, equals('3:arg1')); // Length 3, first argument 'arg1'
      });
  
      test('Main function without arguments called with args (should throw)', () {
        final source = '''
          main() { // Ne prend pas d'arguments
            return 10;
          }
        ''';
        expect(
          () => execute(
            source,
            args: ['fail'], // Passer des arguments quand même
          ),
          throwsRuntimeError(
              contains("'main' function does not accept arguments")),
        );
      });
  
      test(
          'Main function with arguments called without args (should pass empty list)',
          () {
        final source = '''
          main(List<String> args) { // Prend des arguments
            return args.length; // Doit être 0
          }
        ''';
        final result = execute(source);
        expect(result, equals(0));
      });
    });
  
    group('Gestion des portées (Scopes)', () {
      test('Variable interne au bloc non accessible à l\'extérieur', () {
        final code = '''
         main() {
            {
              var a = 10;
            }
            print(a);
          }
        ''';
        // expect(execute(code), isA<RuntimeError>());
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains('Undefined variable: a'),
            )));
      });
  
      test('Variable interne masque variable externe', () {
        final source = '''
          var x = "outer";
          main() {
            {
              var x = "inner";
              return x; // Should return "inner"
            }
            // This return won't be reached if inner block returns
          }
        ''';
        expect(execute(source), equals('inner'));
      });
  
      test('Le bloc interne retourne la valeur correcte (via var)', () {
        final source = '''
          main() {
             var x = "outer";
             var blockResult;
             {
               var y = "inner";
               blockResult = y; // Assign to check
             }
             return blockResult; // Return the assigned variable
          }
        ''';
        expect(execute(source), equals("inner"));
      });
  
      test('Accès à variable externe depuis bloc interne', () {
        final source = '''
          var outer = 100;
          main() {
             var inner;
             {
               inner = outer + 5;
             }
             return inner;
          }
        ''';
        expect(execute(source), equals(105));
      });
    });
  
    group('Control Flow - If Statements', () {
      test('if (true) executes then branch', () {
        final source = '''
          main() {
            if (true) {
              return 1;
            } else {
              return 0;
            }
          }
        ''';
        expect(execute(source), equals(1));
      });
  
      test('if (false) executes else branch', () {
        final source = '''
          main() {
            if (false) {
              return 1;
            } else {
              return 0;
            }
          }
        ''';
        expect(execute(source), equals(0));
      });
  
      test('if with expression condition (true)', () {
        final source = '''
          main() {
            var x = 10;
            if (x > 5) {
              return "oui";
            }
            return "non"; // Should not be reached
          }
        ''';
        expect(execute(source), equals("oui"));
      });
  
      test('if with expression condition (false)', () {
        final source = '''
          main() {
            var x = 3;
            if (x > 5) {
               return "oui";
            } else {
               return "non";
            }
          }
        ''';
        expect(execute(source), equals("non"));
      });
  
      test('if without else (condition true)', () {
        final source = '''
          main() {
            var x = 1;
            if (true) {
               x = 2;
            }
            return x;
          }
        ''';
        expect(execute(source), equals(2));
      });
  
      test('if without else (condition false)', () {
        final source = '''
          main() {
            var x = 1;
            if (false) {
               x = 2;
            }
            return x;
          }
        ''';
        expect(execute(source), equals(1));
      });
  
      test('if condition must be boolean', () {
        final code = '''
         main() {
            if (1) { print("oops"); }
          }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  "The condition of an 'if' must be a boolean, but was int."),
            )));
      });
    });
  
    group('Control Flow - While Loops', () {
      test('simple while loop', () {
        final source = '''
          main() {
            var i = 0;
            var sum = 0;
            while (i < 3) {
              sum = sum + i;
              i = i + 1;
            }
            return sum; // 0 + 1 + 2 = 3
          }
        ''';
        expect(execute(source), equals(3));
      });
  
      test('while loop condition evaluated each time', () {
        final source = '''
          main() {
            var i = 0;
            while (i < 1) {
              i = i + 1;
            }
            return i; // Should be 1
          }
        ''';
        expect(execute(source), equals(1));
      });
  
      test('while loop condition starting false', () {
        final source = '''
          main() {
            var executed = false;
            while (false) {
               executed = true;
            }
            return executed;
          }
        ''';
        expect(execute(source), equals(false));
      });
  
      test('while condition must be boolean', () {
        final code = '''
         main() {
            while (1) { print("oops"); }
          }
        ''';
        // expect(execute(code), isA<RuntimeError>());
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  "The condition of a 'while' loop must be a boolean, but was int."),
            )));
      });
    });
  
    group('Control Flow - Do-While Loops', () {
      test('simple do-while loop executes at least once', () {
        final source = '''
          main() {
            var i = 5;
            var executed = false;
            do {
              executed = true;
              i = i + 1;
            } while (i < 3); // Condition is initially false
            return executed;
          }
        ''';
        expect(execute(source), equals(true));
      });
  
      test('do-while loop condition checking', () {
        final source = '''
          main() {
            var i = 0;
            var sum = 0;
            do {
              sum = sum + i;
              i = i + 1;
            } while (i < 3);
            return sum; // 0 + 1 + 2 = 3
          }
        ''';
        expect(execute(source), equals(3));
      });
  
      test('do-while condition must be boolean', () {
        final code = '''
         main() {
            do { print("hello"); } while (null);
          }
        ''';
        // expect(execute(code), isA<RuntimeError>());
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  "The condition of a 'do-while' loop must be a boolean, but was null."),
            )));
      });
    });
  
    // ==============================================
    // Classes and Instances Tests
    // ==============================================
    group('Classes and Instances', () {
      test('Simple class declaration and instantiation', () {
        final code = '''
          class Bag {}
          main() {
            var bag = Bag();
            return bag; // Return the instance
          }
        ''';
        final result = execute(code);
        expect(result, isA<InterpretedInstance>());
        expect((result as InterpretedInstance).klass.name, equals('Bag'));
      });
  
      test('Instance field access and assignment', () {
        final code = '''
          class Box {}
          main() {
            var box = Box();
            box.value = 123;
            return box.value;
          }
        ''';
        expect(execute(code), equals(123));
      });
  
      test('Direct field initializer', () {
        final code = '''
          class Thing {
            var x = 10;
          }
          main() {
            var thing = Thing();
            return thing.x;
          }
        ''';
        expect(execute(code), equals(10));
      });
  
      test('Another direct field initializer (string)', () {
        final code = '''
          class Stuff {
            var name = "hello";
          }
          main() {
            var stuff = Stuff();
            return stuff.name;
          }
        ''';
        expect(execute(code), equals("hello"));
      });
  
      test('Constructor with parameter and this.field initializer', () {
        final code = '''
          class Points {
            var x;
            Points(val) : this.x = val {}
          }
          main() {
            var p = Points(5);
            return p.x;
          }
        ''';
        expect(execute(code), equals(5));
      });
  
      test('Simple method call', () {
        final code = '''
          class Greeter {
            greet() { return "hello"; }
          }
          main() {
            var g = Greeter();
            return g.greet();
          }
        ''';
        expect(execute(code), equals("hello"));
      });
  
      test('Method using this to access/modify field', () {
        final code = '''
          class Counter {
            var count = 0;
            inc() { 
              this.count = this.count + 1; 
              return this.count;
            }
            getCount() { return this.count; }
          }
          main() {
            var c = Counter();
            c.inc(); 
            c.inc(); 
            return c.getCount();
          }
        ''';
        expect(execute(code), equals(2));
      });
  
      test('Method using this (verify return value of mutating method)', () {
        final code = '''
          class Counter {
            var count = 0;
            inc() { 
              this.count = this.count + 1; 
              return this.count;
            }
          }
          main() {
            var c = Counter();
            c.inc(); 
            return c.inc(); // This call should return 2
          }
        ''';
        expect(execute(code), equals(2));
      });
  
      test('Constructor initializer calculating value using this', () {
        final code = '''
          class Rect {
            var w, h, area;
            Rect(width, height) : 
              this.w = width, 
              this.h = height, 
              this.area = this.w * this.h 
            {}
          }
          main() {
            var r = Rect(4, 5);
            return r.area;
          }
        ''';
        expect(execute(code), equals(20));
      });
  
      // NEW subgroup for static members
      group('Static Members', () {
        test('Access initialized static field', () {
          final code = '''
            class Config {
              static var url = "http://example.com";
            }
            main() {
              return Config.url;
            }
          ''';
          expect(execute(code), equals("http://example.com"));
        });
  
        test('Assign and read static field', () {
          final code = '''
            class AppState {
              static var counter = 0;
            }
            main() {
              AppState.counter = 15;
              return AppState.counter;
            }
          ''';
          expect(execute(code), equals(15));
        });
  
        test('Call simple static method', () {
          final code = '''
            class Utils {
              static String identity(String s) {
                return s;
              }
            }
            main() {
              return Utils.identity("test");
            }
          ''';
          expect(execute(code), equals("test"));
        });
  
        test('Static method accesses static field', () {
          final code = '''
            class Logger {
              static var level = "INFO";
              static String getLevel() {
                return Logger.level; // Access static field via class name
              }
              static void setLevel(String newLevel) {
                 Logger.level = newLevel;
              }
            }
            main() {
              Logger.setLevel("DEBUG");
              return Logger.getLevel();
            }
          ''';
          expect(execute(code), equals("DEBUG"));
        });
      }); // End Static Members group
  
      // NEW subgroup for Getters and Setters
      group('Getters and Setters', () {
        test('Simple instance getter', () {
          final code = '''
            class Circle {
              var radius = 5;
              // Getter for diameter
              get diameter { 
                return this.radius * 2; 
              }
            }
            main() {
              var c = Circle();
              return c.diameter; // Access the getter
            }
          ''';
          expect(execute(code), equals(10));
        });
  
        test('Simple instance setter', () {
          final code = '''
            class Square {
              var _side = 0; // Simulate private field
              get side { return this._side; }
              // Setter for side
              set side(val) { 
                if (val < 0) {
                   // Basic validation example
                   this._side = 0; 
                } else {
                   this._side = val;
                }
              }
            }
            main() {
              var s = Square();
              s.side = 10; // Use the setter
              return s.side; // Use the getter to check
            }
          ''';
          expect(execute(code), equals(10));
        });
  
        test('Instance setter with validation', () {
          final code = '''
            class Square {
              var _side = 0; 
              get side { return this._side; }
              set side(val) { 
                this._side = val < 0 ? 0 : val;
              }
            }
            main() {
              var s = Square();
              s.side = -5; // Setter should clamp to 0
              return s.side;
            }
          ''';
          expect(execute(code), equals(0));
        });
  
        test('Simple static getter', () {
          final code = '''
            class AppConfig {
              static var _baseUrl = "init";
              static get baseUrl { return AppConfig._baseUrl; }
            }
            main() {
               AppConfig._baseUrl = "prod"; // Set directly for test
               return AppConfig.baseUrl; // Access static getter
            }
          ''';
          expect(execute(code), equals("prod"));
        });
  
        test('Simple static setter', () {
          final code = '''
            class Service {
               static var _status = "stopped";
               static get status { return Service._status; }
               static set status(newStatus) {
                  // Only allow specific statuses
                  if (newStatus == "running" || newStatus == "stopped") {
                     Service._status = newStatus;
                  }
               }
            }
            main() {
              Service.status = "running";
              var s1 = Service.status;
              Service.status = "invalid"; // Should be ignored by setter
              var s2 = Service.status; 
              return [s1, s2];
            }
          ''';
          expect(execute(code), equals(["running", "running"]));
        });
      }); // End Getters and Setters group
  
      group('Named Constructors', () {
        test('Simple named constructor', () {
          final code = '''
            class Points {
              num x, y;
              Points(this.x, this.y);
              Points.origin() {
                x = 0;
                y = 0;
              }
            }
            main() {
              var p = Points.origin();
              return [p.x, p.y];
            }
          ''';
          expect(execute(code), equals([0, 0]));
        });
  
        test('Named constructor with parameters', () {
          final code = '''
            class Rect {
              num left, top, width, height;
              Rect(this.left, this.top, this.width, this.height);
              Rect.square(num size, {num x = 0, num y = 0}) {
                left = x;
                top = y;
                width = size;
                height = size;
              }
            }
            main() {
              var r = Rect.square(10, y: 5);
              return [r.left, r.top, r.width, r.height];
            }
          ''';
          expect(execute(code), equals([0, 5, 10, 10]));
        });
  
        test('Named constructor using this.field initializer', () {
          final code = '''
            class Color {
              int red, green, blue;
              Color(this.red, this.green, this.blue);
              Color.grey(int shade) : red = shade, green = shade, blue = shade;
            }
            main() {
               var c = Color.grey(128);
               return [c.red, c.green, c.blue];
            }
          ''';
          expect(execute(code), equals([128, 128, 128]));
        });
  
        test('Calling non-existent named constructor throws error', () {
          final code = '''
            class Foo { Foo(); }
           main() { var f = Foo.bar(); }
          ''';
          // expect(execute(code), isA<RuntimeError>());
          expect(
              () => execute(code),
              throwsA(isA<RuntimeError>().having(
                (e) => e.message,
                'message',
                contains(
                    "Class 'Foo' has no static method or named constructor named 'bar'."),
              )));
        });
      }); // End Named Constructors group
  
      group('Inheritance', () {
        test('Simple inheritance - access inherited field', () {
          final code = '''
            class Animal {
              var name = "Generic";
            }
            class Dog extends Animal {}
            main() {
              var d = Dog();
              return d.name; // Access field from Animal
            }
          ''';
          expect(execute(code), equals("Generic"));
        });
  
        test('Simple inheritance - access inherited method', () {
          final code = '''
            class Vehicle {
              String start() { return "Vroom"; }
            }
            class Car extends Vehicle {}
            main() {
               var c = Car();
               return c.start(); // Call method from Vehicle
            }
          ''';
          expect(execute(code), equals("Vroom"));
        });
  
        test('Overriding method', () {
          final code = '''
            class Bird {
              String fly() { return "Flap flap"; }
            }
            class Penguin extends Bird {
               @override // Annotation ignored by interpreter, just for clarity
               String fly() { return "Waddle waddle"; }
            }
            main() {
              var p = Penguin();
              return p.fly(); // Should call Penguin's version
            }
          ''';
          expect(execute(code), equals("Waddle waddle"));
        });
  
        test('Accessing overridden method via base type reference (polymorphism)',
            () {
          final code = '''
            class Shape {
              String draw() { return "Drawing shape"; }
            }
            class Circle extends Shape {
               @override
               String draw() { return "Drawing circle"; }
            }
            main() {
              Shape myShape = Circle(); // Assign subclass to base class variable
              return myShape.draw(); // Should call Circle's draw() due to runtime type
            }
          ''';
          expect(execute(code), equals("Drawing circle"));
        });
  
        test('Inherited field initialization', () {
          final code = '''
            class Base {
               var a = 1;
            }
            class Derived extends Base {
               var b = 2;
            }
            main() {
              var obj = Derived();
              return [obj.a, obj.b]; // Both fields should be initialized
            }
          ''';
          expect(execute(code), equals([1, 2]));
        });
  
        test('Inheritance chain', () {
          final code = '''
            class A { String getA() { return "A"; } }
            class B extends A { String getB() { return "B"; } }
            class C extends B { String getC() { return "C"; } }
            main() {
              var c = C();
              return c.getA() + c.getB() + c.getC();
            }
          ''';
          expect(execute(code), equals("ABC"));
        });
  
        test('Extending undefined class throws error', () {
          final code = '''
             class Bad extends NonExistent {}
            main() {}
           ''';
  
          expect(
              () => execute(code),
              throwsA(isA<RuntimeError>().having(
                (e) => e.message,
                'message',
                contains("Superclass 'NonExistent' not found for class 'Bad'."),
              )));
        });
      }); // End Inheritance group
  
      group('Super Calls', () {
        test('super method call', () {
          final code = '''
            class Parent {
              String greet() { return "Hello from Parent"; }
            }
            class Child extends Parent {
              @override
              String greet() { 
                var parentGreeting = super.greet();
                return "Child says: " + parentGreeting;
              }
            }
            main() {
              var c = Child();
              return c.greet();
            }
          ''';
          expect(execute(code), equals("Child says: Hello from Parent"));
        });
  
        test('super getter call', () {
          final code = '''
            class Base {
              int _x = 10;
              int get x => _x;
            }
            class Derived extends Base {
              int get x => super.x * 2;
            }
            main() {
              var d = Derived();
              return d.x;
            }
          ''';
          expect(execute(code), equals(20));
        });
  
        test('super setter call (implicit via assignment)', () {
          final code = '''
            class Base { 
              int _val = 0;
              int get value => _val;
              set value(int v) { _val = v > 10 ? 10 : v; } // Clamp at 10
            }
            class Derived extends Base {
              set value(int v) {
                 // Apply different clamping, then call super setter
                 super.value = v > 5 ? 5 : v;
              }
            }
            main() {
              var d = Derived();
              d.value = 15; // Should be clamped to 5 by Derived, then passed to Base (still 5)
              var v1 = d.value;
              d.value = 3;
              var v2 = d.value;
              return [v1, v2];
            }
          ''';
          expect(execute(code), equals([5, 3]));
        });
  
        test('super call on method defined in grandparent', () {
          final code = '''
            class Grandparent { String identify() => "G"; }
            class Parent extends Grandparent { /* No identify */ }
            class Child extends Parent { 
               String identify() => "C->" + super.identify(); 
            }
            main() {
              return Child().identify();
            }
          ''';
          expect(execute(code), equals("C->G"));
        });
  
        test('super used outside instance method fails', () {
          final code = '''
           main() { print(super.toString()); }
          ''';
          // expect(execute(code), isA<RuntimeError>());
          expect(
              () => execute(code),
              throwsA(isA<RuntimeError>().having(
                (e) => e.message,
                'message',
                contains("'super' can only be used within an instance method."),
              )));
        });
      }); // End Super Calls group
  
      group('Super Constructor Calls', () {
        test('Implicit super() call', () {
          final code = '''
            class Parent {
               var initialized = false;
               Parent() { initialized = true; }
            }
            class Child extends Parent {
              Child(); // Implicit super()
            }
            main() {
               var c = Child();
               return c.initialized;
            }
          ''';
          expect(execute(code), isTrue);
        });
  
        test('Explicit super() call with arguments', () {
          final code = '''
            class Parent {
              var x, y;
              Parent(this.x, this.y);
            }
            class Child extends Parent {
              Child(int a, int b) : super(a * 2, b + 1);
            }
            main() {
              var c = Child(10, 5);
              return [c.x, c.y];
            }
          ''';
          expect(execute(code), equals([20, 6]));
        });
  
        test('Explicit super.named() call', () {
          final code = '''
            class Parent {
              var name;
              Parent() : name = "Default";
              Parent.fromName(this.name);
            }
            class Child extends Parent {
               Child.fromParentName(String n) : super.fromName(n + " Child");
            }
            main() {
              var c = Child.fromParentName("Test");
              return c.name;
            }
          ''';
          expect(execute(code), equals("Test Child"));
        });
  
        test('Field initializer runs before super constructor call', () {
          final code = '''
            var log = [];
            class Parent {
               // Use a fixed string or accessible var if needed for verification
               Parent(arg) { log.add("Parent constructor: \$arg"); }
            }
            class Child extends Parent {
               var field = initField(); 
               // Pass the known value (123) or a literal to super()
               Child() : super("Value was 123") { 
                  log.add("Child constructor"); 
               }
               initField() { 
                  log.add("Child field init"); 
                  return 123; 
               }
            }
            main() {
              log.clear();
              Child();
              return log;
            }
          ''';
          // Expected order: Child field init -> Parent constructor -> Child constructor
          expect(
              execute(code),
              equals([
                "Child field init",
                "Parent constructor: Value was 123",
                "Child constructor"
              ]));
        });
  
        test('this.field initializer runs before super constructor call', () {
          final code = '''
             var log = [];
             class Parent {
               var parentVal;
               // Simplified log for Parent constructor
               Parent(this.parentVal) { log.add("Parent init called"); } 
             }
             class Child extends Parent {
               var childVal;
               // Use 'arg' directly in super call, access 'this.childVal' in body
               Child(arg) : this.childVal = arg * 2, super(arg) { 
                 log.add("Child body: \${this.childVal}"); // Use 'this.' access
               }
             }
             main() {
                log.clear();
                Child(5);
                return log;
             }
           ''';
          // Initializers run in order: this.field, then super() body, then child body
          expect(execute(code), equals(["Parent init called", "Child body: 10"]));
        });
  
        test('Calling non-existent super constructor fails', () {
          final code = '''
              class Parent { Parent.named(); }
              class Child extends Parent { Child() : super.unnamed(); }
             main() { Child(); }
           ''';
          expect(
              () => execute(code),
              throwsA(isA<RuntimeError>().having(
                (e) => e.message,
                'message',
                contains(
                    "Superclass 'Parent' does not have a constructor named 'unnamed'."),
              )));
        });
  
        test(
            'Implicit super() call fails if no default constructor in superclass',
            () {
          final code = '''
              class Parent { Parent.named(); }
              class Child extends Parent { Child(); } // Implicit super()
             main() { Child(); }
           ''';
          expect(
              () => execute(code),
              throwsA(isA<RuntimeError>().having(
                (e) => e.message,
                'message',
                contains(
                    "Implicit call to superclass 'Parent' default constructor failed: No default constructor found."),
              )));
        });
  
        test('Calling super() on class with no superclass fails', () {
          final code = '''
              class Orphan { Orphan() : super(); }
             main() { Orphan(); }
            ''';
          expect(
              () => execute(code),
              throwsA(isA<RuntimeError>().having(
                (e) => e.message,
                'message',
                contains(
                    "Cannot call 'super' in constructor of class 'Orphan' because it has no superclass."),
              )));
        });
      }); // End Super Constructor Calls group
    }); // End Classes and Instances group
  
    group('Abstract Classes and Methods', () {
      test('Cannot instantiate abstract class', () {
        final code = '''
          abstract class Shape {
            Shape();
          }
          // Define main to execute the code
         main() {
             var s = Shape(); // Error should happen here
          }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              // Check for the specific error message within the potential wrapper error
              contains('Cannot instantiate abstract class \'Shape\'.'),
            )));
      });
  
      test('Concrete class must implement abstract method', () {
        final code = '''
          abstract class Vehicle {
            void move(); // Abstract method (no body)
          }
          class Car extends Vehicle { // Error: Missing implementation of move()
            Car();
          }
          main() { Car(); }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  'Missing concrete implementation for inherited abstract method \'move\' in class \'Car\'.'),
            )));
      });
  
      test('Concrete class implements abstract method successfully', () {
        final code = '''
          // Ensure correct structure with main()
          List<String> log = [];
          abstract class Vehicle {
            void move(); // Abstract method
            Vehicle(); // Add default constructor
          }
          class Car extends Vehicle {
            Car();
            var result = ""; // Instance variable to store result
            // Override is implicit in Dart
            void move() {
              // log.add("Car moving");
              result = "Car moving"; // Assign instance result
            }
          }
          String main() {
            var c = Car();
            c.move();
            // return log; // Return the result
            return c.result; // Return the instance result
          }
        ''';
        final result = execute(code);
        // expect(result, equals(['Car moving']));
        expect(result, equals("Car moving"));
      });
  
      test('Abstract method cannot be declared in concrete class', () {
        final code = '''
          class MyClass {
            // Abstract methods only make sense in abstract classes and lack a body
            // This syntax is invalid Dart and should be caught by our existing checks
            // But we test if the *runtime* check catches it if parsing allowed it.
            // Let's change to a valid syntax that *should* fail the runtime check:
            // void myMethod(); // This would require the class to be abstract
            // For the specific error message we expect, we need the parser error
            // So keep the original code that causes a parser error for this test:
             abstract void myMethod(); // Keep this to test the specific parser error check first
          }
        ''';
        // Expecting the parser error, not the RuntimeError for this specific case
        // because `abstract` modifier on members is invalid syntax.
        // Let's refine the expectation later if needed based on how the parser handles this.
        // For now, keeping the RuntimeError check as initially generated.
        expect(
            () => execute(code),
            throwsA(isA<Exception>().having(
              (e) => e.toString(), // Check toString() for Exception message
              'toString()',
              // Expecting the parser error
              contains("Members of classes can't be declared to be 'abstract'"),
            )));
      });
  
      test('Abstract method cannot have a body', () {
        final codeWithError = '''
          abstract class MyAbstractClass {
            abstract void myMethod() { // Error intended for testing
               print("Body");
            }
          }
        ''';
        expect(
            () => execute(codeWithError),
            throwsA(isA<Exception>().having(
              (e) => e.toString(), // Check toString() for Exception message
              'toString()',
              // Expecting the parser error (likely flags the modifier first)
              contains("Members of classes can't be declared to be 'abstract'"),
            )));
      });
  
      test('Concrete class must implement abstract getter', () {
        final code = '''
          abstract class Describable {
            String get description; // Abstract getter (no body)
            Describable(); // Add default constructor
          }
          class Item extends Describable { // Error: Missing getter 'description'
             String name;
             Item(this.name);
          }
          // Instantiation should be in main, although the error occurs during class definition
         main() {
             var i = Item("Box");
          }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  'Missing concrete implementation for inherited abstract getter \'description\' in class \'Item\'.'),
            )));
      });
  
      test('Concrete class implements abstract getter successfully', () {
        final code = '''
          // Ensure correct structure with main()
          List<String> log = [];
          abstract class Describable {
            String get description; // Abstract getter
            Describable(); // Add default constructor
          }
          class Item extends Describable {
             String name;
             Item(this.name);
             // Override is implicit
             String get description => "Item: \$name";
          }
          String main() {
            var i = Item("Gadget");
            return i.description; // Return the result
          }
        ''';
        final result = execute(code);
        expect(result, equals('Item: Gadget'));
      });
  
      test('Concrete class must implement abstract setter', () {
        final code = '''
          List<String> log = [];
          abstract class Configurable {
            set config(String value); // Abstract setter (no body)
            Configurable(); // Add default constructor
          }
          class Device extends Configurable { // Error: Missing setter 'config'
            Device();
          }
          // Instantiation should be in main
         main() {
             var d = Device();
          }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  'Missing concrete implementation for inherited abstract setter \'config\' in class \'Device\'.'),
            )));
      });
  
      test('Concrete class implements abstract setter successfully', () {
        final code = '''
          // Ensure correct structure with main()
          abstract class Configurable {
            set config(String value); // Abstract setter
            Configurable(); // Add default constructor
          }
          class Device extends Configurable {
             String _currentConfig = "";
             Device();
              // Override is implicit
             set config(String value) {
                // Simulate some action in the setter
                _currentConfig = value;
             }
          }
          String main() {
            var d = Device();
            d.config = "Mode A";
            // return d.result; // Return the result stored in the instance
            return "Setter called"; // Return a known value
          }
        ''';
        final result = execute(code);
        // expect(result, equals("Setting config to: Mode A"));
        expect(result, equals("Setter called"));
      });
    });
  
    group('Interfaces', () {
      test('Simple implements success', () {
        final code = '''
          abstract class Printable {
            String printInfo();
          }
          class Document implements Printable {
            String content;
            Document(this.content);
  
            @override // Optional here, good practice
            String printInfo() {
              return "Document: " + content;
            }
          }
         main() {
            Printable p = Document("Test");
            return p.printInfo();
          }
        ''';
        expect(execute(code), equals('Document: Test'));
      });
  
      test('Missing interface method implementation fails', () {
        final code = '''
          abstract class Runnable {
             void run();
          }
          class Task implements Runnable { // Error: Missing run()
             Task();
          }
         main() { var t = Task(); }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  'Missing concrete implementation for interface method \'run\' in class \'Task\'.'),
            )));
      });
  
      test('Missing interface getter implementation fails', () {
        final code = '''
          abstract class Labeled {
             String get label;
          }
          class Button implements Labeled { // Error: Missing get label
             Button();
          }
         main() { var b = Button(); }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  'Missing concrete implementation for interface getter \'label\' in class \'Button\'.'),
            )));
      });
  
      test('Missing interface setter implementation fails', () {
        final code = '''
          abstract class Settable {
             set value(int v);
          }
          class Box implements Settable { // Error: Missing set value
             Box();
          }
         main() { var b = Box(); }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  'Missing concrete implementation for interface setter \'value\' in class \'Box\'.'),
            )));
      });
  
      test('Multiple interfaces implementation success', () {
        final code = '''
            abstract class Clickable { void click(); }
            abstract class Draggable { void drag(); }
  
            class Icon implements Clickable, Draggable {
                String name;
                Icon(this.name);
                String result = "";
  
                @override
                void click() { 
                  result = name + " clicked";
                }
                @override
                void drag() { 
                  result = name + " dragged";
                }
            }
           main() {
                Icon i = Icon("File");
                i.click();
                var r1 = i.result;
                i.drag();
                var r2 = i.result;
                return r1 + ", " + r2;
            }
          ''';
        expect(execute(code), equals('File clicked, File dragged'));
      });
  
      test('Missing implementation with multiple interfaces fails', () {
        final code = '''
            abstract class Clickable { void click(); }
            abstract class Draggable { void drag(); }
  
            class Icon implements Clickable, Draggable { // Error: Missing drag()
                String name;
                Icon(this.name);
                @override
                void click() { print("Clicked"); }
                // Missing drag()
            }
           main() {
                Icon i = Icon("Folder");
            }
          ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  'Missing concrete implementation for interface method \'drag\' in class \'Icon\'.'),
            )));
      });
  
      test('Implementing non-class fails', () {
        final code = '''
            var notAClass = 1;
            class MyClass implements notAClass {} // Error
           main() {}
          ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains("Interface 'notAClass' not found for class 'MyClass'"),
            )));
      });
  
      test('Implementing non-existent fails', () {
        final code = '''
            class MyClass implements NonExistent {} // Error
            main() {}
          ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains("Interface 'NonExistent' not found for class 'MyClass'."),
            )));
      });
  
      test('Abstract class implementing interface does not need implementation',
          () {
        final code = '''
            abstract class Doer { void doIt(); }
            abstract class MyAbstract implements Doer { // OK
               MyAbstract();
            }
            // Cannot instantiate MyAbstract directly, so no runtime check here
            // We just check that the class definition itself doesn't throw.
           main() { return "OK"; } 
          ''';
        expect(execute(code), equals("OK"));
      });
  
      test(
          'Concrete class extending abstract class implementing interface must implement',
          () {
        final code = '''
            abstract class Doer { void doIt(); }
            abstract class MyAbstract implements Doer {
               MyAbstract();
            }
            class MyConcrete extends MyAbstract { // Error: Missing doIt()
                MyConcrete();
            }
           main() { var x = MyConcrete(); }
          ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              // The check for interface members happens after abstract member check.
              // Depending on the order, the message might vary. Let's check for doIt.
              contains(
                  "Missing concrete implementation for interface method 'doIt' in class 'MyConcrete'"),
            )));
      });
  
      test('Implementation includes members from super-interfaces', () {
        final code = '''
            abstract class A { void methodA(); }
            abstract class B implements A { void methodB(); }
            class C implements B { // Error: Missing methodA and methodB
                C();
            }
           main() { var x = C(); }
          ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              // Check for one of the missing methods (order might vary)
              contains("Missing concrete implementation for interface method"),
            )));
        // More specific check for methodA might be needed if order is guaranteed
        // expect(() => execute(code), throwsA(isA<RuntimeError>().having(
        //    (e) => e.message, 'message', contains("method 'methodA'"),
        // )));
      });
    });
  
    group('Mixins', () {
      test('Simple mixin application and method call', () {
        final code = '''
          // Declare mixin FIRST
          mixin Walker {
            String walk() => "Walking";
          }
          class Person with Walker {
            Person();
          }
           main() {
            var p = Person();
            return p.walk();
          }
        ''';
        expect(execute(code), equals("Walking"));
      });
  
      test('Accessing mixin field', () {
        final code = '''
          // Declare mixin FIRST
          mixin Data {
            int value = 10;
          }
          class Container with Data {
            Container();
          }
           main() {
            var c = Container();
            return c.value;
          }
        ''';
        expect(execute(code), equals(10));
      });
  
      test('Mixin overrides superclass method', () {
        final code = '''
          // Declare Base and Mixin FIRST
          class Base {
            String message() => "Base";
            Base();
          }
          mixin OverrideMessage on Base {
            @override
            String message() => "Mixin";
          }
          class Derived extends Base with OverrideMessage {
            Derived();
          }
           main() {
            var d = Derived();
            return d.message();
          }
        ''';
        expect(execute(code), equals("Mixin"));
      });
  
      test('Class overrides mixin method', () {
        final code = '''
          // Declare mixin FIRST
          mixin Greeter {
            String greet() => "Mixin Hello";
          }
          class Person with Greeter {
             Person();
             @override
             String greet() => "Person Hello";
          }
           main() {
              var p = Person();
              return p.greet();
          }
        ''';
        expect(execute(code), equals("Person Hello"));
      });
  
      test('Multiple mixins resolution order (last wins)', () {
        final code = '''
          // Declare mixins FIRST
          mixin M1 { String value() => "M1"; }
          mixin M2 { String value() => "M2"; }
          class C with M1, M2 { // M2 is applied last
             C();
          }
           main() {
              var c = C();
              return c.value();
          }
        ''';
        expect(execute(code), equals("M2"));
      });
  
      test('Applying non-mixin class fails', () {
        final code = '''
          class NotAMixin { }
          class MyClass with NotAMixin { } // Error
         main() {}
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
              (e) => e.message,
              'message',
              contains(
                  "Class 'NotAMixin' cannot be used as a mixin because it's not declared with 'mixin' or 'class mixin'"), // Message d'erreur réel
            )));
      });
  
      test('Mixin cannot declare constructor', () {
        final code = '''
          mixin BadMixin {
             BadMixin() {} // Error
          }
         main() {}
        ''';
        expect(
            () => execute(code),
            throwsA(isA<Exception>().having(
              (e) => e.toString(), // Use toString for generic Exception
              'toString()',
              contains("Mixins can't declare constructors"), // Match parser error
            )));
      });
    });
  
    group('Error Handling:', () {
      test('try...finally executes finally block normally', () {
        final code = '''
          var number = 0;
          main() {
            try {
              number = 1;
            } finally {
              number = 2;
            }
            number = 3;
            return number;
          }
        ''';
        expect(execute(code), equals(3));
      });
  
      test('try...finally executes finally block after exception', () {
        final code = '''
          var number = 0;
          main() {
            try {
              number = 1;
              throw "Oops"; // Use simple throw
              number++; // Should not be reached
            } finally {
              number++; // This executes but is not directly verifiable
            }
            number++; // Should not be reached if the exception is rethrown
            return number;
          }
        ''';
        // Expect a RuntimeError, and finally must execute
        // var resultLog = []; // Removed
        expect(
          () {
            // execute(code, externalLog: resultLog); // Modified
            execute(code);
          },
          throwsA(equals("Oops")),
        );
        // Check that the log was modified as expected (1 then 2)
        // expect(resultLog, equals([1, 2])); // Removed as not verifiable
      });
  
      test('try...catch catches specific exception', () {
        final code = '''
          var number = 0;
          main() {
            try {
              number = 1;
              throw "Oops"; // Use simple throw
              number++;
            } catch (e) {
              number++;
            }
            number++;
            return number;
          }
        ''';
        expect(execute(code), equals(3));
      });
  
      test('try...catch...finally combination', () {
        final code = '''
          var number = 0;
          main() {
            try {
              number = 1;
              throw "Problem"; // Use simple throw
            } catch (e) {
              number++;
            } finally {
              number++;
            }
            number++;
            return number;
          }
        ''';
        expect(execute(code), equals(4));
      });
  
      test('try...catch rethrows if no matching catch', () {
        final code = '''
          // Pour l'instant, notre catch attrape tout
          // Ce test sera plus pertinent avec `on Type`
          main() {
            try {
              throw "SpecificError"; // Lancer une valeur spécifique
            } catch (e) {
              // Attrape, mais ne fait rien pour le re-lancer
              return "Caught: " + e; // Retourner la valeur attrapée
            }
          }
        ''';
        expect(execute(code), equals("Caught: SpecificError"));
      });
  
      test('Exception in catch block propagates', () {
        final code = '''
          main() {
            try {
              throw "Initial"; // Lancer une valeur initiale
            } catch (e) {
              throw "Secondary"; // Lancer une autre valeur
            }
          }
        ''';
        expect(
          () => execute(code),
          throwsA(equals('Secondary')),
        );
      });
  
      test('Exception in finally block propagates and overrides', () {
        final code = '''
          main() {
            try {
              throw "TryException"; // Lancer dans le try
            } finally {
              throw "FinallyException"; // Lancer dans le finally (devrait prévaloir)
            }
          }
        ''';
        expect(
          () => execute(code),
          throwsA(equals('FinallyException')),
        );
      });
  
      test('Exception in finally block propagates even if try/catch handles', () {
        final code = '''
          main() {
            try {
              throw "TryException"; // Lancer dans le try
            } catch (e) {
              print("Caught in catch: " + e); // Modifier le print
            } finally {
              throw "FinallyException"; // Lancer dans le finally (devrait prévaloir)
            }
          }
        ''';
        expect(
          () => execute(code),
          throwsA(equals('FinallyException')),
        );
      });
    }); // Fin groupe Error Handling
  
    group('Type Check Operator (is/is!):', () {
      test('is with built-in types', () {
        final code = '''
          main() {
            var i = 10;
            var d = 3.14;
            var s = "hello";
            var b = true;
            var l = [1, 2];
            var n = null;
            // Restoring the fix: s is Object added at the end
            return [i is int, d is double, s is String, b is bool, l is List, n is Null, i is num, d is num, i is String, n is Object, s is Object];
          }
        ''';
        expect(
            execute(code),
            equals([
              true, true, true, true, true,
              true, // int, double, String, bool, List, Null
              true, true, // i is num, d is num
              false, false, // i is String, n is Object (n is null)
              true // s is Object
            ]));
      });
  
      test('is! negation with built-in types', () {
        final code = '''
          main() {
            var i = 10;
            var s = "world";
            return [i is! int, s is! String, i is! String, s is! Object];
          }
        ''';
        expect(execute(code), equals([false, false, true, false]));
      });
  
      test('is with simple user-defined class', () {
        final code = '''
          class A {}
          main() {
            var a = A();
            var b = null;
            return [a is A, b is A, a is Object];
          }
        ''';
        expect(execute(code), equals([true, false, true]));
      });
  
      test('is with inheritance', () {
        final code = '''
          class A {}
          class B extends A {}
          class C {}
          main() {
            var b = B();
            return [b is B, b is A, b is C, b is Object];
          }
        ''';
        expect(execute(code), equals([true, true, false, true]));
      });
  
      test('is with interface implementation', () {
        final code = '''
          abstract class I {}
          class A implements I {}
          class B {}
          main() {
            var a = A();
            return [a is A, a is I, a is B, a is Object];
          }
        ''';
        expect(execute(code), equals([true, true, false, true]));
      });
  
      test('is with mixin application', () {
        final code = '''
          mixin M {}
          class A with M {}
          class B {}
          main() {
            var a = A();
            return [a is A, a is M, a is B, a is Object];
          }
        ''';
        // Note: 'is MixinName' requires the mixin to be treated like a type
        // Our isSubtypeOf logic should handle this.
        expect(execute(code), equals([true, true, false, true]));
      });
  
      test('is with complex hierarchy (extends, implements, with)', () {
        final code = '''
          abstract class Clickable {} 
          mixin Logger { void log(String msg){} }
          class Widget {}
          class Button extends Widget with Logger implements Clickable {}
          
          class Panel extends Widget {}
  
          main() {
            var btn = Button();
            return [
              btn is Button,     // true
              btn is Widget,     // true (extends)
              btn is Clickable,  // true (implements)
              btn is Logger,     // true (with)
              btn is Panel,      // false
              btn is Object,     // true
              btn is! Panel,     // true
            ];
          }
        ''';
        expect(
            execute(code), equals([true, true, true, true, false, true, true]));
      });
  
      test('catch on Type (specific built-in)', () {
        final code = '''
          main() {
            var result = '';
            try {
              throw "Error string";
            } on int {
              result = 'Caught int';
            } on String {
              result = 'Caught String';
            } catch (e) {
              result = 'Caught dynamic';
            }
            return result;
          }
        ''';
        expect(execute(code), equals('Caught String'));
      });
  
      test('catch on Type (superclass)', () {
        final code = '''
          class MyError {}
          class SpecificError extends MyError {}
          main() {
            var result = '';
            try {
              throw SpecificError();
            } on String {
               result = 'Caught String';
            } on MyError {
               result = 'Caught MyError'; // Should catch here
            } on SpecificError {
               result = 'Caught SpecificError'; // Should not reach here
            } catch (e) {
               result = 'Caught dynamic';
            }
             return result;
          }
        ''';
        expect(execute(code), equals('Caught MyError'));
      });
  
      test('catch on Type (interface)', () {
        final code = '''
          abstract class IError {}
          class NetworkError implements IError {}
          main() {
            var result = '';
            try {
              throw NetworkError();
            } on IError {
               result = 'Caught IError';
            } catch (e) {
               result = 'Caught dynamic';
            }
             return result;
          }
        ''';
        expect(execute(code), equals('Caught IError'));
      });
  
      test('catch on Type (mixin)', () {
        final code = '''
          mixin ErrorMixin {}
          class AuthError with ErrorMixin {}
          main() {
            var result = '';
            try {
              throw AuthError();
            } on ErrorMixin {
               result = 'Caught ErrorMixin';
            } catch (e) {
               result = 'Caught dynamic';
            }
             return result;
          }
        ''';
        expect(execute(code), equals('Caught ErrorMixin'));
      });
  
      test('catch on Type (no match, falls through to dynamic catch)', () {
        final code = '''
          main() {
            var result = 'Not caught';
            try {
              throw true; // Throw a boolean
            } on int catch (_) {
              result = 'Caught int';
            } on String catch (e) {
              result = 'Caught String';
            } catch (e) {
              // This should catch the boolean
              result = 'Caught dynamic: \$e';
            }
            return result;
          }
        ''';
  
        expect(execute(code), 'Caught dynamic: true');
      });
  
      test('catch stack trace variable', () {
        final code = '''
          main() {
            try {
              throw "Failure";
            } catch (e, s) {
              // Simplified check: just ensure s is a String
              if (s is String) {
                 return e; // Return original error if stack trace is a String
              } else {
                 return "Invalid stack trace type";
              }
            }
          }
        ''';
        final result = execute(code);
        // Check that the interpreted code returned the original error message,
        // implying the stack trace check passed internally.
        expect(result, 'Failure');
      });
  
      test('rethrow statement', () {
        final code = '''
          main() {
            try {
              try {
                throw "Inner error";
              } catch (e) {
                rethrow; // Rethrow the inner error
              }
            } on String catch (e) {
              return "Caught outer: " + e;
            } catch (e) {
              return "Caught outer dynamic";
            }
          }
        ''';
        expect(execute(code), equals('Caught outer: Inner error'));
      });
  
      test('rethrow outside catch fails', () {
        final code = '''
          main() {
            rethrow;
          }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having((e) => e.message, 'message',
                contains("'rethrow' can only be used within a catch block."))));
      });
    });
  
    group('Redirecting Constructors (this(...)):', () {
      test('Simple redirection to unnamed constructor', () {
        final code = '''
          class Points {
            num x, y;
            Points(this.x, this.y);
            Points.origin() : this(0, 0);
          }
          main() {
            var p = Points.origin();
            return [p.x, p.y];
          }
        ''';
        expect(execute(code), equals([0, 0]));
      });
  
      test('Redirection to named constructor', () {
        final code = '''
          class Rect {
            num left, top, width, height;
            Rect(this.left, this.top, this.width, this.height);
            Rect.square(num size) : this(0, 0, size, size);
            Rect.fromOrigin(num w, num h) : this(0, 0, w, h);
          }
          main() {
            var r1 = Rect.square(10);
            var r2 = Rect.fromOrigin(20, 30);
            return [
              r1.left, r1.top, r1.width, r1.height, 
              r2.left, r2.top, r2.width, r2.height
            ];
          }
        ''';
        expect(execute(code), equals([0, 0, 10, 10, 0, 0, 20, 30]));
      });
  
      test('Redirection with argument passing and calculation', () {
        final code = '''
          class Circle {
            num x, y, radius;
            Circle(this.x, this.y, this.radius);
            Circle.unitAt(num x, num y) : this(x, y, 1);
            Circle.doubleRadius(num r) : this(0, 0, r * 2);
          }
          main() {
            var c1 = Circle.unitAt(5, 6);
            var c2 = Circle.doubleRadius(10);
            return [
              c1.x, c1.y, c1.radius,
              c2.x, c2.y, c2.radius
            ];
          }
        ''';
        expect(execute(code), equals([5, 6, 1, 0, 0, 20]));
      });
  
      test('Redirecting constructor body is not executed', () {
        final code = '''
          class Counter {
            int value = 0;
            Counter(int val) { // Target constructor body
               this.value = val * 10;
            }
            // Removed body from redirecting constructor
            Counter.redirecting() : this(5);
          }
          main() {
            var c = Counter.redirecting();
            return c.value;
          }
        ''';
        expect(execute(code), equals(50));
      });
  
      test('Redirection chain (this -> this -> actual)', () {
        final code = '''
          class Chain {
            String trace = "";
            Chain(String initial) { trace += initial; }
            // Removed body from redirecting constructor
            Chain.step1(String p) : this("(" + p + ")"); 
            // Removed body from redirecting constructor
            Chain.step2(String p) : this.step1("[" + p + "]"); 
          }
          main() {
            var ch = Chain.step2("Value");
            return ch.trace;
          }
        ''';
        expect(execute(code), equals("([Value])"));
      });
  
      test('Redirecting to non-existent constructor fails', () {
        final code = '''
          class Box {
            Box() {}
            Box.redirect() : this.nonExistent(); // Error here
          }
          main() {
            return Box.redirect();
          }
        ''';
        expect(
            () => execute(code),
            throwsA(isA<RuntimeError>().having(
                (e) => e.message,
                'message',
                contains(
                    'Class \'Box\' does not have a constructor named \'nonExistent\''))));
      });
    });
  
    group('Collections', () {
      test('Map literal basic', () {
        final code = '''
          main() {
            var m = {'a': 1, 'b': true, 3: 'hello'};
            return m;
          }
        ''';
        final result = execute(code);
        expect(result is Map, isTrue);
        expect(result, equals({'a': 1, 'b': true, 3: 'hello'}));
      });
  
      test('Map literal with expressions', () {
        final code = '''
          main() {
            int x = 5;
            String k = 'key';
            var m = {k: x * 2, 'next': x + 1};
            return m;
          }
        ''';
        final result = execute(code);
        expect(result is Map, isTrue);
        expect(result, equals({'key': 10, 'next': 6}));
      });
  
      test('Empty map literal', () {
        final code = '''
          main() {
            var m = {};
            // Note: {} defaults to Map<dynamic, dynamic> in Dart
            return m;
          }
        ''';
        final result = execute(code);
        expect(result is Map, isTrue);
        expect(result, isEmpty);
      });
      test('Set literal basic', () {
        final code = '''
            main() {
              var s = {1, 'hello', true, 1}; // Duplicate '1' should be ignored
              return s;
            }
          ''';
        final result = execute(code);
        expect(result is Set, isTrue);
        // Order is not guaranteed in sets, check contents
        expect(result, equals({1, 'hello', true}));
      });
  
      test('Set literal with expressions', () {
        final code = '''
            main() {
              int x = 2;
              var s = {x, x * 3, 'val-\$x'};
              return s;
            }
          ''';
        final result = execute(code);
        expect(result is Set, isTrue);
        expect(result, equals({2, 6, 'val-2'}));
      });
  
      test('List spread operator (...)', () {
        final code = '''
            main() {
              List<int> l1 = [1, 2];
              Set<int> s1 = {3, 4};
              var l2 = [0, ...l1, ...s1, 5];
              return l2;
            }
          ''';
        final result = execute(code);
        expect(result, equals([0, 1, 2, 3, 4, 5]));
      });
  
      test('List null-aware spread operator (...?)', () {
        final code = '''
            main() {
              List<int>? l1 = [1, 2];
              List<int>? l2 = null;
              var l3 = [0, ...?l1, ...?l2, 3];
              return l3;
            }
          ''';
        final result = execute(code);
        expect(result, equals([0, 1, 2, 3]));
      });
  
      test('List spread type error', () {
        final code = '''
            main() {
              var notIterable = 123;
              return [...notIterable];
            }
          ''';
        expect(
            () => execute(code),
            throwsRuntimeError(contains(
                'Spread element in a List literal requires an Iterable'))); // Use contains and updated message
      });
  
      test('Set spread operator (...)', () {
        final code = '''
            main() {
              List<String> l1 = ['a', 'b'];
              Set<String> s1 = {'c', 'a'}; // Duplicate 'a' from spread
              var s2 = {'x', ...l1, ...s1, 'y'}; 
              return s2;
            }
          ''';
        final result = execute(code);
        expect(result is Set, isTrue);
        expect(result, equals({'x', 'a', 'b', 'c', 'y'}));
      });
  
      test('Set null-aware spread operator (...?)', () {
        final code = '''
            main() {
              List<int>? l1 = [1, 2];
              Set<int>? s1 = null;
              var s2 = {0, ...?l1, ...?s1, 3, 0};
              return s2;
            }
          ''';
        final result = execute(code);
        expect(result is Set, isTrue);
        expect(result, equals({0, 1, 2, 3}));
      });
  
      test('Set spread type error', () {
        final code = '''
            main() {
              var notIterable = 123;
              return {...notIterable};
            }
          ''';
        expect(
            () => execute(code),
            throwsRuntimeError(contains(
                'Spread element in a Set literal requires an Iterable'))); // Use contains
      });
  
      test('Map spread operator (...)', () {
        final code = '''
            main() {
              var m1 = {'a': 1, 'b': 2};
              var m2 = {'b': 3, 'c': 4}; // Key 'b' will be overwritten
              var m3 = {'x': 0, ...m1, ...m2, 'y': 5};
              return m3;
            }
          ''';
        final result = execute(code);
        expect(result is Map, isTrue);
        expect(result, equals({'x': 0, 'a': 1, 'b': 3, 'c': 4, 'y': 5}));
      });
  
      test('Map null-aware spread operator (...?)', () {
        final code = '''
            main() {
              Map<String, int>? m1 = {'a': 1};
              Map<String, int>? m2 = null;
              var m3 = {'x': 0, ...?m1, ...?m2, 'y': 2};
              return m3;
            }
          ''';
        final result = execute(code);
        expect(result is Map, isTrue);
        expect(result, equals({'x': 0, 'a': 1, 'y': 2}));
      });
  
      test('Map spread type error', () {
        final code = '''
            main() {
              var notMap = [1, 2];
              return {...notMap}; // Spreading a List into a Map
            }
          ''';
        final result = execute(code);
        expect(result is Set, isTrue);
        expect(result, equals({1, 2}));
      });
  
      test('Map spread combined with entries', () {
        final code = '''
            main() {
              var m1 = {'a': 1};
              return {...m1, 'b': 2};
            }
          ''';
        final result = execute(code);
        expect(result is Map, isTrue);
        expect(result, equals({'a': 1, 'b': 2}));
      });
    });
    group('Collection Control-Flow Elements', () {
      test('List with if (true)', () {
        final code = '''
            main() {
              bool include = true;
              return [1, if (include) 2, 3];
            }
          ''';
        expect(execute(code), equals([1, 2, 3]));
      });
  
      test('List with if (false)', () {
        final code = '''
            main() {
              bool include = false;
              return [1, if (include) 2, 3];
            }
          ''';
        expect(execute(code), equals([1, 3]));
      });
  
      test('List with if-else (true)', () {
        final code = '''
            main() {
              bool useTwo = true;
              return [1, if (useTwo) 2 else -1, 3];
            }
          ''';
        expect(execute(code), equals([1, 2, 3]));
      });
  
      test('List with if-else (false)', () {
        final code = '''
            main() {
              bool useTwo = false;
              return [1, if (useTwo) 2 else -1, 3];
            }
          ''';
        expect(execute(code), equals([1, -1, 3]));
      });
  
      test('List with simple for-in', () {
        final code = '''
            main() {
              var items = [10, 20];
              return [0, for (var i in items) i * 2, 50];
            }
          ''';
        expect(execute(code), equals([0, 20, 40, 50]));
      });
  
      test('List with nested if inside for', () {
        final code = '''
            main() {
              var nums = [1, 2, 3, 4];
              return [for (var n in nums) if (n % 2 == 0) n * 10];
            }
          ''';
        expect(execute(code), equals([20, 40]));
      });
  
      test('List with spread inside if', () {
        final code = '''
            main() {
              bool addMore = true;
              var extras = [3, 4];
              return [1, 2, if (addMore) ...extras, 5];
            }
          ''';
        expect(execute(code), equals([1, 2, 3, 4, 5]));
      });
  
      test('Set with if and for', () {
        final code = '''
            main() {
              bool addZero = false;
              var data = [2, 3, 2]; // Duplicate 2 for set test
              return {1, if (addZero) 0, for (var x in data) x + 10, 13};
            }
          ''';
        final result = execute(code);
        expect(result is Set, isTrue);
        expect(
            result, equals({1, 12, 13})); // 2+10=12, 3+10=13, 2+10=12 (ignored)
      });
  
      test('Map with if and for', () {
        final code = '''
            main() {
              bool isAdmin = true;
              var users = ['a', 'b'];
              return {
                'entry': 0,
                if (isAdmin) 'admin_key': true,
                for (var u in users) 'user_\$u': u + u,
                'exit': 1
              };
            }
          ''';
        final result = execute(code);
        expect(result is Map, isTrue);
        expect(
            result,
            equals({
              'entry': 0,
              'admin_key': true,
              'user_a': 'aa',
              'user_b': 'bb',
              'exit': 1
            }));
      });
      test('Map for element must be MapEntry', () {
        final code = '''
            main() {
              var items = [1, 2];
              return {
                'a': 0,
                for (var i in items) i // Error: Should be key:value
              };
            }
          ''';
        expect(
            () => execute(code),
            throwsRuntimeError(
                contains("Expected a MapLiteralEntry ('key: value')")));
      });
  
      test('Map if element must be MapEntry', () {
        final code = '''
            main() {
              bool addIt = true;
              return {
                'a': 0,
                if (addIt) 1 // Error: Should be key:value
              };
            }
          ''';
        expect(
            () => execute(code),
            throwsRuntimeError(
                contains("Expected a MapLiteralEntry ('key: value')")));
      });
  
      test('If condition not boolean fails', () {
        final code = '''
            main() {
              return [if (1) 2];
            }
          ''';
        expect(
            () => execute(code),
            throwsRuntimeError(
                contains("Condition in collection 'if' must be a boolean")));
      });
  
      test('For iterable not iterable fails', () {
        final code = '''
            main() {
              var notIterable = 1;
              return [for (var i in notIterable) i];
            }
          ''';
        expect(() => execute(code),
            throwsRuntimeError(contains("must be an Iterable")));
      });
    });
  
    // +++++ NOUVELLE SUITE DE TESTS POUR LES PONTS +++++
    group('Bridged Core Types Comprehensive', () {
      test('StringBuffer constructor, write, length, isEmpty, clear', () {
        final result = execute('''
          main() {
            var sb = StringBuffer();
            sb.write('Hello');
            var len1 = sb.length; // 5
            var empty1 = sb.isEmpty; // false
            sb.write(' World');
            var len2 = sb.length; // 11
            sb.clear();
            var len3 = sb.length; // 0
            var empty2 = sb.isEmpty; // true
            return [len1, empty1, len2, len3, empty2];
          }
        ''');
        expect(result, equals([5, false, 11, 0, true]));
      });
  
      test('int.parse static method', () {
        final result = execute('''
          main() {
            return int.parse('-123');
          }
        ''');
        expect(result, equals(-123));
      });
  
      test('int.parse static method - FormatException', () {
        expect(
          () => execute('''
            main() {
              return int.parse('abc');
            }
          '''),
          throwsA(isA<RuntimeError>().having(
            (e) => e.message,
            'message',
            contains('FormatException'),
          )),
        );
      });
  
      test('double.nan static getter', () {
        final result = execute('''
          main() {
            return double.nan;
          }
        ''');
        expect(result, isA<double>());
      });
  
      test('double.infinity static getter', () {
        final result = execute('''
          main() {
            return double.infinity;
          }
        ''');
        expect(result, equals(double.infinity));
      });
  
      test('List.remove instance method', () {
        final result = execute('''
          main() {
            var l = List.filled(3, 'a', growable: true);
            l.add('b'); // [a, a, a, b]
            l.add('a'); // [a, a, a, b, a]
            var removed = l.remove('a'); // Enlève le premier 'a', retourne true
            var lenAfterRemove = l.length; // 4
            // On vérifie que l contient encore 'a' et 'b'
            var containsA = false;
            var containsB = false;
            for (var item in l) { // On suppose que for-in sur BridgedInstance<List> fonctionne
               if (item == 'a') containsA = true;
               if (item == 'b') containsB = true;
            }
            return [removed, lenAfterRemove, containsA, containsB];
          }
        ''');
  
        expect(result, equals([true, 4, true, true]));
      });
    });
  
    group('Interpreter Core Feature Tests', () {
      test('ParenthesizedExpression', () {
        expect(execute('main() { return (1 + 2) * 3; }'), equals(9));
        expect(execute('main() { return (true); }'), isTrue);
        expect(execute('main() { var x = (5); return x; }'), equals(5));
      });
  
      test('CascadeExpression', () {
        const sourceList = '''
        main() {
          var list = [1, 2];
          list..add(3)..add(4)..removeAt(0);
          return list;
        }
        ''';
        expect(execute(sourceList), equals([2, 3, 4]));
  
        const sourceMap = '''
        main() {
          var map = {'a': 1};
          map..['b'] = 2..['a'] = 0;
          return map;
        }
        ''';
        expect(execute(sourceMap), equals({'a': 0, 'b': 2}));
  
        const sourceSB = '''
         main() {
           StringBuffer sb = StringBuffer();
           sb..write('Hello')..write(' ')..write('World');
           return sb.toString();
         }
         ''';
        expect(execute(sourceSB), equals('Hello World'));
  
        const sourceNull = '''
           main() {
             List? list = null;
             list?..add(1); // Should evaluate list, find null, and stop
             return list; // Returns null
           }
           ''';
        expect(execute(sourceNull), isNull);
  
        const sourcePropAssign = '''
           class Counter { int count = 0; void increment() { count++; } }
           main() {
              var c = Counter();
              c..count = 5 ..increment();
              return c.count;
           }
         ''';
        expect(execute(sourcePropAssign), equals(6));
      });
  
      test('FunctionExpressionInvocation', () {
        expect(execute('main() { return (() => 10)(); }'), equals(10));
        expect(execute('main() { var f = (int x) => x * 2; return f(5); }'),
            equals(10));
        const sourceComplex = '''
         class MyClass { Function fn; MyClass(this.fn); }
         main() {
           var obj = MyClass((a, b) => a + b);
           return obj.fn(3, 4);
         }
        ''';
        expect(execute(sourceComplex), equals(7));
      });
  
      test('FunctionReference (Tear-off)', () {
        const sourceTopLevel = '''
           int add(int a, int b) => a + b;
           main() { var f = add; return f(5, 6); }
         ''';
        expect(execute(sourceTopLevel), equals(11));
  
        const sourceStatic = '''
           class Calc { static int mult(int a, int b) => a * b; }
           main() { var f = Calc.mult; return f(5, 6); }
         ''';
        expect(execute(sourceStatic), equals(30));
  
        const sourceInstance = '''
           class Greeter { String prefix; Greeter(this.prefix); String greet(String name) => '\$prefix \$name'; }
           main() { var g = Greeter('Hello'); var f = g.greet; return f('World'); }
         ''';
        expect(execute(sourceInstance), equals('Hello World'));
      });
  
      test('AssertStatement', () {
        expect(() => execute('main() { assert(true); }'), returnsNormally);
        expect(
            () => execute('main() { assert(false); }'),
            throwsA(isA<RuntimeError>()
                .having((e) => e.message, 'message', 'Assertion failed')));
        expect(
            () => execute('main() { assert(1 == 2, "Math is broken"); }'),
            throwsA(isA<RuntimeError>().having((e) => e.message, 'message',
                'Assertion failed: Math is broken')));
        expect(() => execute('main() { var x = 5; assert(x > 0); }'),
            returnsNormally);
      });
  
      test('EmptyStatement', () {
        expect(() => execute('main() { ;;; }'), returnsNormally);
        expect(execute('main() { int x=1; ; return x; }'), equals(1));
      });
  
      test('NullAwareElement (?element)', () {
        expect(execute('main() { int? x = 5; int? y; return [?x, ?y, 10]; }'),
            equals([5, 10]));
        expect(execute('main() { int? y; return [?y]; }'), equals([]));
        // Test in set literal
        expect(execute('main() { int? x = 5; int? y; return {?x, ?y, 10}; }'),
            equals({5, 10}));
      });
  
      test('SetOrMapLiteral edge cases', () {
        // Spread only - Map
        expect(execute('main() { var m1 = {"a":1}; return {...m1}; }'),
            equals({'a': 1}));
        // Spread only - Set
        expect(execute('main() { var s1 = {1}; return {...s1}; }'), equals({1}));
        // Spread only - List (should become Set)
        expect(execute('main() { var l1 = [1, 2]; return {...l1}; }'),
            equals({1, 2}));
  
        expect(
            () => execute(
                'main() { var s1 = {1}; var m1 = {"b":2}; return {...s1, ...m1}; }'),
            throwsA(isA<
                RuntimeError>())); // Dart behavior: Cannot mix Map and Set spreads
        expect(
            () => execute(
                'main() { var s1 = {1}; var m1 = {"b":2}; return {...m1, ...s1}; }'),
            throwsA(isA<RuntimeError>()));
  
        expect(execute('main() { var s1 = {1, 2}; return <int>{...s1}; }'),
            equals({1, 2}));
        expect(
            execute('main() { var m1 = {"a":1}; return <String, int>{...m1}; }'),
            equals({'a': 1}));
      });
    });
  
    group('Pattern Matching - Variable Declarations', () {
      test('Wildcard Pattern', () {
        // Wildcard '_' ignores the value, but initializer is evaluated
        final source = '''
          var counter = 0;
          main() {
            var _ = counter = counter + 1;
            return counter; // Should be 1
          }
        ''';
        expect(execute(source), equals(1));
      });
  
      test('List Pattern - Simple', () {
        final source = '''
          main() {
            var [a, b] = [10, 20];
            return a + b; // 10 + 20 = 30
          }
        ''';
        expect(execute(source), equals(30));
      });
  
      test('List Pattern - Nested', () {
        final source = '''
          main() {
            var [x, [y, z]] = [1, [2, 3]];
            return x * 100 + y * 10 + z; // 1*100 + 2*10 + 3 = 123
          }
        ''';
        expect(execute(source), equals(123));
      });
  
      test('List Pattern - Wildcard', () {
        final source = '''
          main() {
            var [a, _, c] = [10, "ignore", 30];
            return a + c; // 10 + 30 = 40
          }
        ''';
        expect(execute(source), equals(40));
      });
  
      test('List Pattern - Mismatch Length', () {
        final source = '''
          main() {
            var [a, b] = [1]; // Too few elements
          }
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(
                contains('List pattern expected 2 elements, but List has 1')));
      });
  
      test('List Pattern - Mismatch Type', () {
        final source = '''
          main() {
            var [a] = "not a list";
          }
        ''';
        expect(() => execute(source),
            throwsRuntimeError(contains('Expected a List, but got String')));
      });
  
      test('Map Pattern - Simple', () {
        final source = '''
          main() {
            var {'key1': val1, 'key2': val2} = {'key1': 'hello', 'key2': 5};
            return val1 + (val2 * 2).toString(); // 'hello' + (5*2).toString() = 'hello10'
          }
        ''';
        expect(execute(source), equals('hello10'));
      });
  
      test('Map Pattern - Different Key Types', () {
        final source = '''
          main() {
            var map = {1: 'one', true: 'yes', 'k': 99};
            var {1: numVal, true: boolVal, 'k': strVal} = map;
            return numVal + boolVal + strVal.toString(); // 'one' + 'yes' + '99'
          }
        ''';
        expect(execute(source), equals('oneyes99'));
      });
  
      test('Map Pattern - Missing Key', () {
        final source = '''
          main() {
            var {'a': x, 'b': y} = {'a': 1}; // Missing key 'b'
          }
        ''';
        expect(() => execute(source),
            throwsRuntimeError(contains("Map pattern key 'b' not found")));
      });
  
      test('Map Pattern - Mismatch Type', () {
        final source = '''
          main() {
            var {'a': x} = [1, 2]; // Not a map
          }
        ''';
        expect(() => execute(source),
            throwsRuntimeError(contains('Expected a Map, but got List')));
      });
  
      test('Record Pattern - Positional', () {
        final source = '''
          main() {
            var (a, b) = (10, 'world');
            return a.toString() + b; // '10' + 'world'
          }
        ''';
        expect(execute(source), equals('10world'));
      });
  
      test('Record Pattern - Named', () {
        final source = '''
          main() {
            var (name: n, age: a) = (name: 'Bob', age: 42);
            return n + a.toString(); // 'Bob' + '42'
          }
        ''';
        expect(execute(source), equals('Bob42'));
      });
  
      test('Record Pattern - Positional Mismatch Count', () {
        final source = '''
          main() {
            var (a, b) = (1,); // Too few positional fields
          }
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                'Record pattern expected at least 2 positional fields, but Record only has 1')));
      });
  
      test('Record Pattern - Named Mismatch Name', () {
        final source = '''
          main() {
            var (value: v) = (data: 100); // Wrong named field
          }
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                "Record pattern named field 'value' not found in the record.")));
      });
  
      test('Record Pattern - Mismatch Type', () {
        final source = '''
          main() {
            var (a,) = 123; // Not a record
          }
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                "Expected a Record, but got int"))); // Assuming InterpretedRecord is not int
      });
  
      test('Combined Pattern - List of Records', () {
        final source = '''
          main() {
            var [(val: x), (val: y)] = [(val: 5), (val: 10)];
            return x + y; // 5 + 10 = 15
          }
        ''';
        expect(execute(source), equals(15));
      });
  
      test('Combined Pattern - Record with List and Map', () {
        final source = '''
          main() {
            var (list: [a,b], map: {'k': c}) = (list: [1, 2], map: {'k': 3});
            return a + b + c; // 1 + 2 + 3 = 6
          }
        ''';
        expect(execute(source), equals(6));
      });
    });
  
    test('Assignation par pattern (Record)', () {
      final source = '''
        main() {
          var a;
          var c;
          final record = (1, b: 2); // Crée un record interprété
          (a, b: c) = record; // Assignation par pattern
          return [a, c]; // Retourner les valeurs liées pour vérification
        }
      ''';
      final result = execute(source);
      expect(result, equals([1, 2]));
    });
  
    group('Switch Expressions', () {
      test('Basic constant match', () {
        final source = '''
          main() {
            var value = 2;
            var result = switch (value) {
              1 => "One",
              2 => "Two",
              _ => "Other"
            };
            return result;
          }
        ''';
        expect(execute(source), equals("Two"));
      });
  
      test('Default case match (_)', () {
        final source = '''
          main() {
            var value = 100;
            var result = switch (value) {
              1 => "One",
              2 => "Two",
              _ => "Other"
            };
            return result;
          }
        ''';
        expect(execute(source), equals("Other"));
      });
  
      test('Non-exhaustive switch expression throws error', () {
        final source = '''
          main() {
            var value = 3; // Pas de cas pour 3
            var result = switch (value) {
              1 => "One",
              2 => "Two"
              // Pas de cas par défaut
            };
            return result;
          }
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                'Switch expression was not exhaustive for value: 3'))); // Message d'erreur attendu
      });
  
      test('Pattern binding (Record)', () {
        final source = '''
          main() {
            var record = (val: 10, name: 'rec');
            var result = switch (record) {
              (val: var v, name: var n) => "Value: \$v, Name: \$n",
              _ => "Unknown record"
            };
            return result;
          }
        ''';
        expect(execute(source), equals("Value: 10, Name: rec"));
      });
  
      test('Pattern binding (List)', () {
        final source = '''
          main() {
            var list = [1, 5];
            var result = switch (list) {
              [var x, var y] => x + y,
              _ => -1
            };
            return result;
          }
        ''';
        expect(execute(source), equals(6));
      });
  
      test('Case with \'when\' clause (true)', () {
        final source = '''
          main() {
            var point = (x: 10, y: 5);
            var result = switch (point) {
              (x: var a, y: var b) when a > b => "X > Y",
              _ => "Other condition"
            };
            return result;
          }
        ''';
        expect(execute(source), equals("X > Y"));
      });
  
      test('Case with \'when\' clause (false)', () {
        final source = '''
          main() {
            var point = (x: 3, y: 8);
            var result = switch (point) {
              (x: var a, y: var b) when a > b => "X > Y",
              _ => "Other condition"
            };
            return result;
          }
        ''';
        expect(execute(source), equals("Other condition"));
      });
  
      test('When clause must be boolean', () {
        final source = '''
          main() {
            var val = 1;
            var result = switch (val) {
              1 when 1 => "oops", // Guard is not boolean
              _ => "ok"
            };
            return result;
          }
        ''';
        expect(() => execute(source),
            throwsRuntimeError(contains('must evaluate to a boolean')));
      });
    });
  
    group('Return Type Checking Tests', () {
      late D4rt interpreter;
  
      setUp(() {
        interpreter = D4rt();
        interpreter.registerBridgedClass(
            BridgedClass(
              nativeType: DummyNative,
              name: 'Dummy',
              constructors: {'': (v, p, n) => DummyNative()},
              methods: {
                'nativeMethod': (v, t, p, n) => (t as DummyNative).nativeMethod(),
              },
              getters: {},
              setters: {},
              staticGetters: {},
              staticSetters: {},
              staticMethods: {},
            ),
            'package:test/dummy.dart');
      });
  
      test('Correct return type (int)', () {
        final source = '''
          int getNumber() {
            return 10;
          }
          main() => getNumber();
        ''';
        expect(execute(source), equals(10));
      });
  
      test('Correct return type (String)', () {
        final source = '''
          String getText() {
            return "hello";
          }
          main() => getText();
        ''';
        expect(execute(source), equals("hello"));
      });
  
      test('Incorrect return type (String instead of int)', () {
        final source = '''
          int getNumber() {
            return "not a number"; // Error
          }
          main() => getNumber();
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                "A value of type 'String' can't be returned from the function 'getNumber' because it has a return type of 'int'.")));
      });
  
      test('Incorrect return type (int instead of String)', () {
        final source = '''
          String getText() {
            return 123; // Error
          }
          main() => getText();
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                "A value of type 'int' can't be returned from the function 'getText' because it has a return type of 'String'.")));
      });
  
      test('Correct return type (void, implicit)', () {
        final source = '''
          void doNothing() {
            // No return statement
          }
          main() {
            doNothing();
            return 'ok'; // Verify execution completes
          }
        ''';
        expect(execute(source), equals('ok'));
      });
  
      test('Correct return type (void, explicit null)', () {
        final source = '''
          void doNothingExplicit() {
            return; // Equivalent to return null;
          }
          main() {
            doNothingExplicit();
            return 'ok';
          }
        ''';
        expect(execute(source), equals('ok'));
      });
  
      test('Incorrect return type (non-null for void)', () {
        final source = '''
          void doNothingWrong() {
            return 5; // Error
          }
          main() => doNothingWrong();
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                "A value of type 'int' can't be returned from the function 'doNothingWrong' because it has a return type of 'void'.")));
      });
  
      test('Correct return type (dynamic, any value)', () {
        final source = '''
          dynamic getAnything() {
            return true;
          }
          main() => getAnything();
        ''';
        expect(execute(source), isTrue);
  
        final source2 = '''
          dynamic getAnythingElse() {
            return null;
          }
          main() => getAnythingElse();
        ''';
        expect(execute(source2), isNull);
      });
  
      test('Correct return type (Object, non-null)', () {
        final source = '''
          Object getObject() {
            return [1, 2];
          }
          main() => getObject();
        ''';
        expect(execute(source), equals([1, 2]));
      });
  
      test('Incorrect return type (null for Object)', () {
        final source = '''
          Object getObjectWrong() {
            return null; // Error
          }
          main() => getObjectWrong();
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                "A value of type 'Null' can't be returned from the function 'getObjectWrong' because it has a return type of 'Object'.")));
      });
  
      test('Correct return type (int? nullable, int value)', () {
        final source = '''
          int? getNullableInt() {
            return 42;
          }
          main() => getNullableInt();
        ''';
        expect(execute(source), equals(42));
      });
  
      test('Correct return type (int? nullable, null value)', () {
        final source = '''
          int? getNullableIntNull() {
            return null;
          }
          main() => getNullableIntNull();
        ''';
        expect(execute(source), isNull);
      });
  
      test('Incorrect return type (String for int?)', () {
        final source = '''
          int? getNullableIntWrong() {
            return "nope"; // Error
          }
          main() => getNullableIntWrong();
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                "A value of type 'String' can't be returned from the function 'getNullableIntWrong' because it has a return type of 'int?'.")));
      });
  
      test('Correct subtype (int for num)', () {
        final source = '''
          num getNum() {
            return 5; // int is subtype of num
          }
          main() => getNum();
        ''';
        expect(execute(source), equals(5));
      });
  
      test('Correct subtype (double for num)', () {
        final source = '''
          num getNumFloat() {
            return 3.14; // double is subtype of num
          }
          main() => getNumFloat();
        ''';
        expect(execute(source), equals(3.14));
      });
  
      test('Incorrect subtype (String for num)', () {
        final source = '''
          num getNumWrong() {
            return "text"; // Error
          }
          main() => getNumWrong();
        ''';
        expect(
            () => execute(source),
            throwsRuntimeError(contains(
                "A value of type 'String' can't be returned from the function 'getNumWrong' because it has a return type of 'num'.")));
      });
  
      test('Correct return type (Bridged type)', () {
        // Requires DummyNative and its bridge definition
        final source = '''
          import 'package:test/dummy.dart';
           Dummy getDummy() {
             return Dummy();
           }
           main() {
             final d = getDummy();
             return d.nativeMethod(); // Call method to ensure it's the right type
           }
         ''';
        expect(interpreter.execute(source: source),
            equals('DummyNative method result'));
      });
  
      test('Incorrect return type (int for Bridged type)', () {
        final source = '''
          import 'package:test/dummy.dart';
           Dummy getDummyWrong() {
             return 123; // Error
           }
           main() => getDummyWrong();
         ''';
        expect(
            () => interpreter.execute(source: source),
            throwsRuntimeError(contains(
                "A value of type 'int' can't be returned from the function 'getDummyWrong' because it has a return type of 'Dummy'.")));
      });
  
      test('Correct return type (null for Bridged type nullable)', () {
        final source = '''
          import 'package:test/dummy.dart';
           Dummy? getNullableDummy() {
             return null;
           }
           main() => getNullableDummy();
         ''';
        expect(interpreter.execute(source: source), isNull);
      });
    });
  }
  
  class DummyNative {
    String nativeMethod() => 'DummyNative method result';
  }
  