Coverage for tests/component/test_types.py: 100%
178 statements
« prev ^ index » next coverage.py v7.11.3, created at 2025-12-01 19:40 +0000
« prev ^ index » next coverage.py v7.11.3, created at 2025-12-01 19:40 +0000
1import unittest
3from wasmtime import Engine, FuncType as CoreFuncType, GlobalType, WasmtimeError
4from wasmtime.component import *
6def simplety(name):
7 engine = Engine()
8 c = Component(engine, f"""
9 (component
10 (import "a" (func (result {name})))
11 )
12 """)
13 fty = c.type.imports(engine)['a']
14 assert(isinstance(fty, FuncType))
15 return fty.result
17def namedty(contents):
18 engine = Engine()
19 c = Component(engine, f"""
20 (component
21 (type $t' {contents})
22 (import "t" (type $t (eq $t')))
23 (import "a" (func (result $t)))
24 )
25 """)
26 fty = c.type.imports(engine)['a']
27 assert(isinstance(fty, FuncType))
28 return fty.result
30class TestTypes(unittest.TestCase):
31 def test_component(self):
32 engine = Engine()
33 ty = Component(engine, '(component)').type
34 self.assertEqual(len(ty.imports(engine)), 0)
35 self.assertEqual(len(ty.exports(engine)), 0)
37 ty = Component(engine, """
38 (component
39 (import "a" (core module $a))
40 (export "g" (core module $a))
41 )
42 """).type
43 self.assertEqual(len(ty.imports(engine)), 1)
44 self.assertIsInstance(ty.imports(engine)['a'], ModuleType)
45 self.assertEqual(len(ty.exports(engine)), 1)
46 self.assertIsInstance(ty.exports(engine)['g'], ModuleType)
48 with self.assertRaises(WasmtimeError):
49 ComponentType()
51 def test_module(self):
52 engine = Engine()
53 c = Component(engine, """
54 (component
55 (import "a" (core module $a
56 (import "b" "c" (func))
57 (export "d" (global i32))
58 ))
59 )
60 """)
61 mty = c.type.imports(engine)['a']
62 assert(isinstance(mty, ModuleType))
63 imports = mty.imports(engine)
64 self.assertEqual(len(imports), 1)
65 exports = mty.exports(engine)
66 self.assertEqual(len(exports), 1)
68 self.assertEqual(imports[0].module, 'b')
69 self.assertEqual(imports[0].name, 'c')
70 self.assertIsInstance(imports[0].type, CoreFuncType)
72 self.assertEqual(exports[0].name, 'd')
73 self.assertIsInstance(exports[0].type, GlobalType)
75 with self.assertRaises(WasmtimeError):
76 ModuleType()
78 def test_resource(self):
79 engine = Engine()
80 c = Component(engine, """
81 (component
82 (import "a" (type $t (sub resource)))
83 (export "a" (type $t))
84 (type $t2 (resource (rep i32)))
85 (export "b" (type $t2))
86 )
87 """)
88 a1 = c.type.imports(engine)['a']
89 a2 = c.type.exports(engine)['a']
90 b = c.type.exports(engine)['b']
91 assert(isinstance(a1, ResourceType))
92 assert(isinstance(a2, ResourceType))
93 assert(isinstance(b, ResourceType))
94 self.assertEqual(a1, a2)
95 self.assertNotEqual(a1, b)
96 self.assertNotEqual(a2, b)
97 self.assertNotEqual(a2, 'hello')
99 with self.assertRaises(WasmtimeError):
100 ResourceType()
102 def test_instance(self):
103 engine = Engine()
104 cty = Component(engine, """
105 (component
106 (import "a" (instance
107 (export "a" (func))
108 (export "b" (core module))
109 ))
110 (import "b" (instance))
111 )
112 """).type
113 a = cty.imports(engine)['a']
114 b = cty.imports(engine)['b']
115 assert(isinstance(a, ComponentInstanceType))
116 assert(isinstance(b, ComponentInstanceType))
117 exports = a.exports(engine)
118 self.assertEqual(len(exports), 2)
119 self.assertIsInstance(exports['a'], FuncType)
120 self.assertIsInstance(exports['b'], ModuleType)
122 self.assertEqual(len(b.exports(engine)), 0)
124 with self.assertRaises(WasmtimeError):
125 ComponentInstanceType()
127 def test_func(self):
128 engine = Engine()
129 cty = Component(engine, """
130 (component
131 (import "a" (func))
132 (import "b" (func (param "x" u32)))
133 (import "c" (func (result string)))
134 (import "d" (func (param "a" u8) (param "b" u16) (result u32)))
135 )
136 """).type
137 a = cty.imports(engine)['a']
138 b = cty.imports(engine)['b']
139 c = cty.imports(engine)['c']
140 d = cty.imports(engine)['d']
141 assert(isinstance(a, FuncType))
142 assert(isinstance(b, FuncType))
143 assert(isinstance(c, FuncType))
144 assert(isinstance(d, FuncType))
146 self.assertEqual(a.params, [])
147 self.assertIsNone(a.result)
148 self.assertEqual(b.params, [('x', U32())])
149 self.assertIsNone(a.result)
150 self.assertEqual(c.params, [])
151 self.assertEqual(c.result, String())
152 self.assertEqual(d.params, [('a', U8()), ('b', U16())])
153 self.assertEqual(d.result, U32())
155 with self.assertRaises(WasmtimeError):
156 FuncType()
158 def test_primitives(self):
159 self.assertEqual(simplety('bool'), Bool())
160 self.assertEqual(simplety('u8'), U8())
161 self.assertEqual(simplety('u16'), U16())
162 self.assertEqual(simplety('u32'), U32())
163 self.assertEqual(simplety('u64'), U64())
164 self.assertEqual(simplety('s8'), S8())
165 self.assertEqual(simplety('s16'), S16())
166 self.assertEqual(simplety('s32'), S32())
167 self.assertEqual(simplety('s64'), S64())
168 self.assertEqual(simplety('f32'), F32())
169 self.assertEqual(simplety('f64'), F64())
170 self.assertEqual(simplety('char'), Char())
171 self.assertEqual(simplety('string'), String())
173 def test_list(self):
174 l = simplety('(list u8)')
175 assert(isinstance(l, ListType))
176 self.assertEqual(l.element, U8())
177 self.assertEqual(l, simplety('(list u8)'))
178 self.assertNotEqual(l, simplety('(list u16)'))
180 def test_record(self):
181 r = namedty('(record (field "a" u8) (field "b" f32))')
182 assert(isinstance(r, RecordType))
183 self.assertEqual(r.fields, [('a', U8()), ('b', F32())])
184 self.assertEqual(r, namedty('(record (field "a" u8) (field "b" f32))'))
185 self.assertNotEqual(r, namedty('(record (field "a" u8) (field "b" f64))'))
187 def test_tuple(self):
188 t = namedty('(tuple u8 f32)')
189 assert(isinstance(t, TupleType))
190 self.assertEqual(t.elements, [U8(), F32()])
191 self.assertEqual(t, namedty('(tuple u8 f32)'))
192 self.assertNotEqual(t, namedty('(tuple u8 f64)'))
194 def test_variant(self):
195 t = namedty('(variant (case "a") (case "b" f32))')
196 assert(isinstance(t, VariantType))
197 self.assertEqual(t.cases, [('a', None), ('b', F32())])
198 self.assertEqual(t, namedty('(variant (case "a") (case "b" f32))'))
199 self.assertNotEqual(t, namedty('(variant (case "a") (case "b" f64))'))
201 def test_enum(self):
202 e = namedty('(enum "a" "b" "c")')
203 assert(isinstance(e, EnumType))
204 self.assertEqual(e.names, ['a', 'b', 'c'])
205 self.assertEqual(e, namedty('(enum "a" "b" "c")'))
206 self.assertNotEqual(e, namedty('(enum "a" "b" "d")'))
208 def test_option(self):
209 o = simplety('(option u32)')
210 assert(isinstance(o, OptionType))
211 self.assertEqual(o.payload, U32())
212 self.assertEqual(o, simplety('(option u32)'))
213 self.assertNotEqual(o, simplety('(option u64)'))
215 def test_result(self):
216 r = simplety('(result u32 (error f32))')
217 assert(isinstance(r, ResultType))
218 self.assertEqual(r.ok, U32())
219 self.assertEqual(r.err, F32())
220 self.assertEqual(r, simplety('(result u32 (error f32))'))
222 r = simplety('(result (error f32))')
223 assert(isinstance(r, ResultType))
224 self.assertIsNone(r.ok)
225 self.assertEqual(r.err, F32())
227 r = simplety('(result u32)')
228 assert(isinstance(r, ResultType))
229 self.assertEqual(r.ok, U32())
230 self.assertIsNone(r.err)
232 r = simplety('(result)')
233 assert(isinstance(r, ResultType))
234 self.assertIsNone(r.ok)
235 self.assertIsNone(r.err)
237 def test_flags(self):
238 f = namedty('(flags "a" "b" "c")')
239 assert(isinstance(f, FlagsType))
240 self.assertEqual(f.names, ['a', 'b', 'c'])
241 self.assertEqual(f, namedty('(flags "a" "b" "c")'))
242 self.assertNotEqual(f, namedty('(flags "a" "b" "d")'))
244 def test_own_and_borrow(self):
245 engine = Engine()
246 c = Component(engine, f"""
247 (component
248 (import "r" (type $r (sub resource)))
249 (import "a" (func (param "x" (borrow $r)) (result (own $r))))
250 )
251 """)
252 fty = c.type.imports(engine)['a']
253 assert(isinstance(fty, FuncType))
254 _, param = fty.params[0]
255 result = fty.result
256 assert(isinstance(param, BorrowType))
257 assert(isinstance(result, OwnType))
258 self.assertEqual(param.ty, result.ty)