Skip to content

Commit 98170af

Browse files
committed
Add 0.15 regression tests for any and untyped scripts
1 parent c245d6d commit 98170af

2 files changed

Lines changed: 87 additions & 2 deletions

File tree

ROADMAP.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,12 @@ Goal: make types expressive enough for real workflows while keeping runtime chec
192192

193193
- [x] Add parser tests for all new type syntax forms.
194194
- [x] Add runtime tests for nested composite type checks.
195-
- [ ] Add regression tests for existing `any` and nullable behavior.
195+
- [x] Add regression tests for existing `any` and nullable behavior.
196196
- [ ] Expand `docs/typing.md` with migration examples.
197197

198198
### v0.15.0 Definition of Done
199199

200-
- [ ] Existing scripts without annotations remain compatible.
200+
- [x] Existing scripts without annotations remain compatible.
201201
- [x] Type errors include parameter name, expected type, and actual type.
202202
- [x] Capability contract validation can use the same type primitives.
203203

vibes/runtime_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,91 @@ func TestTypedFunctions(t *testing.T) {
13601360
}
13611361
}
13621362

1363+
func TestTypedFunctionsRegressionAnyAndNullableBehavior(t *testing.T) {
1364+
script := compileScript(t, `
1365+
def takes_any(v: any) -> any
1366+
v
1367+
end
1368+
1369+
def takes_nullable(v: string? = nil) -> string?
1370+
v
1371+
end
1372+
1373+
def takes_nullable_union(v: string | nil) -> string | nil
1374+
v
1375+
end
1376+
`)
1377+
1378+
anyBuiltin := NewBuiltin("tmp.any", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
1379+
return NewNil(), nil
1380+
})
1381+
if got := callFunc(t, script, "takes_any", []Value{anyBuiltin}); got.Kind() != KindBuiltin {
1382+
t.Fatalf("takes_any builtin mismatch: %#v", got)
1383+
}
1384+
if got := callFunc(t, script, "takes_any", []Value{NewHash(map[string]Value{"x": NewInt(1)})}); got.Kind() != KindHash {
1385+
t.Fatalf("takes_any hash mismatch: %#v", got)
1386+
}
1387+
if got := callFunc(t, script, "takes_any", []Value{NewNil()}); got.Kind() != KindNil {
1388+
t.Fatalf("takes_any nil mismatch: %#v", got)
1389+
}
1390+
1391+
if got := callFunc(t, script, "takes_nullable", nil); got.Kind() != KindNil {
1392+
t.Fatalf("takes_nullable default nil mismatch: %#v", got)
1393+
}
1394+
if got := callFunc(t, script, "takes_nullable", []Value{NewString("ok")}); got.Kind() != KindString || got.String() != "ok" {
1395+
t.Fatalf("takes_nullable string mismatch: %#v", got)
1396+
}
1397+
_, err := script.Call(context.Background(), "takes_nullable", []Value{NewInt(1)}, CallOptions{})
1398+
if err == nil || !strings.Contains(err.Error(), "argument v expected string?, got int") {
1399+
t.Fatalf("expected nullable type mismatch, got %v", err)
1400+
}
1401+
1402+
if got := callFunc(t, script, "takes_nullable_union", []Value{NewNil()}); got.Kind() != KindNil {
1403+
t.Fatalf("takes_nullable_union nil mismatch: %#v", got)
1404+
}
1405+
if got := callFunc(t, script, "takes_nullable_union", []Value{NewString("ok")}); got.Kind() != KindString || got.String() != "ok" {
1406+
t.Fatalf("takes_nullable_union string mismatch: %#v", got)
1407+
}
1408+
_, err = script.Call(context.Background(), "takes_nullable_union", []Value{NewInt(1)}, CallOptions{})
1409+
if err == nil || !strings.Contains(err.Error(), "argument v expected string | nil, got int") {
1410+
t.Fatalf("expected nullable union mismatch, got %v", err)
1411+
}
1412+
}
1413+
1414+
func TestExistingUntypedScriptsRemainCompatible(t *testing.T) {
1415+
script := compileScript(t, `
1416+
def identity(v)
1417+
v
1418+
end
1419+
1420+
def run()
1421+
first = identity(1)
1422+
second = identity("two")
1423+
third = identity({ ok: true })
1424+
{
1425+
first: first,
1426+
second: second,
1427+
third_ok: third[:ok]
1428+
}
1429+
end
1430+
`)
1431+
1432+
got := callFunc(t, script, "run", nil)
1433+
if got.Kind() != KindHash {
1434+
t.Fatalf("expected hash result, got %v", got.Kind())
1435+
}
1436+
hash := got.Hash()
1437+
if hash["first"].Kind() != KindInt || hash["first"].Int() != 1 {
1438+
t.Fatalf("unexpected first value: %#v", hash["first"])
1439+
}
1440+
if hash["second"].Kind() != KindString || hash["second"].String() != "two" {
1441+
t.Fatalf("unexpected second value: %#v", hash["second"])
1442+
}
1443+
if hash["third_ok"].Kind() != KindBool || !hash["third_ok"].Bool() {
1444+
t.Fatalf("unexpected third_ok value: %#v", hash["third_ok"])
1445+
}
1446+
}
1447+
13631448
func TestArrayAndHashHelpers(t *testing.T) {
13641449
script := compileScript(t, `
13651450
def array_helpers()

0 commit comments

Comments
 (0)