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

1import unittest 

2 

3from wasmtime import Engine, FuncType as CoreFuncType, GlobalType, WasmtimeError 

4from wasmtime.component import * 

5 

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 

16 

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 

29 

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) 

36 

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) 

47 

48 with self.assertRaises(WasmtimeError): 

49 ComponentType() 

50 

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) 

67 

68 self.assertEqual(imports[0].module, 'b') 

69 self.assertEqual(imports[0].name, 'c') 

70 self.assertIsInstance(imports[0].type, CoreFuncType) 

71 

72 self.assertEqual(exports[0].name, 'd') 

73 self.assertIsInstance(exports[0].type, GlobalType) 

74 

75 with self.assertRaises(WasmtimeError): 

76 ModuleType() 

77 

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') 

98 

99 with self.assertRaises(WasmtimeError): 

100 ResourceType() 

101 

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) 

121 

122 self.assertEqual(len(b.exports(engine)), 0) 

123 

124 with self.assertRaises(WasmtimeError): 

125 ComponentInstanceType() 

126 

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)) 

145 

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()) 

154 

155 with self.assertRaises(WasmtimeError): 

156 FuncType() 

157 

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()) 

172 

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)')) 

179 

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))')) 

186 

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)')) 

193 

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))')) 

200 

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")')) 

207 

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)')) 

214 

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))')) 

221 

222 r = simplety('(result (error f32))') 

223 assert(isinstance(r, ResultType)) 

224 self.assertIsNone(r.ok) 

225 self.assertEqual(r.err, F32()) 

226 

227 r = simplety('(result u32)') 

228 assert(isinstance(r, ResultType)) 

229 self.assertEqual(r.ok, U32()) 

230 self.assertIsNone(r.err) 

231 

232 r = simplety('(result)') 

233 assert(isinstance(r, ResultType)) 

234 self.assertIsNone(r.ok) 

235 self.assertIsNone(r.err) 

236 

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")')) 

243 

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)