registerLadderTests function

void registerLadderTests({
  1. required MontyPlatform createPlatform(),
  2. required Directory fixtureDir,
})

Registers ladder test groups for all tiers in fixtureDir.

Call this from a backend's ladder test file:

void main() {
  registerLadderTests(
    createPlatform: () => MyPlatform(),
    fixtureDir: Directory('../../test/fixtures/python_ladder'),
  );
}

Each fixture is run through the appropriate runner (simple, error, or iterative) based on its fixture keys. xfail fixtures are expected to fail and will XPASS-fail if they unexpectedly pass.

Implementation

void registerLadderTests({
  required MontyPlatform Function() createPlatform,
  required Directory fixtureDir,
}) {
  final tiers = loadLadderFixtures(fixtureDir);

  for (final (tierName, fixtures) in tiers) {
    group(tierName, () {
      for (final fixture in fixtures) {
        final id = fixture['id'] as int;
        final name = fixture['name'] as String;
        final code = fixture['code'] as String;
        final expectError = fixture['expectError'] as bool? ?? false;
        final xfail = fixture['xfail'] as String?;

        test('#$id: $name', () async {
          final monty = createPlatform();

          try {
            if (xfail != null) {
              var passed = false;
              try {
                if (fixture['externalFunctions'] != null) {
                  await runIterativeFixture(monty, fixture);
                } else if (expectError) {
                  await runErrorFixture(monty, code, fixture);
                } else {
                  await runSimpleFixture(monty, code, fixture);
                }
                passed = true;
              } on Object catch (_) {
                // Expected failure — xfail working as intended
              }
              if (passed) {
                fail(
                  'XPASS: #$id "$name" unexpectedly passed '
                  '(xfail: $xfail)',
                );
              }
            } else {
              if (fixture['externalFunctions'] != null) {
                await runIterativeFixture(monty, fixture);
              } else if (expectError) {
                await runErrorFixture(monty, code, fixture);
              } else {
                await runSimpleFixture(monty, code, fixture);
              }
            }
          } finally {
            await monty.dispose();
          }
        });
      }
    });
  }
}