diff --git a/org.lflang.tests/src/org/lflang/tests/TestBase.java b/org.lflang.tests/src/org/lflang/tests/TestBase.java index 0f87d53cbc..6dfb4251c7 100644 --- a/org.lflang.tests/src/org/lflang/tests/TestBase.java +++ b/org.lflang.tests/src/org/lflang/tests/TestBase.java @@ -512,6 +512,18 @@ private ProcessBuilder getExecCommand(LFTest test) { } } case TS: { + var binPath = test.fileConfig.binPath; + var binaryName = nameOnly; + // Adjust binary extension if running on Window + if (System.getProperty("os.name").startsWith("Windows")) { + binaryName += ".exe"; + } + var fullPath = binPath.resolve(binaryName); + if (Files.exists(fullPath)) { + // If execution script exists, run it. + return new ProcessBuilder(fullPath.toString()).directory(binPath.toFile()); + } + // If execution script does not exist, run .js directly. var dist = test.fileConfig.getSrcGenPath().resolve("dist"); var file = dist.resolve(nameOnly + ".js"); if (Files.exists(file)) { diff --git a/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt b/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt index 90fe144950..975add1248 100644 --- a/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt +++ b/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt @@ -58,7 +58,7 @@ class TSGenerator( companion object { /** Path to the Cpp lib directory (relative to class path) */ - const val LIB_PATH = "/lib/TS" + const val LIB_PATH = "/lib/ts" /** * Names of the configuration files to check for and copy to the generated @@ -118,7 +118,7 @@ class TSGenerator( fileConfig.deleteDirectory(fileConfig.srcGenPath) for (runtimeFile in RUNTIME_FILES) { fileConfig.copyFileFromClassPath( - "/lib/ts/reactor-ts/src/core/$runtimeFile", + "$LIB_PATH/reactor-ts/src/core/$runtimeFile", tsFileConfig.tsCoreGenPath().resolve(runtimeFile).toString()) } @@ -126,7 +126,7 @@ class TSGenerator( * Check whether configuration files are present in the same directory * as the source file. For those that are missing, install a default * If the given filename is not present in the same directory as the source - * file, copy a default version of it from /lib/ts/. + * file, copy a default version of it from $LIB_PATH/. */ for (configFile in CONFIG_FILES) { val configFileDest = fileConfig.srcGenPath.resolve(configFile).toString() @@ -140,7 +140,7 @@ class TSGenerator( "No '" + configFile + "' exists in " + fileConfig.srcPath + ". Using default configuration." ) - fileConfig.copyFileFromClassPath("/lib/ts/$configFile", configFileDest) + fileConfig.copyFileFromClassPath("$LIB_PATH/$configFile", configFileDest) } } diff --git a/test/TypeScript/src/federated/HelloDistributed.lf b/test/TypeScript/src/federated/HelloDistributed.lf new file mode 100644 index 0000000000..78cd15f8d1 --- /dev/null +++ b/test/TypeScript/src/federated/HelloDistributed.lf @@ -0,0 +1,52 @@ +/** + * A test-version of distributed HelloWorld in the example directory, + * example/TypeScript/src/DistributedHelloWorld/HelloWorld.lf + * This is to make sure that the federated execution for TypeScript target + * always works when there is a relevant change. + * + * @author Edward A. Lee + * @author Hokeun Kim + */ +// TODO(hokeun): Add a check for the number of received messages to be exactly 2. +target TypeScript { + timeout: 2 secs +}; + +/** + * Reactor that generates a sequence of messages, one per second. + * The message will be a string consisting of a root string followed + * by a count. + * @param root The root string. + * @output message The message. + */ +reactor MessageGenerator(root:string("")) { + // Output type char* instead of string is used for dynamically + // allocated character arrays (as opposed to static constant strings). + output message:string; + state count:number(1); + // Send first message after 1 sec so that the startup reactions + // do not factor into the transport time measurement on the first message. + timer t(1 sec, 1 sec); + reaction(t) -> message {= + message = root + " " + count++; + console.log(`At time (elapsed) logical tag ${util.getElapsedLogicalTime()}, source sends message: ${message}`); + =} +} + +/** + * Reactor that prints the current tag and an incoming string. + * + * @input message The message. + */ +reactor PrintMessage { + input message:string; + reaction(message) {= + console.log(`PrintMessage: At (elapsed) logical time ${util.getElapsedLogicalTime()}, receiver receives: ${message}`); + =} +} + +federated reactor HelloDistributed { + source = new MessageGenerator(root = "Hello World"); + print = new PrintMessage(); + source.message -> print.message; +} \ No newline at end of file