Bug 576039: [headless] adapt script execution result to an integer

  before trying to parse a result, we should try to adapt it to an
  integer.

Change-Id: Ibf5c63524b839709a20047bf669818d6757fd5ee
diff --git a/plugins/org.eclipse.ease.lang.unittest/plugin.xml b/plugins/org.eclipse.ease.lang.unittest/plugin.xml
index a5d08ee..650430c 100644
--- a/plugins/org.eclipse.ease.lang.unittest/plugin.xml
+++ b/plugins/org.eclipse.ease.lang.unittest/plugin.xml
@@ -82,5 +82,15 @@
             name="JUnit">
       </generator>
    </extension>
+   <extension
+         point="org.eclipse.core.runtime.adapters">
+      <factory
+            adaptableType="org.eclipse.ease.lang.unittest.runtime.ITestSuite"
+            class="org.eclipse.ease.lang.unittest.adapters.HeadlessResultAdapter">
+         <adapter
+               type="java.lang.Integer">
+         </adapter>
+      </factory>
+   </extension>
 
 </plugin>
diff --git a/plugins/org.eclipse.ease.lang.unittest/src/org/eclipse/ease/lang/unittest/adapters/HeadlessResultAdapter.java b/plugins/org.eclipse.ease.lang.unittest/src/org/eclipse/ease/lang/unittest/adapters/HeadlessResultAdapter.java
new file mode 100644
index 0000000..43ad8c8
--- /dev/null
+++ b/plugins/org.eclipse.ease.lang.unittest/src/org/eclipse/ease/lang/unittest/adapters/HeadlessResultAdapter.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Christian Pontesegger and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Christian Pontesegger - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ease.lang.unittest.adapters;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.ease.lang.unittest.runtime.ITestSuite;
+
+public class HeadlessResultAdapter implements IAdapterFactory {
+
+	@Override
+	public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+		if ((adaptableObject instanceof ITestSuite) && (Integer.class.equals(adapterType))) {
+
+			switch (((ITestSuite) adaptableObject).getStatus()) {
+			case ERROR:
+				return (T) Integer.valueOf(200);
+			case FAILURE:
+				return (T) Integer.valueOf(100);
+			default:
+				return (T) Integer.valueOf(0);
+			}
+		}
+
+		return null;
+	}
+
+	@Override
+	public Class<?>[] getAdapterList() {
+		return new Class<?>[] { ITestSuite.class };
+	}
+}
diff --git a/plugins/org.eclipse.ease/src/org/eclipse/ease/applications/RunHeadlessScript.java b/plugins/org.eclipse.ease/src/org/eclipse/ease/applications/RunHeadlessScript.java
index 673f16d..8bd896f 100644
--- a/plugins/org.eclipse.ease/src/org/eclipse/ease/applications/RunHeadlessScript.java
+++ b/plugins/org.eclipse.ease/src/org/eclipse/ease/applications/RunHeadlessScript.java
@@ -26,6 +26,7 @@
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Adapters;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Platform;
@@ -188,9 +189,12 @@
 
 	private int getScriptResult(final Object result) {
 		if (result != null) {
-			if (ScriptResult.VOID.equals(result)) {
+			if (ScriptResult.VOID.equals(result))
 				return 0;
-			}
+
+			final Integer adaptedResult = Adapters.adapt(result, Integer.class);
+			if (adaptedResult != null)
+				return adaptedResult;
 
 			try {
 				return Integer.parseInt(result.toString());
diff --git a/tests/org.eclipse.ease.lang.unittest.test/META-INF/MANIFEST.MF b/tests/org.eclipse.ease.lang.unittest.test/META-INF/MANIFEST.MF
index cd50b5d..a811000 100644
--- a/tests/org.eclipse.ease.lang.unittest.test/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.ease.lang.unittest.test/META-INF/MANIFEST.MF
@@ -6,4 +6,5 @@
 Automatic-Module-Name: org.eclipse.ease.lang.unittest.test
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Require-Bundle: org.junit.jupiter.api;bundle-version="5.5.0",
- org.eclipse.ease.lang.javascript.rhino
+ org.eclipse.ease.lang.javascript.rhino,
+ org.mockito
diff --git a/tests/org.eclipse.ease.lang.unittest.test/src/org/eclipse/ease/lang/unittest/adapters/HeadlessResultAdapterTest.java b/tests/org.eclipse.ease.lang.unittest.test/src/org/eclipse/ease/lang/unittest/adapters/HeadlessResultAdapterTest.java
new file mode 100644
index 0000000..c3b48b6
--- /dev/null
+++ b/tests/org.eclipse.ease.lang.unittest.test/src/org/eclipse/ease/lang/unittest/adapters/HeadlessResultAdapterTest.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Christian Pontesegger and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Christian Pontesegger - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ease.lang.unittest.adapters;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.eclipse.core.runtime.Adapters;
+import org.eclipse.ease.lang.unittest.runtime.ITestSuite;
+import org.eclipse.ease.lang.unittest.runtime.TestStatus;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+public class HeadlessResultAdapterTest {
+
+	@Test
+	@DisplayName("getAdapterList() returns only ITestSuite")
+	public void getAdapterList_returns_only_ITestSuite() {
+		assertArrayEquals(new Class<?>[] { ITestSuite.class }, new HeadlessResultAdapter().getAdapterList());
+	}
+
+	@Test
+	@DisplayName("getAdapter() declines to adapt generic object")
+	public void getAdapter_declines_to_adapt_generic_object() {
+		assertNull(new HeadlessResultAdapter().getAdapter(new Object(), Integer.class));
+	}
+
+	@Test
+	@DisplayName("getAdapter() declines to adapt to Boolean")
+	public void getAdapter_declines_to_adapt_to_Boolean() {
+		final ITestSuite suite = mock(ITestSuite.class);
+		assertNull(new HeadlessResultAdapter().getAdapter(suite, Boolean.class));
+	}
+
+	@Test
+	@DisplayName("getAdapter(PASS) = 0")
+	public void getAdapter_adapts_testsuite_with_no_errors_to_0() {
+		final ITestSuite suite = mock(ITestSuite.class);
+		when(suite.getStatus()).thenReturn(TestStatus.PASS);
+
+		assertEquals(0, new HeadlessResultAdapter().getAdapter(suite, Integer.class));
+	}
+
+	@Test
+	@DisplayName("getAdapter(FAILURE) = 100")
+	public void getAdapter_adapts_testsuite_with_failures_to_100() {
+		final ITestSuite suite = mock(ITestSuite.class);
+		when(suite.getStatus()).thenReturn(TestStatus.FAILURE);
+
+		assertEquals(100, new HeadlessResultAdapter().getAdapter(suite, Integer.class));
+	}
+
+	@Test
+	@DisplayName("getAdapter(ERROR) = 200")
+	public void getAdapter_adapts_testsuite_with_errors_to_200() {
+		final ITestSuite suite = mock(ITestSuite.class);
+		when(suite.getStatus()).thenReturn(TestStatus.ERROR);
+
+		assertEquals(200, new HeadlessResultAdapter().getAdapter(suite, Integer.class));
+	}
+
+	@Test
+	@DisplayName("adapter can be called via adapter framework")
+	public void adapter_can_be_called_via_adapter_framework() {
+		final ITestSuite suite = mock(ITestSuite.class);
+		when(suite.getStatus()).thenReturn(TestStatus.PASS);
+
+		assertEquals(0, Adapters.adapt(suite, Integer.class));
+	}
+}