From d52adb4cfa059b28abb9bf91aa420960b2de8d96 Mon Sep 17 00:00:00 2001 From: Santiago Date: Mon, 22 Jun 2026 16:53:09 -0300 Subject: [PATCH] test(invoke): cover arg encoding through the invoke glue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a smoke test over cshell's own invoke path — `prepare_invocation` → `load_args` → `into_resolve_request` — on the `05-invoke` arg surface: a record `meta` nesting a `List` plus Int/ Bool/Bytes scalars. Asserts the record serializes to the tagged wire form (fields positional in declared order) and scalars stay bare. The SDK already covers the encoder; this pins cshell's glue (JSON-string parsing, tii load, the args→resolve-request hand-off) that the SDK tests skip. Adds a staged `tests/fixtures/invoke.tii`. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/tx/common.rs | 46 ++++++++++++++++++++ tests/fixtures/invoke.tii | 91 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 tests/fixtures/invoke.tii diff --git a/src/tx/common.rs b/src/tx/common.rs index 90ccacd..f0e65dc 100644 --- a/src/tx/common.rs +++ b/src/tx/common.rs @@ -262,3 +262,49 @@ pub async fn sign_tx( Ok(cbor) } + +#[cfg(test)] +mod tests { + use super::*; + + // The invoke glue cshell owns: `prepare_invocation` (load the .tii + select + // the tx) → `load_args` (parse `--args-json` → `set_args`) → + // `into_resolve_request`. A complex record arg must serialize to the tagged + // wire form while scalars stay bare — the `05-invoke` arg surface. + #[test] + fn invoke_encodes_diverse_args_into_resolve_request() { + let tii = format!("{}/tests/fixtures/invoke.tii", env!("CARGO_MANIFEST_DIR")); + let mut invocation = + prepare_invocation(Path::new(&tii), Some("transfer"), None).unwrap(); + + let args_json = r#"{ + "quantity": 2000000, + "urgent": true, + "memo": "deadbeef", + "meta": { "tags": [1, 2, 3], "level": 7 } + }"#; + load_args(&mut invocation, Some(args_json), None).unwrap(); + + let request = invocation.into_resolve_request().unwrap(); + + // Record `meta` → tagged struct; fields positional in declared order + // (tags, level), not alphabetical. + assert_eq!( + request.args["meta"], + json!({ + "struct": { + "constructor": 0, + "fields": [ + { "list": [{ "int": 1 }, { "int": 2 }, { "int": 3 }] }, + { "int": 7 } + ] + } + }) + ); + + // Scalars stay bare for the resolver to coerce via the flat type. + assert_eq!(request.args["quantity"], json!(2000000)); + assert_eq!(request.args["urgent"], json!(true)); + assert_eq!(request.args["memo"], json!("deadbeef")); + } +} diff --git a/tests/fixtures/invoke.tii b/tests/fixtures/invoke.tii new file mode 100644 index 0000000..86fc149 --- /dev/null +++ b/tests/fixtures/invoke.tii @@ -0,0 +1,91 @@ +{ + "components": { + "schemas": { + "Meta": { + "properties": { + "level": { + "type": "integer" + }, + "tags": { + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "required": [ + "tags", + "level" + ], + "type": "object" + } + } + }, + "environment": { + "properties": {}, + "required": [], + "type": "object" + }, + "parties": { + "receiver": {}, + "sender": {} + }, + "profiles": { + "local": { + "environment": {}, + "parties": {} + }, + "mainnet": { + "environment": {}, + "parties": {} + }, + "preprod": { + "environment": {}, + "parties": {} + }, + "preview": { + "environment": {}, + "parties": {} + } + }, + "protocol": { + "name": "cshell-fix", + "scope": "unknown", + "version": "0.0.0" + }, + "tii": { + "version": "v1beta0" + }, + "transactions": { + "transfer": { + "params": { + "properties": { + "memo": { + "$ref": "https://tx3.land/specs/v1beta0/tii#/$defs/Bytes" + }, + "meta": { + "$ref": "#/components/schemas/Meta" + }, + "quantity": { + "type": "integer" + }, + "urgent": { + "type": "boolean" + } + }, + "required": [ + "quantity", + "urgent", + "memo", + "meta" + ], + "type": "object" + }, + "tir": { + "content": "ab6466656573a1694576616c506172616d6a457870656374466565736a7265666572656e6365738066696e7075747381a3646e616d6566736f75726365657574786f73a1694576616c506172616da16b457870656374496e7075748266736f75726365a56761646472657373a1694576616c506172616da16b45787065637456616c7565826673656e64657267416464726573736a6d696e5f616d6f756e74a16b4576616c4275696c74496ea16341646482a16641737365747381a366706f6c696379644e6f6e656a61737365745f6e616d65644e6f6e6566616d6f756e74a1694576616c506172616da16b45787065637456616c756582687175616e7469747963496e74a1694576616c506172616d6a4578706563744665657363726566644e6f6e65646d616e79f46a636f6c6c61746572616cf46872656465656d6572644e6f6e65676f75747075747382a46761646472657373a1694576616c506172616da16b45787065637456616c756582687265636569766572674164647265737365646174756da166537472756374a26b636f6e7374727563746f7200666669656c647383a1694576616c506172616da16b45787065637456616c756582646d656d6f654279746573a1694576616c506172616da16b45787065637456616c75658266757267656e7464426f6f6ca1694576616c506172616da16b45787065637456616c756582646d657461a166437573746f6d644d65746166616d6f756e74a16641737365747381a366706f6c696379644e6f6e656a61737365745f6e616d65644e6f6e6566616d6f756e74a1694576616c506172616da16b45787065637456616c756582687175616e7469747963496e74686f7074696f6e616cf4a46761646472657373a1694576616c506172616da16b45787065637456616c7565826673656e646572674164647265737365646174756d644e6f6e6566616d6f756e74a16b4576616c4275696c74496ea16353756282a16b4576616c4275696c74496ea16353756282a16a4576616c436f65726365a16a496e746f417373657473a1694576616c506172616da16b457870656374496e7075748266736f75726365a56761646472657373a1694576616c506172616da16b45787065637456616c7565826673656e64657267416464726573736a6d696e5f616d6f756e74a16b4576616c4275696c74496ea16341646482a16641737365747381a366706f6c696379644e6f6e656a61737365745f6e616d65644e6f6e6566616d6f756e74a1694576616c506172616da16b45787065637456616c756582687175616e7469747963496e74a1694576616c506172616d6a4578706563744665657363726566644e6f6e65646d616e79f46a636f6c6c61746572616cf4a16641737365747381a366706f6c696379644e6f6e656a61737365745f6e616d65644e6f6e6566616d6f756e74a1694576616c506172616da16b45787065637456616c756582687175616e7469747963496e74a1694576616c506172616d6a45787065637446656573686f7074696f6e616cf46876616c6964697479f6656d696e747380656275726e7380656164686f63806a636f6c6c61746572616c80677369676e657273f6686d6574616461746180", + "encoding": "hex", + "version": "v1beta0" + } + } + } +} \ No newline at end of file