Skip to content

Commit ee6a8b0

Browse files
committed
Add map tests for nested maps, multi-param, variant, and result types
Exercise additional ABI code paths: nested map<K, map<K2, V>> with recursive lower/lift blocks, multiple map parameters with independent ptr/len pairs, map as a variant arm payload, map inside result<ok, err>, and tuple-with-map in codegen.
1 parent 43a7fd6 commit ee6a8b0

4 files changed

Lines changed: 127 additions & 2 deletions

File tree

tests/codegen/map.wit

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ interface map-types {
1616
y: string,
1717
}
1818

19+
variant map-or-string {
20+
as-map(names-by-id),
21+
as-string(string),
22+
}
23+
1924
named-roundtrip: func(a: names-by-id) -> ids-by-name;
2025
inline-roundtrip: func(a: map<u32, string>, b: map<string, list<u8>>) -> tuple<map<string, u32>, map<string, list<u8>>>;
2126
nested-roundtrip: func(a: bytes-by-name) -> bytes-by-name;
@@ -25,6 +30,9 @@ interface map-types {
2530
record-value-roundtrip: func(a: map<string, map-value-record>) -> map<string, map-value-record>;
2631
bool-key-roundtrip: func(a: map<bool, string>) -> map<bool, string>;
2732
char-key-roundtrip: func(a: map<char, u32>) -> map<char, u32>;
33+
variant-roundtrip: func(a: map-or-string) -> map-or-string;
34+
result-roundtrip: func(a: result<names-by-id, string>) -> result<names-by-id, string>;
35+
tuple-with-map: func(a: tuple<names-by-id, u64>) -> tuple<names-by-id, u64>;
2836
}
2937

3038
world map-world {

tests/runtime/map/runner.rs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ impl Guest for Component {
1717
test_record_roundtrip();
1818
test_inline_roundtrip();
1919
test_large_map();
20+
test_multi_param_roundtrip();
21+
test_nested_roundtrip();
22+
test_variant_roundtrip();
23+
test_result_roundtrip();
2024
}
2125
}
2226

@@ -95,6 +99,78 @@ fn test_large_map() {
9599
let result = large_roundtrip(&input);
96100
assert_eq!(result.len(), 100);
97101
for i in 0..100 {
98-
assert_eq!(result.get(&i).map(String::as_str), Some(format!("value-{i}").as_str()));
102+
assert_eq!(
103+
result.get(&i).map(String::as_str),
104+
Some(format!("value-{i}").as_str()),
105+
);
106+
}
107+
}
108+
109+
fn test_multi_param_roundtrip() {
110+
let mut names = NamesById::new();
111+
names.insert(1, "one".to_string());
112+
names.insert(2, "two".to_string());
113+
let mut bytes = BytesByName::new();
114+
bytes.insert("key".to_string(), vec![42u8]);
115+
let (ids, bytes_out) = multi_param_roundtrip(&names, &bytes);
116+
assert_eq!(ids.len(), 2);
117+
assert_eq!(ids.get("one"), Some(&1));
118+
assert_eq!(ids.get("two"), Some(&2));
119+
assert_eq!(bytes_out.len(), 1);
120+
assert_eq!(
121+
bytes_out.get("key").map(Vec::as_slice),
122+
Some([42u8].as_slice()),
123+
);
124+
}
125+
126+
fn test_nested_roundtrip() {
127+
let mut inner_a = wit_bindgen::rt::Map::new();
128+
inner_a.insert(1, "one".to_string());
129+
inner_a.insert(2, "two".to_string());
130+
let mut inner_b = wit_bindgen::rt::Map::new();
131+
inner_b.insert(10, "ten".to_string());
132+
let mut outer = wit_bindgen::rt::Map::new();
133+
outer.insert("group-a".to_string(), inner_a);
134+
outer.insert("group-b".to_string(), inner_b);
135+
let result = nested_roundtrip(&outer);
136+
assert_eq!(result.len(), 2);
137+
let ra = result.get("group-a").unwrap();
138+
assert_eq!(ra.get(&1).map(String::as_str), Some("one"));
139+
assert_eq!(ra.get(&2).map(String::as_str), Some("two"));
140+
let rb = result.get("group-b").unwrap();
141+
assert_eq!(rb.get(&10).map(String::as_str), Some("ten"));
142+
}
143+
144+
fn test_variant_roundtrip() {
145+
let mut map = NamesById::new();
146+
map.insert(1, "one".to_string());
147+
let as_map = variant_roundtrip(&MapOrString::AsMap(map));
148+
match &as_map {
149+
MapOrString::AsMap(m) => {
150+
assert_eq!(m.get(&1).map(String::as_str), Some("one"));
151+
}
152+
MapOrString::AsString(_) => panic!("expected AsMap"),
153+
}
154+
155+
let as_str = variant_roundtrip(&MapOrString::AsString("hello".to_string()));
156+
match &as_str {
157+
MapOrString::AsString(s) => assert_eq!(s, "hello"),
158+
MapOrString::AsMap(_) => panic!("expected AsString"),
159+
}
160+
}
161+
162+
fn test_result_roundtrip() {
163+
let mut map = NamesById::new();
164+
map.insert(5, "five".to_string());
165+
let ok_result = result_roundtrip(Ok(&map));
166+
match &ok_result {
167+
Ok(m) => assert_eq!(m.get(&5).map(String::as_str), Some("five")),
168+
Err(_) => panic!("expected Ok"),
169+
}
170+
171+
let err_result = result_roundtrip(Err("bad input"));
172+
match &err_result {
173+
Err(e) => assert_eq!(e, "bad input"),
174+
Ok(_) => panic!("expected Err"),
99175
}
100176
}

