content: import 'package:test/test.dart';
  
  import '../../interpreter_test.dart';
  
  main() {
    group('List stdlib tests', () {
      test('List literal and basic properties', () {
        final result = execute(r'''
          main() {
            List<int> l1 = [1, 2, 3];
            List<dynamic> l2 = [];
            return [
              l1.length, l1.isEmpty, l1.isNotEmpty,
              l2.length, l2.isEmpty, l2.isNotEmpty
            ];
          }
        ''');
        expect(result, equals([3, false, true, 0, true, false]));
      });
  
      test('List index access [] and assignment []=', () {
        final result = execute(r'''
          main() {
            List<String> l = ['a', 'b', 'c'];
            var first = l[0];
            l[1] = 'B';
            return [first, l[1], l];
          }
        ''');
        expect(
            result,
            equals([
              'a',
              'B',
              ['a', 'B', 'c']
            ]));
      });
  
      test('List add and addAll', () {
        final result = execute(r'''
          main() {
            List<int> l = [1];
            l.add(2);
            l.addAll([3, 4]);
            return l;
          }
        ''');
        expect(result, equals([1, 2, 3, 4]));
      });
  
      test('List remove, removeAt, clear', () {
        final result = execute(r'''
          main() {
            List<String> l = ['x', 'y', 'z', 'y'];
            bool removedY = l.remove('y'); // Removes first 'y'
            var removedAt1 = l.removeAt(1); // Removes 'z'
            l.clear();
            return [removedY, removedAt1, l.length, l];
          }
        ''');
        expect(result, equals([true, 'z', 0, []]));
      });
  
      test('List contains, indexOf, lastIndexOf', () {
        final result = execute(r'''
          main() {
            List<int> l = [10, 20, 30, 20, 40];
            return [
              l.contains(20),
              l.contains(50),
              l.indexOf(20),       // First occurrence
              l.lastIndexOf(20),   // Last occurrence
              l.indexOf(50)        // Not found
            ];
          }
        ''');
        expect(result, equals([true, false, 1, 3, -1]));
      });
  
      test('List join', () {
        final result = execute(r'''
          main() {
            List<String> l = ['h', 'e', 'l', 'l', 'o'];
            return l.join('-');
          }
        ''');
        expect(result, equals('h-e-l-l-o'));
      });
  
      test('List sublist', () {
        final result = execute(r'''
          main() {
            List<int> l = [0, 1, 2, 3, 4, 5];
            return [l.sublist(1, 4), l.sublist(3)];
          }
        ''');
        expect(
            result,
            equals([
              [1, 2, 3],
              [3, 4, 5]
            ]));
      });
  
      group('List methods', () {
        test('insert', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 4];
          numbers.insert(2, 3);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 2, 3, 4]));
        });
  
        test('insertAll', () {
          const source = '''
         main() {
          List<int> numbers = [1, 4];
          numbers.insertAll(1, [2, 3]);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 2, 3, 4]));
        });
  
        test('setAll', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.setAll(1, [5, 6]);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 5, 6, 4]));
        });
  
        test('fillRange', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.fillRange(1, 3, 0);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 0, 0, 4]));
        });
  
        test('replaceRange', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.replaceRange(1, 3, [5, 6]);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 5, 6, 4]));
        });
  
        test('removeRange', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.removeRange(1, 3);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 4]));
        });
  
        test('retainWhere', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.retainWhere((n) => n % 2 == 0);
          return numbers;
        }
        ''';
          expect(execute(source), equals([2, 4]));
        });
  
        test('removeWhere', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.removeWhere((n) => n % 2 == 0);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 3]));
        });
  
        test('sort', () {
          const source = '''
         main() {
          List<int> numbers = [4, 2, 3, 1];
          numbers.sort();
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 2, 3, 4]));
        });
  
        test('shuffle', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.shuffle();
          return numbers; // Cannot check order, but check length and elements
        }
        ''';
          final result = execute(source) as List;
          expect(result, isA<List>());
          expect(result.length, equals(4));
          expect(result, containsAll([1, 2, 3, 4]));
        });
  
        test('reversed', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          return numbers.reversed.toList();
        }
        ''';
          expect(execute(source), equals([4, 3, 2, 1]));
        });
  
        test('asMap', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.asMap();
        }
        ''';
          expect(execute(source), equals({0: 1, 1: 2, 2: 3}));
        });
      });
  
      group('List methods - comprehensive', () {
        test('add', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2];
          numbers.add(3);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 2, 3]));
        });
  
        test('addAll', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2];
          numbers.addAll([3, 4]);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 2, 3, 4]));
        });
  
        test('remove', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          numbers.remove(2);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 3]));
        });
  
        test('removeAt', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          numbers.removeAt(1);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 3]));
        });
  
        test('removeLast', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          numbers.removeLast();
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 2]));
        });
  
        test('removeRange', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.removeRange(1, 3);
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 4]));
        });
  
        test('retainWhere', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          numbers.retainWhere((n) => n % 2 == 0);
          return numbers;
        }
        ''';
          expect(execute(source), equals([2, 4]));
        });
  
        test('indexOf', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 2];
          return numbers.indexOf(2);
        }
        ''';
          expect(execute(source), equals(1));
        });
  
        test('lastIndexOf', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 2];
          return numbers.lastIndexOf(2);
        }
        ''';
          expect(execute(source), equals(3));
        });
  
        test('sublist', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          return numbers.sublist(1, 3);
        }
        ''';
          expect(execute(source), equals([2, 3]));
        });
  
        test('contains', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.contains(2);
        }
        ''';
          expect(execute(source), equals(true));
        });
  
        test('length', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.length;
        }
        ''';
          expect(execute(source), equals(3));
        });
  
        test('isEmpty and isNotEmpty', () {
          const source = '''
         main() {
          List<int> numbers = [];
          return [numbers.isEmpty, numbers.isNotEmpty];
        }
        ''';
          expect(execute(source), equals([true, false]));
        });
  
        test('reverse', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.reversed.toList();
        }
        ''';
          expect(execute(source), equals([3, 2, 1]));
        });
  
        test('sort', () {
          const source = '''
         main() {
          List<int> numbers = [3, 1, 2];
          numbers.sort();
          return numbers;
        }
        ''';
          expect(execute(source), equals([1, 2, 3]));
        });
  
        test('shuffle', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          numbers.shuffle();
          return numbers; // Cannot check order, but check length and elements
        }
        ''';
          final result = execute(source) as List;
          expect(result, isA<List>());
          expect(result.length, equals(3));
          expect(result, containsAll([1, 2, 3]));
        });
  
        test('expand', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.expand((n) => [n, n * 2]).toList();
        }
        ''';
          expect(execute(source), equals([1, 2, 2, 4, 3, 6]));
        });
  
        test('forEach', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          var sum = 0;
          numbers.forEach((n) => sum += n);
          return sum;
        }
        ''';
          expect(execute(source), equals(6));
        });
  
        test('map', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.map((n) => n * 2).toList();
        }
        ''';
          expect(execute(source), equals([2, 4, 6]));
        });
  
        test('where', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3, 4];
          return numbers.where((n) => n % 2 == 0).toList();
        }
        ''';
          expect(execute(source), equals([2, 4]));
        });
  
        test('reduce', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.reduce((a, b) => a + b);
        }
        ''';
          expect(execute(source), equals(6));
        });
  
        test('fold', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.fold(0, (a, b) => a + b);
        }
        ''';
          expect(execute(source), equals(6));
        });
  
        test('join', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          return numbers.join(", ");
        }
        ''';
          expect(execute(source), equals('1, 2, 3'));
        });
  
        test('toSet', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 2, 3];
          return numbers.toSet().toList();
        }
        ''';
          final result = execute(source) as List;
          result.sort();
          expect(result, equals([1, 2, 3]));
        });
  
        test('toList', () {
          const source = '''
         main() {
          List<int> numbers = [1, 2, 3];
          var l = numbers.toList();
          l.add(4); // Modify to ensure it's a new list
          return [numbers, l]; // Return both to check independence
        }
        ''';
          expect(
              execute(source),
              equals([
                [1, 2, 3],
                [1, 2, 3, 4]
              ]));
        });
      });
  
      group('Iterable methods', () {
        test('cast', () {
          const source = '''
         main() {
          Iterable<dynamic> numbers = [1, 2, 3];
          Iterable<int> casted = numbers.cast<int>();
          return casted.toList();
        }
        ''';
          expect(execute(source), equals([1, 2, 3]));
        });
  
        test('followedBy', () {
          const source = '''
         main() {
          Iterable<int> numbers = [1, 2];
          Iterable<int> moreNumbers = numbers.followedBy([3, 4]);
          return moreNumbers.toList();
        }
        ''';
          expect(execute(source), equals([1, 2, 3, 4]));
        });
  
        test('elementAt', () {
          const source = '''
         main() {
          Iterable<int> numbers = [1, 2, 3];
          return numbers.elementAt(1);
        }
        ''';
          expect(execute(source), equals(2));
        });
      });
  
      group('Set methods', () {
        test('retainWhere', () {
          const source = '''
         main() {
          Set<int> numbers = {1, 2, 3, 4};
          numbers.retainWhere((n) => n % 2 == 0);
          return numbers.toList(); // Convert to list for stable comparison
        }
        ''';
          final result = execute(source) as List;
          result.sort();
          expect(result, equals([2, 4]));
        });
  
        test('removeWhere', () {
          const source = '''
         main() {
          Set<int> numbers = {1, 2, 3, 4};
          numbers.removeWhere((n) => n % 2 == 0);
          return numbers.toList(); // Convert to list for stable comparison
        }
        ''';
          final result = execute(source) as List;
          result.sort();
          expect(result, equals([1, 3]));
        });
      });
    });
  }
  