Files

204 lines
4.9 KiB
Go

//go:build !aego_runtime
package docs_test
import (
"encoding/json"
"os"
"strings"
"testing"
"testing/fstest"
"aego/app/assembly"
"aego/app/assembly/builtin"
"aego/engine/docs"
"aego/engine/module"
scriptsystems "aego/modules/scripting/systems"
"aego/script/bind"
"aego/script/bind/manifest"
"aego/script/diag"
)
func build(t *testing.T, extra ...module.DocSource) (*docs.Registry, *manifest.Manifest) {
t.Helper()
r, bm, _ := buildWith(t, extra...)
return r, bm
}
func buildWith(t *testing.T, extra ...module.DocSource) (*docs.Registry, *manifest.Manifest, *bind.Registry) {
t.Helper()
types, err := assembly.NewTypes()
if err != nil {
t.Fatal(err)
}
reg := bind.New()
man, err := builtin.Default().Load(types, reg, assembly.Options{Seed: 1, Testing: true})
if err != nil {
t.Fatal(err)
}
if err := types.Schema().Freeze(); err != nil {
t.Fatal(err)
}
if err := scriptsystems.Freeze(reg, types.Schema()); err != nil {
t.Fatal(err)
}
bm, err := manifest.FromRegistry(reg, types.Schema())
if err != nil {
t.Fatal(err)
}
man.Docs = append(man.Docs, extra...)
return docs.FromManifest(bm, types.Schema(), man), bm, reg
}
func TestCoverage(t *testing.T) {
r, bm := build(t)
want := func(id string, k docs.Kind) {
t.Helper()
e, ok := r.Get(id)
if !ok {
t.Errorf("no entry %s", id)
return
}
if e.Kind != k {
t.Errorf("%s is %s, want %s", id, e.Kind, k)
}
}
for _, m := range bm.Modules {
want(m.Path, docs.Module)
for _, f := range m.Funcs {
want(m.Path+"."+f.Name, docs.Function)
}
for _, c := range m.Consts {
want(m.Path+"."+c.Name, docs.Const)
}
}
for _, e := range bm.Enums {
want(e.Module+"."+e.Name, docs.Enum)
}
for _, me := range bm.Methods {
want(docs.BuiltinID+"."+me.Recv.String()+"."+me.Name, docs.Method)
}
for _, c := range bm.Components {
want(c.Name, docs.Type)
for _, f := range c.Fields {
want(c.Name+"."+f.Name, docs.Field)
}
}
for _, c := range diag.Codes() {
want(c, docs.Code)
}
for _, p := range r.Check(false) {
if p.Error {
t.Errorf("%s: %s", p.ID, p.Message)
}
}
}
func TestSearchClamp(t *testing.T) {
r, _ := build(t)
hits := r.Search("clamp", 5)
if len(hits) == 0 || hits[0].ID != "aego/math.Clamp" {
ids := make([]string, len(hits))
for i, h := range hits {
ids[i] = h.ID
}
t.Fatalf("Search(clamp) = %v", ids)
}
}
func TestPages(t *testing.T) {
src := strings.Join([]string{
"---",
"id: test/coroutines",
"title: Coroutines",
"order: 2",
`requires: [script, "render2d"]`,
"---",
"# Coroutines",
"",
"A coroutine pauses with [yield](ref:test/yield) and resumes later.",
"",
"```aes run",
"package demo",
"---",
"```",
"---",
"id: test/yield",
"parent: test/coroutines",
`keys: ["test yield", "test yield, again"]`,
"---",
"yield pauses the current coroutine.",
"---",
"id: aego/math.Clamp",
"---",
"Extra text for [nothing](ref:missing/entry).",
"",
}, "\n")
fsys := fstest.MapFS{"lang.md": {Data: []byte(src)}}
r, _ := build(t, module.DocSource{Owner: "script", FS: fsys})
page, ok := r.Get("test/coroutines")
if !ok {
t.Fatal("page missing")
}
if page.Summary != "A coroutine pauses with yield and resumes later." {
t.Errorf("summary = %q", page.Summary)
}
if len(page.Snippets) != 1 || !page.Snippets[0].Run || page.Snippets[0].Lang != "aes" || page.Snippets[0].Code != "package demo\n---" {
t.Errorf("snippets = %+v", page.Snippets)
}
if len(page.Requires) != 2 || page.Requires[1] != "render2d" {
t.Errorf("requires = %v", page.Requires)
}
if e, ok := r.ByKey("test yield, again"); !ok || e.ID != "test/yield" {
t.Errorf("ByKey = %v %v", e.ID, ok)
}
if kids := r.Children("test/coroutines"); len(kids) != 1 || kids[0].ID != "test/yield" {
t.Errorf("children = %v", kids)
}
clamp, _ := r.Get("aego/math.Clamp")
if clamp.Kind != docs.Function || !strings.Contains(clamp.Body, "Extra text") {
t.Errorf("clamp not merged: %+v", clamp)
}
broken := false
for _, p := range r.Check(false) {
if p.Error && p.ID == "aego/math.Clamp" && strings.Contains(p.Message, "missing/entry") {
broken = true
}
}
if !broken {
t.Error("broken ref link is not reported")
}
}
func TestKeywordsMatchLegacy(t *testing.T) {
r, _ := build(t)
data, err := os.ReadFile("testdata/keywords.golden.json")
if err != nil {
t.Fatal(err)
}
var want map[string]string
if err := json.Unmarshal(data, &want); err != nil {
t.Fatal(err)
}
got := r.Keywords()
for k, v := range want {
if got[k] != v {
t.Errorf("hover text of %q changed:\n got %q\nwant %q", k, got[k], v)
}
}
if len(got) != len(want) {
t.Errorf("%d keywords, want %d", len(got), len(want))
}
}
func TestCompose(t *testing.T) {
r, _ := build(t)
md := r.Compose("language")
for _, want := range []string{"# Aego Script\n", "\n## Coroutines\n", "\n### yield wait\n"} {
if !strings.Contains(md, want) {
t.Errorf("Compose(language) has no %q", want)
}
}
}