Skip to content

Commit 2e12eab

Browse files
committed
test
1 parent a37a073 commit 2e12eab

File tree

1 file changed

+392
-0
lines changed

1 file changed

+392
-0
lines changed

gnovm/pkg/gnolang/gotypecheck_test.go

+392
Original file line numberDiff line numberDiff line change
@@ -357,3 +357,395 @@ func Hello(name string) string {
357357
assert.NotEqual(t, input, pkg.Files[0].Body)
358358
assert.Equal(t, expected, pkg.Files[0].Body)
359359
}
360+
361+
func TestTypeCheckMemPackage_RealmImports(t *testing.T) {
362+
t.Parallel()
363+
364+
type testCase struct {
365+
name string
366+
pkg *gnovm.MemPackage
367+
getter MemPackageGetter
368+
check func(*testing.T, error)
369+
}
370+
371+
tests := []testCase{
372+
{
373+
name: "realm package with init-only imports",
374+
pkg: &gnovm.MemPackage{
375+
Name: "gns",
376+
Path: "gno.land/r/demo/gns",
377+
Files: []*gnovm.MemFile{
378+
{
379+
Name: "gns.gno",
380+
Body: `
381+
package gns
382+
import (
383+
"std"
384+
"gno.land/r/demo/registry"
385+
)
386+
387+
var (
388+
adminAddr std.Address
389+
)
390+
391+
func init() {
392+
registry.Register("gns")
393+
}
394+
395+
func GetAdmin() string {
396+
return string(adminAddr)
397+
}`,
398+
},
399+
},
400+
},
401+
getter: mockPackageGetter{
402+
&gnovm.MemPackage{
403+
Name: "std",
404+
Path: "std",
405+
Files: []*gnovm.MemFile{
406+
{
407+
Name: "std.gno",
408+
Body: `
409+
package std
410+
type Address string`,
411+
},
412+
},
413+
},
414+
&gnovm.MemPackage{
415+
Name: "registry",
416+
Path: "gno.land/r/demo/registry",
417+
Files: []*gnovm.MemFile{
418+
{
419+
Name: "registry.gno",
420+
Body: `
421+
package registry
422+
func Register(name string) {}`,
423+
},
424+
},
425+
},
426+
},
427+
check: func(t *testing.T, err error) {
428+
t.Helper()
429+
require.NoError(t, err, "should not report unused imports in realm packages")
430+
},
431+
},
432+
{
433+
name: "realm package with cross-realm imports",
434+
pkg: &gnovm.MemPackage{
435+
Name: "gns",
436+
Path: "gno.land/r/demo/gns",
437+
Files: []*gnovm.MemFile{
438+
{
439+
Name: "gns.gno",
440+
Body: `
441+
package gns
442+
import (
443+
"gno.land/r/demo/token"
444+
"gno.land/r/demo/registry"
445+
)
446+
447+
func init() {
448+
registry.Register()
449+
}
450+
451+
func Transfer(t token.Token) {
452+
t.Transfer()
453+
}`,
454+
},
455+
},
456+
},
457+
getter: mockPackageGetter{
458+
&gnovm.MemPackage{
459+
Name: "token",
460+
Path: "gno.land/r/demo/token",
461+
Files: []*gnovm.MemFile{
462+
{
463+
Name: "token.gno",
464+
Body: `
465+
package token
466+
type Token interface {
467+
Transfer()
468+
}`,
469+
},
470+
},
471+
},
472+
&gnovm.MemPackage{
473+
Name: "registry",
474+
Path: "gno.land/r/demo/registry",
475+
Files: []*gnovm.MemFile{
476+
{
477+
Name: "registry.gno",
478+
Body: `
479+
package registry
480+
func Register() {}`,
481+
},
482+
},
483+
},
484+
},
485+
check: func(t *testing.T, err error) {
486+
t.Helper()
487+
require.NoError(t, err, "should handle cross-realm imports correctly")
488+
},
489+
},
490+
{
491+
name: "debug realm package import scope",
492+
pkg: &gnovm.MemPackage{
493+
Name: "gns",
494+
Path: "gno.land/r/demo/gns",
495+
Files: []*gnovm.MemFile{
496+
{
497+
Name: "gns.gno",
498+
Body: `
499+
package gns
500+
import "gno.land/r/demo/registry"
501+
502+
func init() {
503+
registry.Register("test")
504+
}`,
505+
},
506+
},
507+
},
508+
getter: &debugPackageGetter{
509+
mockPackageGetter: mockPackageGetter{
510+
&gnovm.MemPackage{
511+
Name: "registry",
512+
Path: "gno.land/r/demo/registry",
513+
Files: []*gnovm.MemFile{
514+
{
515+
Name: "registry.gno",
516+
Body: `
517+
package registry
518+
func Register(name string) {}`,
519+
},
520+
},
521+
},
522+
},
523+
},
524+
check: func(t *testing.T, err error) {
525+
t.Helper()
526+
require.NoError(t, err)
527+
},
528+
},
529+
}
530+
531+
for _, tc := range tests {
532+
tc := tc
533+
t.Run(tc.name, func(t *testing.T) {
534+
t.Parallel()
535+
err := TypeCheckMemPackage(tc.pkg, tc.getter, false)
536+
if tc.check != nil {
537+
tc.check(t, err)
538+
} else {
539+
require.NoError(t, err)
540+
}
541+
})
542+
}
543+
}
544+
545+
func TestTypeCheckMemPackage_InitAndCallbacks(t *testing.T) {
546+
t.Parallel()
547+
548+
type testCase struct {
549+
name string
550+
pkg *gnovm.MemPackage
551+
getter MemPackageGetter
552+
check func(*testing.T, error)
553+
}
554+
555+
tests := []testCase{
556+
{
557+
name: "callback registration in init",
558+
pkg: &gnovm.MemPackage{
559+
Name: "callback",
560+
Path: "gno.land/r/demo/callback",
561+
Files: []*gnovm.MemFile{
562+
{
563+
Name: "callback.gno",
564+
Body: `
565+
package callback
566+
import "gno.land/r/demo/events"
567+
568+
func MintCallback(amount uint64) {
569+
// will be called at runtime
570+
}
571+
572+
func init() {
573+
events.RegisterCallback("mint", MintCallback)
574+
}`,
575+
},
576+
},
577+
},
578+
getter: mockPackageGetter{
579+
&gnovm.MemPackage{
580+
Name: "events",
581+
Path: "gno.land/r/demo/events",
582+
Files: []*gnovm.MemFile{
583+
{
584+
Name: "events.gno",
585+
Body: `
586+
package events
587+
588+
type CallbackFn func(uint64)
589+
590+
func RegisterCallback(event string, fn CallbackFn) {}`,
591+
},
592+
},
593+
},
594+
},
595+
check: func(t *testing.T, err error) {
596+
t.Helper()
597+
require.NoError(t, err, "callback registration should be recognized as package usage")
598+
},
599+
},
600+
{
601+
name: "multiple aliases with init usage",
602+
pkg: &gnovm.MemPackage{
603+
Name: "main",
604+
Path: "gno.land/r/demo/main",
605+
Files: []*gnovm.MemFile{
606+
{
607+
Name: "main.gno",
608+
Body: `
609+
package main
610+
611+
import (
612+
ev "gno.land/r/demo/events"
613+
cb "gno.land/r/demo/callback"
614+
)
615+
616+
func ProcessEvent(amount uint64) {
617+
// will be called at runtime
618+
}
619+
620+
func init() {
621+
ev.RegisterCallback("process", ProcessEvent)
622+
cb.SetHandler(ProcessEvent)
623+
}`,
624+
},
625+
},
626+
},
627+
getter: mockPackageGetter{
628+
&gnovm.MemPackage{
629+
Name: "events",
630+
Path: "gno.land/r/demo/events",
631+
Files: []*gnovm.MemFile{
632+
{
633+
Name: "events.gno",
634+
Body: `
635+
package events
636+
type CallbackFn func(uint64)
637+
func RegisterCallback(event string, fn CallbackFn) {}`,
638+
},
639+
},
640+
},
641+
&gnovm.MemPackage{
642+
Name: "callback",
643+
Path: "gno.land/r/demo/callback",
644+
Files: []*gnovm.MemFile{
645+
{
646+
Name: "callback.gno",
647+
Body: `
648+
package callback
649+
type HandlerFn func(uint64)
650+
func SetHandler(fn HandlerFn) {}`,
651+
},
652+
},
653+
},
654+
},
655+
check: func(t *testing.T, err error) {
656+
t.Helper()
657+
require.NoError(t, err, "aliased imports in init should be recognized")
658+
},
659+
},
660+
{
661+
name: "init with deferred callback setup",
662+
pkg: &gnovm.MemPackage{
663+
Name: "deferred",
664+
Path: "gno.land/r/demo/deferred",
665+
Files: []*gnovm.MemFile{
666+
{
667+
Name: "deferred.gno",
668+
Body: `
669+
package deferred
670+
671+
import handler "gno.land/r/demo/handler"
672+
673+
var setupCallback func()
674+
675+
func init() {
676+
setupCallback = func() {
677+
handler.Register("deferred", processEvent)
678+
}
679+
setupCallback()
680+
}
681+
682+
func processEvent() {}`,
683+
},
684+
},
685+
},
686+
getter: mockPackageGetter{
687+
&gnovm.MemPackage{
688+
Name: "handler",
689+
Path: "gno.land/r/demo/handler",
690+
Files: []*gnovm.MemFile{
691+
{
692+
Name: "handler.gno",
693+
Body: `
694+
package handler
695+
func Register(name string, fn func()) {}`,
696+
},
697+
},
698+
},
699+
},
700+
check: func(t *testing.T, err error) {
701+
t.Helper()
702+
require.NoError(t, err, "deferred callback setup should be recognized")
703+
},
704+
},
705+
}
706+
707+
for _, tc := range tests {
708+
tc := tc
709+
t.Run(tc.name, func(t *testing.T) {
710+
t.Parallel()
711+
712+
debugGetter := &debugPackageGetter{
713+
mockPackageGetter: tc.getter.(mockPackageGetter),
714+
}
715+
716+
err := TypeCheckMemPackage(tc.pkg, debugGetter, false)
717+
718+
t.Logf("Imported packages: %v", debugGetter.GetImportedPackages())
719+
720+
if tc.check != nil {
721+
tc.check(t, err)
722+
} else {
723+
require.NoError(t, err)
724+
}
725+
})
726+
}
727+
}
728+
729+
type debugPackageGetter struct {
730+
mockPackageGetter
731+
importedPkgs map[string]bool
732+
}
733+
734+
func (d *debugPackageGetter) GetMemPackage(path string) *gnovm.MemPackage {
735+
if d.importedPkgs == nil {
736+
d.importedPkgs = make(map[string]bool)
737+
}
738+
pkg := d.mockPackageGetter.GetMemPackage(path)
739+
if pkg != nil {
740+
d.importedPkgs[path] = true
741+
}
742+
return pkg
743+
}
744+
745+
func (d *debugPackageGetter) GetImportedPackages() []string {
746+
var pkgs []string
747+
for pkg := range d.importedPkgs {
748+
pkgs = append(pkgs, pkg)
749+
}
750+
return pkgs
751+
}

0 commit comments

Comments
 (0)