evaluate method

  1. @override
Future<DartBlockEvaluation> evaluate(
  1. DartBlockProgram solutionCore,
  2. DartBlockProgram answerCore
)
override

Implementation

@override
Future<DartBlockEvaluation> evaluate(
  DartBlockProgram solutionCore,
  DartBlockProgram answerCore,
) async {
  final solutionExecutor = DartBlockExecutor(solutionCore);
  final answerExecutor = DartBlockExecutor(answerCore);
  final List<(FunctionCallStatement, String?)> correctFunctionCalls = [];
  final List<(FunctionCallStatement, String?, String?, DartBlockException?)>
  wrongFunctionCalls = [];
  // Used to execute each function call once and catch any exceptions (step 1. below)
  final answerCoreCopy = answerCore.copy();
  for (final sampleFunctionCall in sampleFunctionCalls) {
    // if (answerCore.customFunctions.firstWhereOrNull((element) =>
    //         element.name == sampleFunctionCall.customFunctionName) ==
    //     null) {}
    try {
      /// 1. Try running the program using the given sample function call.
      /// If an exception occurs (infinite loop, stack overflow, etc.), catch
      /// it and log as a failed function call.
      answerCoreCopy.mainFunction.statements.clear();
      answerCoreCopy.mainFunction.statements.add(sampleFunctionCall);
      final copyExecutor = DartBlockExecutor(answerCoreCopy);
      await copyExecutor.execute();
      if (copyExecutor.thrownException != null) {
        wrongFunctionCalls.add((
          sampleFunctionCall,
          null,
          null,
          copyExecutor.thrownException,
        ));
        continue;
      }

      /// 2. Otherwise, the program does not crash outright with the function call.
      /// In that case, actually check the output of the function call and compare
      /// to expected output.
      final expectedValue = DartBlockFunctionCallValue.init(
        sampleFunctionCall,
      ).getValue(solutionExecutor);
      final actualValue = DartBlockFunctionCallValue.init(
        sampleFunctionCall,
      ).getValue(answerExecutor);
      final isCorrect = expectedValue == actualValue;
      if (isCorrect) {
        correctFunctionCalls.add((
          sampleFunctionCall,
          actualValue.toString(),
        ));
      } else {
        wrongFunctionCalls.add((
          sampleFunctionCall,
          expectedValue?.toString(),
          actualValue?.toString(),
          null,
        ));
      }
    } on DartBlockException catch (ex) {
      wrongFunctionCalls.add((sampleFunctionCall, null, null, ex));
    } on Exception catch (ex) {
      wrongFunctionCalls.add((
        sampleFunctionCall,
        null,
        null,
        DartBlockException.fromException(exception: ex),
      ));
    }
  }

  return DartBlockFunctionOutputEvaluation.init(
    correctFunctionCalls,
    wrongFunctionCalls,
  );
}