mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 10:21:41 +03:00
visualizationResultToBytes converts anything that looks like a string (#4045)
Use `InteropLibrary.isString` and `asString` to convert any string value to `byte[]` # Important Notes Also contains a support for `Metadata.assertInCode` to help locating the right place in the code snippets.
This commit is contained in:
parent
ccde47e24e
commit
917176873d
@ -1612,6 +1612,7 @@ lazy val `runtime-with-polyglot` =
|
||||
"ENSO_TEST_DISABLE_IR_CACHE" -> "false"
|
||||
),
|
||||
libraryDependencies ++= Seq(
|
||||
"org.graalvm.sdk" % "graal-sdk" % graalVersion % "provided",
|
||||
"org.scalatest" %% "scalatest" % scalatestVersion % Test
|
||||
)
|
||||
)
|
||||
|
@ -27,11 +27,6 @@ json_from_table table =
|
||||
Arguments:
|
||||
- value: the value to be visualized.
|
||||
process_to_json_text : Any -> Text
|
||||
process_to_json_text value =
|
||||
json = case value of
|
||||
Table.Value _ -> json_from_table value . to_text
|
||||
_ -> value.to_json
|
||||
|
||||
## Workaround so that the JS String is converted to a Text
|
||||
https://www.pivotaltracker.com/story/show/184061302
|
||||
"" + json
|
||||
process_to_json_text value = case value of
|
||||
Table.Value _ -> json_from_table value . to_text
|
||||
_ -> value.to_json
|
||||
|
@ -68,6 +68,4 @@ from_value value =
|
||||
- value: the value to be visualized.
|
||||
process_to_json_text : Any -> Text
|
||||
process_to_json_text value =
|
||||
## Workaround so that the JS String is converted to a Text
|
||||
https://www.pivotaltracker.com/story/show/184061302
|
||||
"" + (from_value value . to_json)
|
||||
from_value value . to_json
|
||||
|
@ -3,10 +3,7 @@ import project.Helpers
|
||||
|
||||
## PRIVATE
|
||||
Default visualization preprocessor.
|
||||
default_preprocessor x =
|
||||
## Workaround so that the JS String is converted to a Text
|
||||
https://www.pivotaltracker.com/story/show/184061302
|
||||
"" + x.to_default_visualization_data
|
||||
default_preprocessor x = x.to_default_visualization_data
|
||||
|
||||
## PRIVATE
|
||||
Error visualization preprocessor.
|
||||
@ -18,6 +15,4 @@ error_preprocessor x =
|
||||
full_message = message + if stack_trace.length > 1 then " (" + stack_trace.at 1 . trim +")" else ""
|
||||
JS_Object.from_pairs [['kind', 'Dataflow'], ['message', full_message]] . to_json
|
||||
|
||||
## Workaround so that the JS String is converted to a Text
|
||||
https://www.pivotaltracker.com/story/show/184061302
|
||||
"" + if result.is_error then result.catch else ok
|
||||
if result.is_error then result.catch else ok
|
||||
|
@ -29,11 +29,7 @@ prepare_visualization x = Helpers.recover_errors <|
|
||||
expected_enso_type = find_expected_enso_type_for_sql e.second
|
||||
JS_Object.from_pairs [["value", value], ["actual_type", actual_type], ["expected_sql_type", expected_sql_type], ["expected_enso_type", expected_enso_type]]
|
||||
dialect = x.connection.dialect.name
|
||||
json = JS_Object.from_pairs [["dialect", dialect], ["code", code], ["interpolations", mapped]] . to_text
|
||||
|
||||
## Workaround so that the JS String is converted to a Text
|
||||
https://www.pivotaltracker.com/story/show/184061302
|
||||
"" + json
|
||||
JS_Object.from_pairs [["dialect", dialect], ["code", code], ["interpolations", mapped]] . to_text
|
||||
|
||||
## PRIVATE
|
||||
|
||||
|
@ -202,6 +202,4 @@ process_to_json_text value bounds=Nothing limit=Nothing =
|
||||
_ : Vector -> json_from_vector value bounds limit
|
||||
_ -> json_from_vector value.to_vector bounds limit
|
||||
|
||||
## Workaround so that the JS String is converted to a Text
|
||||
https://www.pivotaltracker.com/story/show/184061302
|
||||
"" + json
|
||||
json
|
||||
|
@ -30,17 +30,13 @@ prepare_visualization y max_rows=1000 = Helpers.recover_errors <|
|
||||
included_rows = dataframe.row_count
|
||||
index = Dataframe_Column.from_vector "" (Vector.new included_rows i->i)
|
||||
|
||||
## Workaround so that the JS String is converted to a Text
|
||||
https://www.pivotaltracker.com/story/show/184061302
|
||||
"" + make_json dataframe [index] all_rows_count
|
||||
make_json dataframe [index] all_rows_count
|
||||
|
||||
_ : Database_Table ->
|
||||
df = x.read max_rows
|
||||
all_rows_count = x.row_count
|
||||
|
||||
## Workaround so that the JS String is converted to a Text
|
||||
https://www.pivotaltracker.com/story/show/184061302
|
||||
"" + make_json df [] all_rows_count
|
||||
make_json df [] all_rows_count
|
||||
|
||||
# We display columns as 1-column tables.
|
||||
_ : Dataframe_Column ->
|
||||
|
@ -0,0 +1,46 @@
|
||||
package org.enso.interpreter.test.instrument;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Paths;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class VerifyJavaScriptIsAvailableTest {
|
||||
private static Context ctx;
|
||||
|
||||
@BeforeClass
|
||||
public static void initEnsoContext() {
|
||||
ctx =
|
||||
Context.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.allowIO(true)
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
Paths.get("../../distribution/component").toFile().getAbsolutePath())
|
||||
.logHandler(OutputStream.nullOutputStream())
|
||||
.allowAllAccess(true)
|
||||
.build();
|
||||
assertNotNull("Enso language is supported", ctx.getEngine().getLanguages().get("enso"));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void closeEnsoContext() throws Exception {
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void javaScriptIsPresent() {
|
||||
var js = ctx.getEngine().getLanguages().get("js");
|
||||
assertNotNull("JavaScript is available", js);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensoIsPresent() {
|
||||
var enso = ctx.getEngine().getLanguages().get("enso");
|
||||
assertNotNull("Enso is available", enso);
|
||||
}
|
||||
}
|
@ -2807,6 +2807,9 @@ class RuntimeVisualizationsTest
|
||||
|main =
|
||||
| [Warning.attach "y" 42]
|
||||
|""".stripMargin.linesIterator.mkString("\n")
|
||||
|
||||
metadata.assertInCode(idMain, code, "\n [Warning.attach \"y\" 42]")
|
||||
|
||||
val contents = metadata.appendToCode(code)
|
||||
val mainFile = context.writeMain(contents)
|
||||
|
||||
|
@ -0,0 +1,36 @@
|
||||
package org.enso.interpreter.instrument.job;
|
||||
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
import org.enso.interpreter.runtime.error.WithWarnings;
|
||||
|
||||
public final class VisualizationResult {
|
||||
private VisualizationResult() {
|
||||
}
|
||||
|
||||
public static byte[] visualizationResultToBytes(Object value) {
|
||||
if (value instanceof byte[] arr) {
|
||||
return arr;
|
||||
}
|
||||
if (value instanceof String text) {
|
||||
return text.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
if (value instanceof Text text) {
|
||||
return visualizationResultToBytes(text.toString());
|
||||
}
|
||||
if (value instanceof WithWarnings warn) {
|
||||
return visualizationResultToBytes(warn.getValue());
|
||||
}
|
||||
var iop = InteropLibrary.getUncached();
|
||||
if (iop.isString(value)) {
|
||||
try {
|
||||
return visualizationResultToBytes(iop.asString(value));
|
||||
} catch (UnsupportedMessageException ex) {
|
||||
// fallthru
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -17,19 +17,13 @@ import org.enso.interpreter.instrument._
|
||||
import org.enso.interpreter.node.callable.FunctionCallInstrumentationNode.FunctionCall
|
||||
import org.enso.interpreter.runtime.`type`.Types
|
||||
import org.enso.interpreter.runtime.control.ThreadInterruptedException
|
||||
import org.enso.interpreter.runtime.data.text.Text
|
||||
import org.enso.interpreter.runtime.error.{
|
||||
DataflowError,
|
||||
PanicSentinel,
|
||||
WithWarnings
|
||||
}
|
||||
import org.enso.interpreter.runtime.error.{DataflowError, PanicSentinel}
|
||||
import org.enso.interpreter.service.error._
|
||||
import org.enso.polyglot.LanguageInfo
|
||||
import org.enso.polyglot.runtime.Runtime.Api
|
||||
import org.enso.polyglot.runtime.Runtime.Api.ContextId
|
||||
|
||||
import java.io.File
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.UUID
|
||||
import java.util.function.Consumer
|
||||
import java.util.logging.Level
|
||||
@ -528,26 +522,15 @@ object ProgramExecutionSupport {
|
||||
* @return either a byte array representing the visualization result or an
|
||||
* error
|
||||
*/
|
||||
@scala.annotation.tailrec
|
||||
private def visualizationResultToBytes(
|
||||
value: AnyRef
|
||||
): Either[VisualisationException, Array[Byte]] =
|
||||
value match {
|
||||
case text: String =>
|
||||
Right(text.getBytes(StandardCharsets.UTF_8))
|
||||
case text: Text =>
|
||||
Right(text.toString.getBytes(StandardCharsets.UTF_8))
|
||||
case bytes: Array[Byte] =>
|
||||
Right(bytes)
|
||||
case withWarnings: WithWarnings =>
|
||||
visualizationResultToBytes(withWarnings.getValue)
|
||||
case other =>
|
||||
Left(
|
||||
new VisualisationException(
|
||||
s"Cannot encode ${other.getClass} to byte array."
|
||||
)
|
||||
)
|
||||
}
|
||||
): Either[VisualisationException, Array[Byte]] = {
|
||||
Option(VisualizationResult.visualizationResultToBytes(value)).toRight(
|
||||
new VisualisationException(
|
||||
s"Cannot encode ${value.getClass} to byte array."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Extract method pointer information from the expression value.
|
||||
*
|
||||
|
@ -0,0 +1,46 @@
|
||||
package org.enso.interpreter.test.instrument;
|
||||
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.TruffleObject;
|
||||
import com.oracle.truffle.api.library.ExportLibrary;
|
||||
import com.oracle.truffle.api.library.ExportMessage;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Paths;
|
||||
import org.enso.interpreter.instrument.job.VisualizationResult;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ConvertAsStringObjectTest {
|
||||
@Test
|
||||
public void conversionOfStringObject() {
|
||||
var wrap = new AsString("Hello");
|
||||
var wrapRes = VisualizationResult.visualizationResultToBytes(wrap);
|
||||
assertNotNull("Special String object converted", wrapRes);
|
||||
var directRes = VisualizationResult.visualizationResultToBytes("Hello");
|
||||
assertArrayEquals("Both arrays are the same", wrapRes, directRes);
|
||||
}
|
||||
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
static class AsString implements TruffleObject {
|
||||
private final String value;
|
||||
|
||||
private AsString(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
boolean isString() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
String asString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
@ -41,4 +41,24 @@ class Metadata {
|
||||
*/
|
||||
def appendToCode(code: String): String =
|
||||
s"$code\n\n\n#### METADATA ####\n$toJsonString\n[]"
|
||||
|
||||
/** Checks whether given UUID is assigned to expected string
|
||||
* @param uuid the UUID to search for; defined by {@code #addItem}
|
||||
* @param code whole code to search in
|
||||
* @param expected the text that should be assigned to the UUID
|
||||
*/
|
||||
def assertInCode(uuid: UUID, code: String, expected: String): Unit = {
|
||||
for (item <- items) {
|
||||
if (item.id == uuid) {
|
||||
val real = code.substring(item.start, item.start + item.len)
|
||||
if (real != expected) {
|
||||
throw new AssertionError(
|
||||
"Expecting " + expected + " but found '" + real + "'"
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
throw new AssertionError("UUID " + uuid + " not found")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user