tests/runtime/map/test.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
include!(env!("BINDINGS"));
22

3-
use crate::exports::test::maps::to_test::{BytesByName, IdsByName, LabeledEntry, NamesById};
3+
use crate::exports::test::maps::to_test::{
4+
BytesByName, IdsByName, LabeledEntry, MapOrString, NamesById,
5+
};
46

57
struct Component;
68

@@ -64,4 +66,34 @@ impl exports::test::maps::to_test::Guest for Component {
6466
fn large_roundtrip(a: NamesById) -> NamesById {
6567
a
6668
}
69+
70+
fn multi_param_roundtrip(a: NamesById, b: BytesByName) -> (IdsByName, BytesByName) {
71+
assert_eq!(a.len(), 2);
72+
assert_eq!(b.len(), 1);
73+
let mut ids = IdsByName::new();
74+
for (id, name) in a {
75+
ids.insert(name, id);
76+
}
77+
(ids, b)
78+
}
79+
80+
fn nested_roundtrip(
81+
a: wit_bindgen::rt::Map<String, wit_bindgen::rt::Map<u32, String>>,
82+
) -> wit_bindgen::rt::Map<String, wit_bindgen::rt::Map<u32, String>> {
83+
assert_eq!(a.len(), 2);
84+
let inner = a.get("group-a").unwrap();
85+
assert_eq!(inner.get(&1).map(String::as_str), Some("one"));
86+
assert_eq!(inner.get(&2).map(String::as_str), Some("two"));
87+
let inner2 = a.get("group-b").unwrap();
88+
assert_eq!(inner2.get(&10).map(String::as_str), Some("ten"));
89+
a
90+
}
91+
92+
fn variant_roundtrip(a: MapOrString) -> MapOrString {
93+
a
94+
}
95+
96+
fn result_roundtrip(a: Result<NamesById, String>) -> Result<NamesById, String> {
97+
a
98+
}
6799
}

tests/runtime/map/test.wit

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,22 @@ interface to-test {
1010
values: names-by-id,
1111
}
1212

13+
variant map-or-string {
14+
as-map(names-by-id),
15+
as-string(string),
16+
}
17+
1318
named-roundtrip: func(a: names-by-id) -> ids-by-name;
1419
bytes-roundtrip: func(a: bytes-by-name) -> bytes-by-name;
1520
empty-roundtrip: func(a: names-by-id) -> names-by-id;
1621
option-roundtrip: func(a: map<string, option<u32>>) -> map<string, option<u32>>;
1722
record-roundtrip: func(a: labeled-entry) -> labeled-entry;
1823
inline-roundtrip: func(a: map<u32, string>) -> map<string, u32>;
1924
large-roundtrip: func(a: names-by-id) -> names-by-id;
25+
multi-param-roundtrip: func(a: names-by-id, b: bytes-by-name) -> tuple<ids-by-name, bytes-by-name>;
26+
nested-roundtrip: func(a: map<string, map<u32, string>>) -> map<string, map<u32, string>>;
27+
variant-roundtrip: func(a: map-or-string) -> map-or-string;
28+
result-roundtrip: func(a: result<names-by-id, string>) -> result<names-by-id, string>;
2029
}
2130

2231
world test {

0 commit comments

Comments
 (0)