mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-27 19:50:36 +02:00
[jsscripting] Add integration tests (#20517)
Signed-off-by: Florian Hotze <dev@florianhotze.com>
This commit is contained in:
+1
-1
@@ -508,8 +508,8 @@
|
||||
/bundles/org.openhab.voice.watsonstt/ @GiviMAD
|
||||
/bundles/org.openhab.voice.whisperstt/ @GiviMAD
|
||||
/itests/org.openhab.automation.groovyscripting.tests/ @wborn
|
||||
/itests/org.openhab.automation.jsscripting.tests/ @florian-h05
|
||||
/itests/org.openhab.automation.jsscriptingnashorn.tests/ @wborn
|
||||
/itests/org.openhab.binding.astro.tests/ @gerrieg
|
||||
/itests/org.openhab.binding.avmfritz.tests/ @cweitkamp
|
||||
/itests/org.openhab.binding.feed.tests/ @openhab/add-ons-maintainers
|
||||
/itests/org.openhab.binding.homeassistant.tests/ @ccutrer
|
||||
|
||||
@@ -153,6 +153,14 @@ mvn clean install -DwithResolver -DskipChecks
|
||||
|
||||
The build generates a `.jar` file per bundle in the respective bundle `/target` directory.
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
When having issues with running the integration tests, try the following steps:
|
||||
|
||||
1. Clear the bnd cache: Remove the `~/.bnd` directory.
|
||||
1. Rebuild the `bom` index: Execute `mvn clean install` in the [`bom`](bom) directory.
|
||||
1. Rebuild the `itests` index: Execute `mvn clean install -N` in the [`itests`](itests) directory.
|
||||
|
||||
### How to develop via an Integrated Development Environment (IDE)
|
||||
|
||||
We have assembled some step-by-step guides for different IDEs on our developer documentation website:
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory;
|
||||
* @author Jonathan Gilbert - Initial contribution
|
||||
* @author Florian Hotze - Improve logger name, Fix memory leak caused by exception logging
|
||||
*/
|
||||
class DebuggingGraalScriptEngine<T extends ScriptEngine & Invocable & AutoCloseable & Compilable & Lock>
|
||||
public class DebuggingGraalScriptEngine<T extends ScriptEngine & Invocable & AutoCloseable & Compilable & Lock>
|
||||
extends InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable<T> implements Lock {
|
||||
|
||||
private static final int STACK_TRACE_LENGTH = 5;
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
-include: ../itest-common.bndrun
|
||||
|
||||
Bundle-SymbolicName: ${project.artifactId}
|
||||
Fragment-Host: org.openhab.automation.jsscripting
|
||||
|
||||
Import-Package: \
|
||||
*
|
||||
|
||||
-runrequires: \
|
||||
bnd.identity;id='org.openhab.automation.jsscripting.tests',\
|
||||
bnd.identity;id='org.graalvm.js.js-language',\
|
||||
bnd.identity;id='org.graalvm.regex.regex'
|
||||
|
||||
-runblacklist: \
|
||||
bnd.identity;id='org.openhab.core.storage.json'
|
||||
|
||||
#
|
||||
# done
|
||||
#
|
||||
|
||||
-runbundles: \
|
||||
biz.aQute.tester.junit-platform;version='[7.2.1,7.2.2)',\
|
||||
ch.qos.logback.classic;version='[1.5.27,1.5.28)',\
|
||||
ch.qos.logback.core;version='[1.5.27,1.5.28)',\
|
||||
com.fasterxml.jackson.core.jackson-annotations;version='[2.21.0,2.21.1)',\
|
||||
com.fasterxml.jackson.core.jackson-core;version='[2.21.1,2.21.2)',\
|
||||
com.fasterxml.jackson.core.jackson-databind;version='[2.21.1,2.21.2)',\
|
||||
com.fasterxml.jackson.dataformat.jackson-dataformat-xml;version='[2.21.1,2.21.2)',\
|
||||
com.fasterxml.jackson.dataformat.jackson-dataformat-yaml;version='[2.21.1,2.21.2)',\
|
||||
com.google.gson;version='[2.13.2,2.13.3)',\
|
||||
com.sun.jna;version='[5.18.1,5.18.2)',\
|
||||
com.sun.xml.bind.jaxb-osgi;version='[2.3.9,2.3.10)',\
|
||||
de.focus_shift.jollyday-core;version='[1.8.1,1.8.2)',\
|
||||
de.focus_shift.jollyday-jackson;version='[1.8.1,1.8.2)',\
|
||||
io.methvin.directory-watcher;version='[0.19.1,0.19.2)',\
|
||||
jakarta.annotation-api;version='[2.1.1,2.1.2)',\
|
||||
jakarta.inject.jakarta.inject-api;version='[2.0.1,2.0.2)',\
|
||||
jakarta.xml.bind-api;version='[2.3.3,2.3.4)',\
|
||||
javax.measure.unit-api;version='[2.2.0,2.2.1)',\
|
||||
junit-jupiter-api;version='[5.14.2,5.14.3)',\
|
||||
junit-jupiter-engine;version='[5.14.2,5.14.3)',\
|
||||
junit-platform-commons;version='[1.14.2,1.14.3)',\
|
||||
junit-platform-engine;version='[1.14.2,1.14.3)',\
|
||||
junit-platform-launcher;version='[1.14.2,1.14.3)',\
|
||||
net.bytebuddy.byte-buddy;version='[1.17.7,1.17.8)',\
|
||||
net.bytebuddy.byte-buddy-agent;version='[1.17.7,1.17.8)',\
|
||||
org.apache.aries.spifly.dynamic.bundle;version='[1.3.7,1.3.8)',\
|
||||
org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\
|
||||
org.apache.felix.http.servlet-api;version='[1.2.0,1.2.1)',\
|
||||
org.apache.felix.scr;version='[2.2.6,2.2.7)',\
|
||||
org.apache.servicemix.specs.activation-api-1.2.1;version='[1.2.1,1.2.2)',\
|
||||
org.eclipse.equinox.event;version='[1.6.300,1.6.301)',\
|
||||
org.eclipse.jetty.http;version='[9.4.58,9.4.59)',\
|
||||
org.eclipse.jetty.io;version='[9.4.58,9.4.59)',\
|
||||
org.eclipse.jetty.security;version='[9.4.58,9.4.59)',\
|
||||
org.eclipse.jetty.server;version='[9.4.58,9.4.59)',\
|
||||
org.eclipse.jetty.servlet;version='[9.4.58,9.4.59)',\
|
||||
org.eclipse.jetty.util;version='[9.4.58,9.4.59)',\
|
||||
org.eclipse.jetty.util.ajax;version='[9.4.58,9.4.59)',\
|
||||
org.glassfish.hk2.osgi-resource-locator;version='[3.0.0,3.0.1)',\
|
||||
org.graalvm.js.js-language;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.js.js-scriptengine;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.polyglot.polyglot;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.sdk.collections;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.sdk.nativeimage;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.sdk.word;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.shadowed.icu4j;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.shadowed.xz;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.truffle.truffle-api;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.truffle.truffle-compiler;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.truffle.truffle-runtime;version='[25.0.1,25.0.2)',\
|
||||
org.graalvm.regex.regex;version='[25.0.1,25.0.2)',\
|
||||
org.hamcrest;version='[3.0.0,3.0.1)',\
|
||||
org.mockito.junit-jupiter;version='[5.21.0,5.21.1)',\
|
||||
org.mockito.mockito-core;version='[5.21.0,5.21.1)',\
|
||||
org.objectweb.asm;version='[9.9.0,9.9.1)',\
|
||||
org.objectweb.asm.commons;version='[9.6.0,9.6.1)',\
|
||||
org.objectweb.asm.tree;version='[9.6.0,9.6.1)',\
|
||||
org.objectweb.asm.tree.analysis;version='[9.6.0,9.6.1)',\
|
||||
org.objectweb.asm.util;version='[9.6.0,9.6.1)',\
|
||||
org.objenesis;version='[3.3.0,3.3.1)',\
|
||||
org.openhab.automation.jsscripting;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.automation.jsscripting.tests;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.addon;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.automation;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.automation.module.script;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.automation.module.script.rulesupport;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.config.core;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.ephemeris;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.io.console;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.semantics;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.test;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.thing;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.transform;version='[5.2.0,5.2.1)',\
|
||||
org.opentest4j;version='[1.3.0,1.3.1)',\
|
||||
org.ops4j.pax.logging.pax-logging-api;version='[2.3.2,2.3.3)',\
|
||||
org.osgi.service.component;version='[1.5.1,1.5.2)',\
|
||||
org.osgi.service.component.annotations;version='[1.5.1,1.5.2)',\
|
||||
org.osgi.service.event;version='[1.4.1,1.4.2)',\
|
||||
org.osgi.util.function;version='[1.2.0,1.2.1)',\
|
||||
org.osgi.util.promise;version='[1.3.0,1.3.1)',\
|
||||
org.threeten.extra;version='[1.8.0,1.8.1)',\
|
||||
org.yaml.snakeyaml;version='[2.5.0,2.5.1)',\
|
||||
si-quantity;version='[2.2.3,2.2.4)',\
|
||||
si-units;version='[2.2.3,2.2.4)',\
|
||||
stax2-api;version='[4.2.2,4.2.3)',\
|
||||
tech.units.indriya;version='[2.2.3,2.2.4)',\
|
||||
uom-lib-common;version='[2.2.0,2.2.1)',\
|
||||
xstream;version='[1.4.21,1.4.22)'
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.itests</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.itests</artifactId>
|
||||
<version>5.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.automation.jsscripting.tests</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Integration Tests :: JavaScript Scripting</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.automation.jsscripting</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- GraalVM dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.polyglot.polyglot</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.js.js-scriptengine</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.js.js-language</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.regex.regex</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.sdk.collections</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.sdk.nativeimage</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.sdk.jniutils</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.sdk.word</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.shadowed.icu4j</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.shadowed.json</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.shadowed.xz</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.tools.chromeinspector-tool</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.tools.profiler-tool</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.truffle.truffle-api</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.truffle.truffle-compiler</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.osgiify</groupId>
|
||||
<artifactId>org.graalvm.truffle.truffle-runtime</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.automation.jsscripting;
|
||||
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.openhab.automation.jsscripting.internal.GraalJSScriptEngineFactory;
|
||||
import org.openhab.automation.jsscripting.internal.JSScriptServiceUtil;
|
||||
import org.openhab.automation.jsscripting.internal.fs.watch.JSDependencyTracker;
|
||||
import org.openhab.core.automation.module.script.action.ScriptExecution;
|
||||
import org.openhab.core.scheduler.Scheduler;
|
||||
import org.openhab.core.service.WatchService;
|
||||
import org.openhab.core.test.java.JavaOSGiTest;
|
||||
|
||||
/**
|
||||
* Base class for GraalJS-related tests.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
@NonNullByDefault
|
||||
public abstract class GraalJSOSGiTest extends JavaOSGiTest {
|
||||
static final String SCRIPT_TYPE = "application/javascript";
|
||||
static final String SCRIPT_FILE_EXTENSION = "js";
|
||||
|
||||
final Map<String, Object> config;
|
||||
|
||||
@TempDir
|
||||
@NonNullByDefault({})
|
||||
Path tempDir;
|
||||
|
||||
@Mock
|
||||
@NonNullByDefault({})
|
||||
WatchService watchService;
|
||||
@Mock
|
||||
@NonNullByDefault({})
|
||||
Scheduler scheduler;
|
||||
@Mock
|
||||
@NonNullByDefault({})
|
||||
ScriptExecution scriptExecution;
|
||||
|
||||
@NonNullByDefault({})
|
||||
JSScriptServiceUtil jsScriptServiceUtil;
|
||||
@NonNullByDefault({})
|
||||
JSDependencyTracker jsDependencyTracker;
|
||||
@NonNullByDefault({})
|
||||
GraalJSScriptEngineFactory scriptEngineFactory;
|
||||
|
||||
GraalJSOSGiTest() {
|
||||
config = Map.of();
|
||||
}
|
||||
|
||||
GraalJSOSGiTest(Map<String, Object> config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() throws Exception {
|
||||
when(watchService.getWatchPath()).thenReturn(tempDir);
|
||||
|
||||
jsScriptServiceUtil = new JSScriptServiceUtil(scheduler, scriptExecution);
|
||||
jsDependencyTracker = new JSDependencyTracker(watchService);
|
||||
|
||||
scriptEngineFactory = new GraalJSScriptEngineFactory(jsScriptServiceUtil, jsDependencyTracker, config);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() throws Exception {
|
||||
scriptEngineFactory.dispose();
|
||||
scriptEngineFactory = null;
|
||||
|
||||
jsDependencyTracker.deactivate();
|
||||
jsDependencyTracker = null;
|
||||
|
||||
clearInvocations(watchService, scheduler, scriptExecution);
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.automation.jsscripting;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.automation.jsscripting.internal.DebuggingGraalScriptEngine;
|
||||
import org.openhab.automation.jsscripting.internal.OpenhabGraalJSScriptEngine;
|
||||
|
||||
/**
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GraalJSScriptEngineFactoryTest extends GraalJSOSGiTest {
|
||||
|
||||
@Test
|
||||
public void registersScriptTypeForJs() {
|
||||
final List<String> scriptTypes = scriptEngineFactory.getScriptTypes();
|
||||
|
||||
assertTrue(scriptTypes.contains(SCRIPT_TYPE));
|
||||
assertTrue(scriptTypes.contains(SCRIPT_FILE_EXTENSION));
|
||||
|
||||
assertFalse(scriptTypes.contains("application/x-python3"));
|
||||
assertFalse(scriptTypes.contains("application/javascript;version=ECMAScript-5.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createsScriptEngineForJs() {
|
||||
// main MIME type:
|
||||
try (DebuggingGraalScriptEngine<OpenhabGraalJSScriptEngine> scriptEngine = assertInstanceOf(
|
||||
DebuggingGraalScriptEngine.class, scriptEngineFactory.createScriptEngine(SCRIPT_TYPE))) {
|
||||
assertNotNull(scriptEngine);
|
||||
}
|
||||
// file extension:
|
||||
try (DebuggingGraalScriptEngine<OpenhabGraalJSScriptEngine> scriptEngine = assertInstanceOf(
|
||||
DebuggingGraalScriptEngine.class, scriptEngineFactory.createScriptEngine(SCRIPT_FILE_EXTENSION))) {
|
||||
assertNotNull(scriptEngine);
|
||||
}
|
||||
// backwards-compatibility with versioned MIME type:
|
||||
try (DebuggingGraalScriptEngine<OpenhabGraalJSScriptEngine> scriptEngine = assertInstanceOf(
|
||||
DebuggingGraalScriptEngine.class,
|
||||
scriptEngineFactory.createScriptEngine("application/javascript;version=ECMAScript-2021"))) {
|
||||
assertNotNull(scriptEngine);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotCreateScriptEngineForOtherLanguages() {
|
||||
@Nullable
|
||||
ScriptEngine scriptEngine = scriptEngineFactory
|
||||
.createScriptEngine("application/javascript;version=ECMAScript-5.1");
|
||||
assertNull(scriptEngine);
|
||||
|
||||
scriptEngine = scriptEngineFactory.createScriptEngine("application/x-python3");
|
||||
assertNull(scriptEngine);
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.automation.jsscripting;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.openhab.core.automation.module.script.ScriptEngineFactory.CONTEXT_KEY_DEPENDENCY_LISTENER;
|
||||
import static org.openhab.core.automation.module.script.ScriptEngineFactory.CONTEXT_KEY_ENGINE_IDENTIFIER;
|
||||
import static org.openhab.core.automation.module.script.ScriptEngineFactory.CONTEXT_KEY_EXTENSION_ACCESSOR;
|
||||
import static org.openhab.core.automation.module.script.internal.handler.AbstractScriptModuleHandler.CONTEXT_KEY_MODULE_TYPE_ID;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.openhab.core.automation.module.script.ScriptExtensionAccessor;
|
||||
import org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler;
|
||||
|
||||
/**
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class OpenhabGraalJSScriptEngineTest extends GraalJSOSGiTest {
|
||||
private static final String SCRIPT_FILENAME = "itest.js";
|
||||
private static final String RULE_UID = "itest";
|
||||
private static final String ENGINE_IDENTIFIER = "itest-engine";
|
||||
|
||||
private @Mock @NonNullByDefault({}) ScriptExtensionAccessor scriptExtensionAccessor;
|
||||
|
||||
private @NonNullByDefault({}) ScriptEngine scriptEngine;
|
||||
|
||||
OpenhabGraalJSScriptEngineTest() {
|
||||
super(Map.of("injectionEnabledV2", 0, "injectionCachingEnabled", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
public void beforeEach() throws Exception {
|
||||
super.beforeEach();
|
||||
|
||||
scriptEngine = Objects.requireNonNull(scriptEngineFactory.createScriptEngine(SCRIPT_TYPE),
|
||||
"Failed to create script engine for script type: " + SCRIPT_TYPE);
|
||||
ScriptContext context = scriptEngine.getContext();
|
||||
context.setAttribute(CONTEXT_KEY_ENGINE_IDENTIFIER, ENGINE_IDENTIFIER, ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute(CONTEXT_KEY_EXTENSION_ACCESSOR, scriptExtensionAccessor, ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute(CONTEXT_KEY_DEPENDENCY_LISTENER, jsDependencyTracker.getTracker(ENGINE_IDENTIFIER),
|
||||
ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@AfterEach
|
||||
public void afterEach() throws Exception {
|
||||
if (scriptEngine instanceof AutoCloseable closeable) {
|
||||
closeable.close();
|
||||
}
|
||||
scriptEngine = null;
|
||||
|
||||
super.afterEach();
|
||||
}
|
||||
|
||||
private void setFileContext() {
|
||||
ScriptContext context = scriptEngine.getContext();
|
||||
context.setAttribute("javax.script.filename", SCRIPT_FILENAME, ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
|
||||
private void setScriptActionContext() {
|
||||
ScriptContext context = scriptEngine.getContext();
|
||||
context.setAttribute(CONTEXT_KEY_MODULE_TYPE_ID, ScriptActionHandler.TYPE_ID, ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute("ruleUID", RULE_UID, ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evaluatesBasicExpressions() throws ScriptException {
|
||||
setFileContext();
|
||||
|
||||
// Boolean
|
||||
assertTrue((Boolean) scriptEngine.eval("(false && true) || true"));
|
||||
assertFalse((Boolean) scriptEngine.eval("(true || false) && false"));
|
||||
// Arithmetic
|
||||
assertEquals(10, ((Number) scriptEngine.eval("5 + 5")).intValue());
|
||||
assertEquals(2.5, ((Number) scriptEngine.eval("5 / 2")).doubleValue(), 0.001);
|
||||
// Comparisons
|
||||
assertTrue((Boolean) scriptEngine.eval("'apple' !== 'orange'"));
|
||||
assertTrue((Boolean) scriptEngine.eval("10 >= 10"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadsOpenhabJsLibrary() {
|
||||
setFileContext();
|
||||
|
||||
String script = """
|
||||
const { utils } = require('openhab');
|
||||
if (!utils.OPENHAB_JS_VERSION) {
|
||||
throw new Error('OPENHAB_JS_VERSION is undefined/null');
|
||||
}
|
||||
""";
|
||||
assertDoesNotThrow(() -> scriptEngine.eval(script));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwsOnScriptLoadingInvalidLibrary() {
|
||||
setFileContext();
|
||||
|
||||
String script = "const { foo } = require('bar');";
|
||||
assertThrows(ScriptException.class, () -> scriptEngine.eval(script));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwsScriptExceptionOnJsError() {
|
||||
setFileContext();
|
||||
|
||||
String script = "throw new Error('JS Error');";
|
||||
assertThrows(ScriptException.class, () -> scriptEngine.eval(script));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperAllowsForLetConstInScriptActions() {
|
||||
setScriptActionContext();
|
||||
|
||||
String script = """
|
||||
const foo = 'Hello';
|
||||
const bar = 'World';
|
||||
const result = `${foo} ${bar}`;
|
||||
""";
|
||||
|
||||
// if let/const are allowed in script actions, we can execute scripts containing let/const more than once
|
||||
assertDoesNotThrow(() -> scriptEngine.eval(script));
|
||||
assertDoesNotThrow(() -> scriptEngine.eval(script));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperAllowsForReturnInScriptActions() {
|
||||
setScriptActionContext();
|
||||
|
||||
String script = "return true;";
|
||||
assertDoesNotThrow(() -> scriptEngine.eval(script));
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
<modules>
|
||||
<module>org.openhab.automation.groovyscripting.tests</module>
|
||||
<module>org.openhab.automation.jsscripting.tests</module>
|
||||
<module>org.openhab.automation.jsscriptingnashorn.tests</module>
|
||||
<module>org.openhab.binding.avmfritz.tests</module>
|
||||
<module>org.openhab.binding.feed.tests</module>
|
||||
|
||||
Reference in New Issue
Block a user