Sakura Lang

V3020 test_unhandled_effect

Tests run under deterministic default handlers for Clock, Random, Env, Console and Log (design §5.8).

An error from the effect phase. sakura explain V3020 prints this explanation offline.

Tests run under deterministic default handlers for Clock, Random, Env, Console and Log (design §5.8). Any other effect used in a test must be handled inside the test with with, usually by a fake handler from std or one the test module declares.

Wrong:

effect Db { fn count() -> Int }
test "counts rows" { expect_eq(Db.count(), 0) }

Fixed:

fn empty_db() -> Handler<Db> { handler Db { fn count() { 0 } } }
test "counts rows" { with empty_db() { expect_eq(Db.count(), 0) } }

Wrong program

compiler/tests/ui/V3020_test_unhandled_effect.sakura, which the compiler's ui suite runs through sakura check:

effect Db {
  fn count() -> Int
}

test "counts rows" { expect_eq(Db.count(), 0) }

sakura check --json reports this record (pretty-printed; $DIR is the fixture's directory):

{
  "schema_version": "1.0",
  "kind": "diagnostic",
  "id": "d:e91988b019622147",
  "code": "V3020",
  "severity": "error",
  "phase": "effect",
  "message": "test uses `Db` without a handler; install one with `with` (std ships fake handlers for its own effects)",
  "snapshot": "sha256:$SNAPSHOT",
  "symbol_id": "main::V3020_test_unhandled_effect::test:counts rows",
  "spans": [
    {
      "uri": "file://$DIR/V3020_test_unhandled_effect.sakura",
      "content_hash": "sha256:c7c8d39e5ec232c63875fbbb369da28bf275c4e6a4ba8b50111740b0eb0a9a4a",
      "start_byte": 74,
      "end_byte": 87,
      "role": "primary"
    },
    {
      "uri": "file://$DIR/V3020_test_unhandled_effect.sakura",
      "content_hash": "sha256:c7c8d39e5ec232c63875fbbb369da28bf275c4e6a4ba8b50111740b0eb0a9a4a",
      "start_byte": 100,
      "end_byte": 110,
      "role": "cause",
      "label": "`Db.count` performs `Db` here"
    }
  ],
  "related_ids": [],
  "expected": {
    "render": "{Clock, Console, Env, Log, Random, Test}",
    "row": {
      "labels": [
        {
          "effect": "std::Clock",
          "args": []
        },
        {
          "effect": "std::Console",
          "args": []
        },
        {
          "effect": "std::Env",
          "args": []
        },
        {
          "effect": "std::Log",
          "args": []
        },
        {
          "effect": "std::Random",
          "args": []
        },
        {
          "effect": "std::Test",
          "args": []
        }
      ],
      "tail": null
    }
  },
  "actual": {
    "render": "{Db, Test}",
    "row": {
      "labels": [
        {
          "effect": "std::Test",
          "args": []
        },
        {
          "effect": "main::Db",
          "args": []
        }
      ],
      "tail": null
    }
  },
  "obligation": null,
  "counterexample": null,
  "explanation_uri": "sakura://explain/V3020",
  "fixes": []
}

Fixed program

compiler/tests/ui/V3020_test_unhandled_effect.fixed.sakura, which sakura check accepts with no diagnostics:

effect Db {
  fn count() -> Int
}

fn empty_db() -> Handler<Db> {
  handler Db {
    fn count() { 0 }
  }
}

test "counts rows" { with empty_db() { expect_eq(Db.count(), 0) } }
Edit on GitHub

On this page