diff --git a/crates/opy-rs/src/compiler/tests/builtins.rs b/crates/opy-rs/src/compiler/tests/builtins.rs index ce45d64a..02bf9070 100644 --- a/crates/opy-rs/src/compiler/tests/builtins.rs +++ b/crates/opy-rs/src/compiler/tests/builtins.rs @@ -305,6 +305,30 @@ rule "builtin surface": assert_eq!(artifact.emitted.matches("Create HUD Text").count(), 6); } +#[test] +fn start_hot_keyword_arguments_bind_like_positional_arguments() { + let source = include_str!("../../manifest/probes/start-hot-signature.opy"); + let hir = crate::compile(source, "start-hot-signature.opy", Path::new(".")) + .expect("pinned startHoT positional and keyword forms must resolve natively"); + let artifact = Compiler::new() + .expect("released Workshop contract must load") + .compile_hir(&hir) + .expect("pinned startHoT positional and keyword forms must lower natively"); + + assert_eq!(artifact.wir.rules.len(), 2); + assert_eq!(artifact.wir.rules[0].actions.len(), 1); + assert_eq!(artifact.wir.rules[1].actions.len(), 1); + let mut positional = artifact.wir.clone(); + positional.rules.truncate(1); + let mut keyword = artifact.wir; + keyword.rules.remove(0); + keyword.rules[0].name = positional.rules[0].name.clone(); + assert!( + workshop_rs::roundtrip::equivalent(&positional, &keyword), + "keyword arguments must bind to the same Workshop arguments as positional calls" + ); +} + #[test] fn stop_chasing_variable_dispatches_by_variable_kind() { let source = "globalvar g\nplayervar p\nrule \"r\":\n @Event eachPlayer\n stopChasingVariable(g)\n stopChasingVariable(eventPlayer.p)\n"; diff --git a/crates/opy-rs/src/manifest/data/manifest.json b/crates/opy-rs/src/manifest/data/manifest.json index ce577060..a1f08a43 100644 --- a/crates/opy-rs/src/manifest/data/manifest.json +++ b/crates/opy-rs/src/manifest/data/manifest.json @@ -983,7 +983,7 @@ { "catalogId": "startHealingOverTime", "evidence": [ - "builtin-surface" + "start-hot-signature" ], "id": "startHoT", "kind": "memberAction", @@ -995,7 +995,7 @@ "name": "duration" }, { - "name": "healing" + "name": "healingPerSecond" } ], "receiver": "Player" @@ -2993,26 +2993,6 @@ "params": [], "receiver": "Player" }, - { - "catalogId": "startHealingOverTime", - "evidence": [ - "builtin-surface" - ], - "id": "startHoT", - "kind": "memberAction", - "params": [ - { - "name": "healer" - }, - { - "name": "rate" - }, - { - "name": "duration" - } - ], - "receiver": "Player" - }, { "catalogId": "isInSpawnRoom", "evidence": [ diff --git a/crates/opy-rs/src/manifest/probes/probes.json b/crates/opy-rs/src/manifest/probes/probes.json index 358c3dbe..c6f150a8 100644 --- a/crates/opy-rs/src/manifest/probes/probes.json +++ b/crates/opy-rs/src/manifest/probes/probes.json @@ -358,6 +358,13 @@ "sha256": "5b69c61321ca05c3a9fbc2c12d225dbce749b7a05d82ad1b2f11852f4d5ac208", "source": "missing-values.opy" }, + { + "expect": "success", + "id": "start-hot-signature", + "outputSha256": "a9b80d7f57b61fdb490c15b63c635f7e5e6dd44658e9603ca630cc27b850a785", + "sha256": "399aa9fea314fec321d49b3cea47af7a5d8dfb84cd52b432325bf1130f38bdbe", + "source": "start-hot-signature.opy" + }, { "expect": "success", "id": "missing-actions", diff --git a/crates/opy-rs/src/manifest/probes/start-hot-signature.opy b/crates/opy-rs/src/manifest/probes/start-hot-signature.opy new file mode 100644 index 00000000..42ae7a0b --- /dev/null +++ b/crates/opy-rs/src/manifest/probes/start-hot-signature.opy @@ -0,0 +1,7 @@ +rule "startHoT positional signature": + @Event eachPlayer + eventPlayer.startHoT(null, 2, 3) + +rule "startHoT keyword signature": + @Event eachPlayer + eventPlayer.startHoT(healer=null, duration=2, healingPerSecond=3)