Skip to content

Commit

Permalink
Fix Runtime.assert (#8742)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akirathan authored Jan 12, 2024
1 parent 58cf4e5 commit 6ae35ab
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 141 deletions.
17 changes: 12 additions & 5 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import project.Errors.Common.Assertion_Error
import project.Errors.Common.Forbidden_Operation
import project.Errors.Common.Type_Error
import project.Function.Function
import project.IO
import project.Nothing.Nothing
import project.Panic.Panic
import project.Polyglot.Polyglot
import project.Runtime.Source_Location.Source_Location
import project.System
from project.Data.Index_Sub_Range.Index_Sub_Range import First, Last
from project.Data.Text.Extensions import all
from project.Runtime.Context import Input, Output
Expand Down Expand Up @@ -58,13 +60,18 @@ gc = @Builtin_Method "Runtime.gc"
Asserts that the given action succeeds, otherwise throws a panic.

Assertions are disable by default, meaning that call to this method is
a no-op. To enable assertions, set the environment variable
`ENSO_ENABLE_ASSERTIONS=true`
assert : Boolean -> Text -> Nothing ! Assertion_Error
assert ~action message="" = assert_builtin action message
a no-op. To enable assertions, either set the environment variable
`ENSO_ENABLE_ASSERTIONS=true` or enable JVM assertions by passing `-ea`
cmd line option to java.
assert : Boolean -> Text -> Nothing
assert (~action : Boolean) (message : Text = "") =
if assertions_enabled.not then Nothing else
if action then Nothing else
Panic.throw <| Assertion_Error.Error message

## PRIVATE
assert_builtin ~action message = @Builtin_Method "Runtime.assert_builtin"
Returns True if assertions are enabled.
assertions_enabled = @Builtin_Method "Runtime.assertions_enabled"

## PRIVATE
ADVANCED
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.enso.interpreter.node.expression.builtin.runtime;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext;

@BuiltinMethod(
type = "Runtime",
name = "assertions_enabled",
description = "Returns True iff assertions are enabled")
public class IsAssertionEnabledNode extends Node {
public static IsAssertionEnabledNode build() {
return new IsAssertionEnabledNode();
}

public boolean execute(VirtualFrame frame) {
return EnsoContext.get(this).isAssertionsEnabled();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.junit.Test;

public class AssertionsTest extends TestBase {

private static Context ctx;

private static final ByteArrayOutputStream out = new ByteArrayOutputStream();
Expand Down Expand Up @@ -63,9 +64,9 @@ public void simpleAssertionFailureWithMessage() {
TestBase.evalModule(
ctx,
"""
from Standard.Base import False, Runtime
main = Runtime.assert False
""");
from Standard.Base import False, Runtime
main = Runtime.assert False
""");
fail("Should throw Assertion_Error");
} catch (PolyglotException e) {
assertThat(e.getGuestObject().isException(), is(true));
Expand All @@ -78,9 +79,9 @@ public void assertionFailureDisplaysMessage() {
TestBase.evalModule(
ctx,
"""
from Standard.Base import False, Runtime
main = Runtime.assert False 'My fail message'
""");
from Standard.Base import False, Runtime
main = Runtime.assert False 'My fail message'
""");
fail("Should throw Assertion_Error");
} catch (PolyglotException e) {
assertThat(
Expand All @@ -95,17 +96,18 @@ public void assertionFailureDisplaysStackTrace() {
TestBase.evalModule(
ctx,
"""
from Standard.Base import False, Runtime
foo = Runtime.assert False 'My fail message'
main = foo
""");
from Standard.Base import False, Runtime
foo = Runtime.assert False 'My fail message'
main = foo
""");
fail("Should throw Assertion_Error");
} catch (PolyglotException e) {
assertThat(e.getStackTrace().length, greaterThan(3));
assertThat(e.getStackTrace()[0].toString(), containsString("Runtime.assert_builtin"));
assertThat(e.getStackTrace().length, greaterThan(5));
assertThat(e.getStackTrace()[0].toString(), containsString("Panic"));
assertThat(e.getStackTrace()[1].toString(), containsString("Runtime.assert"));
assertThat(e.getStackTrace()[2].toString(), containsString("foo"));
assertThat(e.getStackTrace()[3].toString(), containsString("main"));
// Ignore the next two frames as they are implementation details
assertThat(e.getStackTrace()[4].toString(), containsString("foo"));
assertThat(e.getStackTrace()[5].toString(), containsString("main"));
}
}

Expand All @@ -115,9 +117,9 @@ public void assertionSuccessReturnsNothing() {
TestBase.evalModule(
ctx,
"""
from Standard.Base import Runtime, True
main = Runtime.assert True
""");
from Standard.Base import Runtime, True
main = Runtime.assert True
""");
assertTrue(res.isNull());
}

Expand All @@ -127,9 +129,9 @@ public void assertChecksTypeOfReturnValue() {
TestBase.evalModule(
ctx,
"""
from Standard.Base import Runtime
main = Runtime.assert [1,2,3]
""");
from Standard.Base import Runtime
main = Runtime.assert [1,2,3]
""");
fail("Should throw Type_Error");
} catch (PolyglotException e) {
assertThat(e.getMessage(), stringContainsInOrder(List.of("Type", "error")));
Expand All @@ -142,14 +144,14 @@ public void actionInAssertIsComputedWhenAssertionsAreEnabled() {
TestBase.evalModule(
ctx,
"""
from Standard.Base import Runtime
import Standard.Base.Runtime.Ref.Ref
main =
ref = Ref.new 10
Runtime.assert (ref.put 23 . is_nothing . not)
ref.get
""");
from Standard.Base import Runtime
import Standard.Base.Runtime.Ref.Ref
main =
ref = Ref.new 10
Runtime.assert (ref.put 23 . is_nothing . not)
ref.get
""");
assertTrue(res.isNumber());
assertThat(res.asInt(), is(23));
}
Expand Down
17 changes: 7 additions & 10 deletions test/Tests/src/Runtime/Asserts_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ import Standard.Test.Extensions
foreign js js_check = """
return (4 == 2 + 2)

on_ci = if Environment.get "ENSO_RUNNER_CONTAINER_NAME" . is_nothing . not then Nothing else "Not in CI"

spec = Test.group "Asserts" pending=on_ci <|
Test.specify "should be enabled on the CI" <|
spec = Test.group "Asserts" <|
Test.specify "should be enabled in tests" <|
p = Panic.catch Assertion_Error (Runtime.assert False) err->
err.payload
Meta.type_of p . should_be_a Assertion_Error
Expand All @@ -26,15 +24,14 @@ spec = Test.group "Asserts" pending=on_ci <|
4 == 2 + 2
ret . should_be_a Nothing

Test.specify "should fail with type error when given dataflow error as expression" <|
p = Panic.catch Assertion_Error (Runtime.assert (Error.throw "foo")) err->
err.payload
Meta.type_of p . should_be_a Assertion_Error
p.message . should_start_with "Result of assert action is a dataflow error"

Test.specify "should be able to take values with warnings" <|
foo x = Warning.attach "My warning" (x+2)
Runtime.assert (foo 2 > 2) . should_be_a Nothing

Test.specify "should fail with Type_Error if action does not return Boolean" <|
p = Panic.catch Type_Error (Runtime.assert 42) err->
err
Meta.type_of p.payload . should_be_a Type_Error


main = Test_Suite.run_main spec

0 comments on commit 6ae35ab

Please sign in to comment.