package org.shedlang.compiler.config; import org.junit.jupiter.api.Test; import org.shedlang.compiler.config.errors.ConfigError; import org.shedlang.compiler.typechecker.TypeInfos; import org.shedlang.compiler.types.*; import java.io.IOException; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.zwobble.precisely.AssertThat.assertThat; import static org.zwobble.precisely.Matchers.equalTo; public class ConfigCheckerTests { @Test public void whenMainFunctionExistsWithCorrectTypeThenBinConfigIsValid() throws IOException { var binConfig = new BinConfig("x", NamespaceName.of("Main")); var typeInfos = TypeInfos.EMPTY .addNamespaceTypeInfo( NamespaceName.of("Main"), NamespaceTypeInfo.builder() .addField( "main", FunctionType.builder() .withEffect(Effects.IO) .withReturnType(Types.UNIT) .build() ) .build() ); ConfigChecker.configCheckBin(binConfig, typeInfos); } @Test public void whenMainNamespaceSourceIsMissingThenBinConfigIsInvalid() throws IOException { var binConfig = new BinConfig("x", NamespaceName.of("Main")); var typeInfos = TypeInfos.EMPTY; var error = assertThrows( ConfigError.class, () -> ConfigChecker.configCheckBin(binConfig, typeInfos) ); assertThat(error.getMessage(), equalTo("Namespace Main not found")); } @Test public void whenMainFunctionIsMissingThenBinConfigIsInvalid() throws IOException { var binConfig = new BinConfig("x", NamespaceName.of("Main")); var typeInfos = TypeInfos.EMPTY .addNamespaceTypeInfo( NamespaceName.of("Main"), NamespaceTypeInfo.builder() .addField( "main2", FunctionType.builder() .withEffect(Effects.IO) .withReturnType(Types.UNIT) .build() ) .build() ); var error = assertThrows( ConfigError.class, () -> ConfigChecker.configCheckBin(binConfig, typeInfos) ); assertThat(error.getMessage(), equalTo("Namespace Main has no field main")); } @Test public void whenMainFunctionHasWrongTypeThenBinConfigIsInvalid() throws IOException { var binConfig = new BinConfig("x", NamespaceName.of("Main")); var typeInfos = TypeInfos.EMPTY .addNamespaceTypeInfo( NamespaceName.of("Main"), NamespaceTypeInfo.builder() .addField( "main", FunctionType.builder() .withEffect(Effects.IO) .withReturnType(Types.STRING) .build() ) .build() ); var error = assertThrows( ConfigError.class, () -> ConfigChecker.configCheckBin(binConfig, typeInfos) ); assertThat( error.getMessage(), equalTo("main function should have type fn () ! Io -> Unit, but Main.main has type fn () ! Io -> String") ); } }