From b33ae479dd18db04424cb88705a0b818ce78efcd Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 25 May 2023 10:18:46 +0200 Subject: [PATCH] Various test improvements to increase coverage and speed things up (#6820) --- .../Base/0.0.0-dev/src/Data/Interval.enso | 2 +- .../src/Data/Text/Regex/Pattern.enso | 4 +- .../Database/0.0.0-dev/src/Data/Table.enso | 2 +- .../interpreter/test/MetaIsAPolyglotTest.java | 13 +++ .../test/MetaObjectPolyglotTest.java | 13 +++ .../org/enso/compiler/EnsoCompilerTest.java | 8 +- .../org/enso/interpreter/test/EqualsTest.java | 6 +- .../enso/interpreter/test/HashCodeTest.java | 4 +- .../enso/interpreter/test/MetaIsATest.java | 102 +++++++++--------- .../enso/interpreter/test/MetaObjectTest.java | 23 +++- .../interpreter/test/ValuesGenerator.java | 29 ++++- .../enso/interpreter/test/VectorSortTest.java | 8 +- 12 files changed, 142 insertions(+), 72 deletions(-) create mode 100644 engine/runtime-with-polyglot/src/test/java/org/enso/interpreter/test/MetaIsAPolyglotTest.java create mode 100644 engine/runtime-with-polyglot/src/test/java/org/enso/interpreter/test/MetaObjectPolyglotTest.java diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Interval.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Interval.enso index b6681a32b67..7416a4224ad 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Interval.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Interval.enso @@ -87,7 +87,7 @@ type Interval Arguments: - start: The start of the interval. - end: The end of the interval. - Between (start : Bound.Bound) (end : Bound.Bound) + Between (start : Bound) (end : Bound) ## Checks if the interval contains `that`. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso index 2a50eb4a8d2..b4d95df7ea4 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso @@ -378,10 +378,10 @@ type Match_Iterator ## PRIVATE type Match_Iterator_Value ## PRIVATE - Next (filler : Span) (match : Match) (next_iterator : Match_Iterator) + Next (filler : Utf_16_Span) (match : Match) (next_iterator : Match_Iterator) ## PRIVATE - Last (filler : Span) + Last (filler : Utf_16_Span) ## PRIVATE Convert the polyglot map to a Map. diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso index a74ab230aad..f9af2117209 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso @@ -63,7 +63,7 @@ type Table - connection: The connection with which the table is associated. - internal_columns: The internal representation of the table columns. - context: The context associated with this table. - Value name:Text connection:Connection (internal_columns:(Vector Internal_Column)) context:IR.Context + Value name:Text connection:Connection (internal_columns:(Vector Internal_Column)) context:Context ## PRIVATE ADVANCED diff --git a/engine/runtime-with-polyglot/src/test/java/org/enso/interpreter/test/MetaIsAPolyglotTest.java b/engine/runtime-with-polyglot/src/test/java/org/enso/interpreter/test/MetaIsAPolyglotTest.java new file mode 100644 index 00000000000..a2c2e6f115e --- /dev/null +++ b/engine/runtime-with-polyglot/src/test/java/org/enso/interpreter/test/MetaIsAPolyglotTest.java @@ -0,0 +1,13 @@ +package org.enso.interpreter.test; + +import org.enso.interpreter.test.ValuesGenerator.Language; +import org.graalvm.polyglot.Context; + +public final class MetaIsAPolyglotTest extends MetaIsATest { + public MetaIsAPolyglotTest() {} + + @Override + protected ValuesGenerator createGenerator(Context ctx) { + return ValuesGenerator.create(ctx, Language.values()); + } +} diff --git a/engine/runtime-with-polyglot/src/test/java/org/enso/interpreter/test/MetaObjectPolyglotTest.java b/engine/runtime-with-polyglot/src/test/java/org/enso/interpreter/test/MetaObjectPolyglotTest.java new file mode 100644 index 00000000000..ba762343479 --- /dev/null +++ b/engine/runtime-with-polyglot/src/test/java/org/enso/interpreter/test/MetaObjectPolyglotTest.java @@ -0,0 +1,13 @@ +package org.enso.interpreter.test; + +import org.enso.interpreter.test.ValuesGenerator.Language; +import org.graalvm.polyglot.Context; + +public final class MetaObjectPolyglotTest extends MetaObjectTest { + public MetaObjectPolyglotTest() {} + + @Override + protected ValuesGenerator createGenerator(Context ctx) { + return ValuesGenerator.create(ctx, Language.values()); + } +} diff --git a/engine/runtime/src/test/java/org/enso/compiler/EnsoCompilerTest.java b/engine/runtime/src/test/java/org/enso/compiler/EnsoCompilerTest.java index 6e6ebe243b3..16ee9e39142 100644 --- a/engine/runtime/src/test/java/org/enso/compiler/EnsoCompilerTest.java +++ b/engine/runtime/src/test/java/org/enso/compiler/EnsoCompilerTest.java @@ -1,13 +1,14 @@ package org.enso.compiler; -import com.oracle.truffle.api.source.Source; import java.io.IOException; + import org.enso.compiler.core.IR; import org.junit.AfterClass; +import static org.junit.Assert.assertNotNull; import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Ignore; + +import com.oracle.truffle.api.source.Source; public class EnsoCompilerTest { private static EnsoCompiler ensoCompiler; @@ -947,7 +948,6 @@ public class EnsoCompilerTest { } @Test - @Ignore // Crashes old parser public void testAlternationTypes() throws Exception { parseTest(""" foo : [Integer | Text] -> (Integer | Text) diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/EqualsTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/EqualsTest.java index 621142f1f4b..0793fb65a68 100644 --- a/engine/runtime/src/test/java/org/enso/interpreter/test/EqualsTest.java +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/EqualsTest.java @@ -55,11 +55,7 @@ public class EqualsTest extends TestBase { private static Object[] fetchAllUnwrappedValues() { var valGenerator = ValuesGenerator.create( - context, - ValuesGenerator.Language.ENSO, - ValuesGenerator.Language.JAVA, - ValuesGenerator.Language.JAVASCRIPT, - ValuesGenerator.Language.PYTHON); + context, ValuesGenerator.Language.ENSO, ValuesGenerator.Language.JAVA); List values = new ArrayList<>(); values.addAll(valGenerator.numbers()); values.addAll(valGenerator.booleans()); diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/HashCodeTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/HashCodeTest.java index 102fe13ef85..2e9d618d0f4 100644 --- a/engine/runtime/src/test/java/org/enso/interpreter/test/HashCodeTest.java +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/HashCodeTest.java @@ -63,9 +63,7 @@ public class HashCodeTest extends TestBase { var valGenerator = ValuesGenerator.create( context, ValuesGenerator.Language.ENSO, - ValuesGenerator.Language.JAVA, - ValuesGenerator.Language.JAVASCRIPT, - ValuesGenerator.Language.PYTHON + ValuesGenerator.Language.JAVA ); List values = new ArrayList<>(); values.addAll(valGenerator.numbers()); diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/MetaIsATest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/MetaIsATest.java index f6b2adfc3c6..572e1d2e306 100644 --- a/engine/runtime/src/test/java/org/enso/interpreter/test/MetaIsATest.java +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/MetaIsATest.java @@ -4,6 +4,8 @@ import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; + +import org.enso.interpreter.test.ValuesGenerator.Language; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Source; import org.graalvm.polyglot.Value; @@ -12,16 +14,17 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import org.junit.After; -import org.junit.Before; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; public class MetaIsATest extends TestBase { - private Context ctx; - private Value isACheck; + private static Context ctx; + private static Value isACheck; + private static ValuesGenerator generator; - @Before - public void prepareCtx() throws Exception { + @BeforeClass + public static void prepareCtx() throws Exception { ctx = createDefaultContext(); final URI uri = new URI("memory://choose.enso"); final Source src = Source.newBuilder("enso", """ @@ -37,16 +40,31 @@ public class MetaIsATest extends TestBase { assertTrue("it is a function", isACheck.canExecute()); } - @After - public void disposeCtx() { + @AfterClass + public static void disposeCtx() { ctx.close(); } + /** Override to create different values generator. + * + * @param context the context to allocate values in + * @return an instance of values generator + */ + ValuesGenerator createGenerator(Context context) { + return ValuesGenerator.create(context, Language.ENSO, Language.JAVA); + } + + private ValuesGenerator generator() { + if (generator == null) { + generator = createGenerator(ctx); + } + return generator; + } + @Test public void checkNumbersAreNumber() { - var g = ValuesGenerator.create(ctx); - var typeNumber = g.typeNumber(); - for (var v : g.numbers()) { + var typeNumber = generator().typeNumber(); + for (var v : generator().numbers()) { var r = isACheck.execute(v, typeNumber); assertTrue("Value " + v + " is a number, type: " + v.getMetaObject(), r.asBoolean()); } @@ -54,9 +72,8 @@ public class MetaIsATest extends TestBase { @Test public void checkValuesAreAny() throws Exception { - var g = ValuesGenerator.create(ctx); - var typeAny = g.typeAny(); - for (var v : g.allValues()) { + var typeAny = generator().typeAny(); + for (var v : generator().allValues()) { var r = isACheck.execute(v, typeAny); assertTrue("Value " + v + " is any", r.asBoolean()); } @@ -64,71 +81,63 @@ public class MetaIsATest extends TestBase { @Test public void checkNumbersAreNotText() { - var g = ValuesGenerator.create(ctx); - for (var v : g.numbers()) { - var r = isACheck.execute(v, g.typeText()); + for (var v : generator().numbers()) { + var r = isACheck.execute(v, generator().typeText()); assertFalse("Value " + v + " is not a string", r.asBoolean()); } } @Test public void checkTextsAreText() { - var g = ValuesGenerator.create(ctx); - for (var v : g.textual()) { - var r = isACheck.execute(v, g.typeText()); + for (var v : generator().textual()) { + var r = isACheck.execute(v, generator().typeText()); assertTrue("Value " + v + " is a string", r.asBoolean()); } } @Test public void checkIntegerIsNotInstanceOfInteger() { - var g = ValuesGenerator.create(ctx); - var t = g.typeInteger(); + var t = generator().typeInteger(); var r = isACheck.execute(t, t); assertFalse("Integer is not instance of Integer", r.asBoolean()); } @Test public void checkNumberIsNotInstanceOfNumber() { - var g = ValuesGenerator.create(ctx); - var t = g.typeNumber(); + var t = generator().typeNumber(); var r = isACheck.execute(t, t); assertFalse("Number is not instance of Number", r.asBoolean()); } @Test public void checkAnyIsInstanceOfAny() { - var g = ValuesGenerator.create(ctx); - var t = g.typeAny(); + var t = generator().typeAny(); var r = isACheck.execute(t, t); assertTrue("Everything is instance of Any even Any", r.asBoolean()); } @Test public void checkTextsAreNotNumbers() { - var g = ValuesGenerator.create(ctx); - for (var v : g.textual()) { - var r = isACheck.execute(v, g.typeNumber()); + for (var v : generator().textual()) { + var r = isACheck.execute(v, generator().typeNumber()); assertFalse("Value " + v + " is not a number", r.asBoolean()); } } @Test public void checkArraysAreArrays() { - var g = ValuesGenerator.create(ctx); - for (var v : g.arrayLike()) { - var isVector = isACheck.execute(v, g.typeVector()); - var isArray = isACheck.execute(v, g.typeArray()); + for (var v : generator().arrayLike()) { + var isVector = isACheck.execute(v, generator().typeVector()); + var isArray = isACheck.execute(v, generator().typeArray()); assertTrue("Value " + v + " of type " + v.getMetaObject() + " should either be array (" + isArray + ") or vector (" + isVector + ")", isArray.asBoolean() ^ isVector.asBoolean()); } } @Test public void valuesAreNotInstancesOfThemselves() throws Exception { - var g = ValuesGenerator.create(ctx); - for (var v : g.allValues()) { + for (var v : generator().allValues()) { var r = isACheck.execute(v, v); - if (v.equals(g.typeNothing())) { + if (v.equals(generator().typeNothing())) { assertTrue("Nothing is instance of itself", r.asBoolean()); } else { assertFalse("Value " + v + " shall not be instance of itself", r.isBoolean() && r.asBoolean()); @@ -138,12 +147,11 @@ public class MetaIsATest extends TestBase { @Test public void constructorVariants() throws Exception { - var g = ValuesGenerator.create(ctx); var found = new HashMap(); - final List values = g.constructorsAndValuesAndSumType(); + final List values = generator().constructorsAndValuesAndSumType(); for (var v1 : values) { for (var v2 : values) { - assertTypeWithCheck(g, v1, v2, found); + assertTypeWithCheck(generator, v1, v2, found); } } assertEquals("Just one: " + found, 1, found.size()); @@ -170,14 +178,13 @@ public class MetaIsATest extends TestBase { @Test public void typesAreNotInstancesOfThemselves() throws Exception { - var g = ValuesGenerator.create(ctx); var f = new StringBuilder(); - for (var v : g.allTypes()) { - if (v.equals(g.typeAny())) { + for (var v : generator().allTypes()) { + if (v.equals(generator().typeAny())) { continue; } var r = isACheck.execute(v, v); - if (v.equals(g.typeNothing())) { + if (v.equals(generator().typeNothing())) { assertTrue("Nothing is instance of itself", r.asBoolean()); } else { if (r.asBoolean()) { @@ -190,13 +197,12 @@ public class MetaIsATest extends TestBase { @Test public void consistencyWithCase() throws Exception { - var g = ValuesGenerator.create(ctx); var f = new StringBuilder(); - for (var t : g.allTypes()) { - var typeCaseOf = g.withType(t); + for (var t : generator().allTypes()) { + var typeCaseOf = generator().withType(t); - for (var v : g.allValues()) { - assertTypeAndValue(typeCaseOf, v, t, f, g); + for (var v : generator().allValues()) { + assertTypeAndValue(typeCaseOf, v, t, f, generator); } } if (f.length() > 0) { diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/MetaObjectTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/MetaObjectTest.java index d317e453eac..b40ce9da9dc 100644 --- a/engine/runtime/src/test/java/org/enso/interpreter/test/MetaObjectTest.java +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/MetaObjectTest.java @@ -6,7 +6,9 @@ import java.net.URI; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; + import org.enso.interpreter.runtime.type.ConstantsGen; +import org.enso.interpreter.test.ValuesGenerator.Language; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Source; import org.graalvm.polyglot.Value; @@ -22,6 +24,7 @@ import org.junit.Test; public class MetaObjectTest extends TestBase { private static Context ctx; + private static ValuesGenerator generator; @BeforeClass public static void prepareCtx() { @@ -33,6 +36,22 @@ public class MetaObjectTest extends TestBase { ctx.close(); } + /** Override to create different values generator. + * + * @param context the context to allocate values in + * @return an instance of values generator + */ + ValuesGenerator createGenerator(Context context) { + return ValuesGenerator.create(context, Language.ENSO, Language.JAVA); + } + + private ValuesGenerator generator() { + if (generator == null) { + generator = createGenerator(ctx); + } + return generator; + } + @Test public void checkingAtomMetaObject() throws Exception { final URI uri = new URI("memory://callback.enso"); @@ -68,7 +87,7 @@ public class MetaObjectTest extends TestBase { @Test public void checkAllConstantGenValuesArePresent() throws Exception { - var g = ValuesGenerator.create(ctx); + var g = generator(); var expecting = new HashSet(); for (var f : ConstantsGen.class.getFields()) { if (!f.getName().endsWith("_BUILTIN")) { @@ -135,7 +154,7 @@ public class MetaObjectTest extends TestBase { } private void checkAllTypesSatisfy(Check check) throws Exception { - var g = ValuesGenerator.create(ctx); + var g = generator(); var expecting = new LinkedHashSet(); for (var t : g.allTypes()) { if (t.isNull()) { diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/ValuesGenerator.java b/engine/runtime/src/test/java/org/enso/interpreter/test/ValuesGenerator.java index fd002f64f48..6c17386a133 100644 --- a/engine/runtime/src/test/java/org/enso/interpreter/test/ValuesGenerator.java +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/ValuesGenerator.java @@ -1,5 +1,7 @@ package org.enso.interpreter.test; +import java.lang.reflect.Method; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -20,6 +22,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; + import org.enso.polyglot.MethodNames.Module; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.PolyglotException; @@ -36,6 +39,7 @@ class ValuesGenerator { private final Set languages; private final Map values = new HashMap<>(); private final Map> multiValues = new HashMap<>(); + private final Map computed = new HashMap<>(); private ValuesGenerator(Context ctx, Set languages) { this.ctx = ctx; @@ -587,6 +591,17 @@ class ValuesGenerator { map.put("C", 3); collect.add(ctx.asValue(map)); } + if (languages.contains(Language.JAVASCRIPT)) { + var fn = ctx.eval("js", """ + (function() { + var map = new Map(); + map.set('A', 1); + map.set('B', 2); + return map; + }) + """); + collect.add(fn.execute()); + } return collect; } @@ -733,7 +748,7 @@ class ValuesGenerator { } if (m.getReturnType() == List.class) { @SuppressWarnings("unchecked") - var r = (List) m.invoke(this); + var r = (List) invokeWithCache(m); collect.addAll(r); } } @@ -746,7 +761,8 @@ class ValuesGenerator { if (m.getName().startsWith("type")) { if (m.getReturnType() == Value.class) { - var r = (Value) m.invoke(this); + @SuppressWarnings("unchecked") + var r = (Value) invokeWithCache(m); collect.add(r); } } @@ -754,6 +770,15 @@ class ValuesGenerator { return collect; } + private Object invokeWithCache(Method m) throws Exception { + var v = computed.get(m); + if (v == null) { + v = m.invoke(this); + computed.put(m, v); + } + return v; + } + public enum Language { ENSO, JAVASCRIPT, PYTHON, JAVA } diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/VectorSortTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/VectorSortTest.java index cceda051e36..5c167e0c313 100644 --- a/engine/runtime/src/test/java/org/enso/interpreter/test/VectorSortTest.java +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/VectorSortTest.java @@ -1,14 +1,14 @@ package org.enso.interpreter.test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.util.ArrayList; import java.util.List; + import org.enso.interpreter.test.ValuesGenerator.Language; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; import org.junit.AfterClass; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.junit.Assume; import org.junit.BeforeClass; import org.junit.experimental.theories.DataPoints; @@ -40,7 +40,7 @@ public class VectorSortTest extends TestBase { values = new ArrayList<>(); var valuesGenerator = - ValuesGenerator.create(context, Language.ENSO, Language.JAVA, Language.JAVASCRIPT); + ValuesGenerator.create(context, Language.ENSO, Language.JAVA); values.addAll(valuesGenerator.numbers()); values.addAll(valuesGenerator.vectors()); values.addAll(valuesGenerator.arrayLike());