assets builder tools (#39)
Reviewed-on: #39 Reviewed-by: xtul <mpiasecki720@protonmail.com>
This commit was merged in pull request #39.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompileDrivesEngineAndReplacesInPlace(t *testing.T) {
|
||||
home := t.TempDir()
|
||||
userData := filepath.Join(home, ".local", "share", "Neverwinter Nights")
|
||||
dev := filepath.Join(userData, "development")
|
||||
mc := filepath.Join(userData, "modelcompiler")
|
||||
for _, d := range []string{dev, mc} {
|
||||
if err := os.MkdirAll(d, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
// Fake nwmain binary for discovery via --nwn.
|
||||
binDir := t.TempDir()
|
||||
nwmain := filepath.Join(binDir, "nwmain-linux")
|
||||
if err := os.WriteFile(nwmain, []byte("#!/bin/sh\n"), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
getenv := func(k string) string {
|
||||
switch k {
|
||||
case "HOME":
|
||||
return home
|
||||
case "DISPLAY":
|
||||
return ":0" // pretend a display exists so no xvfb wrap is needed
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Stub the engine: writes a binary compiled model into modelcompiler/.
|
||||
orig := runner
|
||||
defer func() { runner = orig }()
|
||||
runner = func(dir string, env []string, name string, args ...string) ([]byte, error) {
|
||||
// args: compilemodel <stem>
|
||||
stem := args[len(args)-1]
|
||||
compiled := filepath.Join(mc, stem+".mdl")
|
||||
return nil, os.WriteFile(compiled, []byte("\x00\x00compiled"), 0o644)
|
||||
}
|
||||
|
||||
// Source tree with one ASCII model whose names already match its stem.
|
||||
srcDir := t.TempDir()
|
||||
src := filepath.Join(srcDir, "foo.mdl")
|
||||
body := "newmodel foo\nbeginmodelgeom foo\n node dummy foo\n parent null\n endnode\nendmodelgeom foo\ndonemodel foo\n"
|
||||
if err := os.WriteFile(src, []byte(body), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
code := runCompile([]string{"--nwn", nwmain, srcDir}, &stdout, &stderr, getenv)
|
||||
if code != exitOK {
|
||||
t.Fatalf("compile exit = %d\n%s", code, stderr.String())
|
||||
}
|
||||
// The source is now binary (the compiled artifact moved back over it).
|
||||
data, err := os.ReadFile(src)
|
||||
if err != nil {
|
||||
t.Fatalf("compiled model missing: %v", err)
|
||||
}
|
||||
if string(data) != "\x00\x00compiled" {
|
||||
t.Fatalf("source not replaced by compiled binary: %q", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompileAbortsOnNameMismatch(t *testing.T) {
|
||||
home := t.TempDir()
|
||||
if err := os.MkdirAll(filepath.Join(home, ".local", "share", "Neverwinter Nights", "development"), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
binDir := t.TempDir()
|
||||
nwmain := filepath.Join(binDir, "nwmain-linux")
|
||||
if err := os.WriteFile(nwmain, []byte("#!/bin/sh\n"), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
getenv := func(k string) string {
|
||||
if k == "HOME" {
|
||||
return home
|
||||
}
|
||||
if k == "DISPLAY" {
|
||||
return ":0"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
orig := runner
|
||||
defer func() { runner = orig }()
|
||||
engineCalled := false
|
||||
runner = func(string, []string, string, ...string) ([]byte, error) {
|
||||
engineCalled = true
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
srcDir := t.TempDir()
|
||||
// Internal name "wrong" != stem "foo": must abort before touching the engine.
|
||||
if err := os.WriteFile(filepath.Join(srcDir, "foo.mdl"),
|
||||
[]byte("newmodel wrong\ndonemodel wrong\n"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var stdout, stderr bytes.Buffer
|
||||
if code := runCompile([]string{"--nwn", nwmain, srcDir}, &stdout, &stderr, getenv); code != exitFail {
|
||||
t.Fatalf("mismatch exit = %d, want %d", code, exitFail)
|
||||
}
|
||||
if engineCalled {
|
||||
t.Fatal("engine should not run for a name-mismatched model")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user