internal/autogen/inherit_test.go
Rama main · réplica de lectura del repositorio original.
package autogen
import (
"strings"
"testing"
)
// The sentinel exists because "" already means inherit, so a variant had no way
// to say "drop the knob the model-wide override sets". Each case is one of the
// three states the field now carries.
func TestInheritStr(t *testing.T) {
for _, c := range []struct {
name string
variant string
model string
want string
}{
{"blank inherits", "", "C:/t/model.jinja", "C:/t/model.jinja"},
{"blank inherits nothing", "", "", ""},
{"value pins", "C:/t/var.jinja", "C:/t/model.jinja", "C:/t/var.jinja"},
{"none drops the inherited value", "none", "C:/t/model.jinja", ""},
{"none is case-insensitive", "None", "C:/t/model.jinja", ""},
{"none tolerates padding", " none ", "C:/t/model.jinja", ""},
{"none with nothing to drop", "none", "", ""},
{"a path merely containing none still pins", "C:/none/x.jinja", "C:/t/m.jinja", "C:/none/x.jinja"},
} {
if got := inheritStr(c.variant, c.model); got != c.want {
t.Errorf("%s: inheritStr(%q, %q) = %q, want %q", c.name, c.variant, c.model, got, c.want)
}
}
}
// A sentinel written at model level would otherwise reach the emitter as a
// literal path, so it is cleared once at load.
func TestNormalizeNone(t *testing.T) {
o := Override{
ChatTemplateFile: "none", ExtraArgs: "NONE", TensorSplit: "none",
OverrideTensor: "3,1", VaePath: "none", T5Path: "D:/t5.gguf",
}
NormalizeNone(&o)
for name, got := range map[string]string{
"ChatTemplateFile": o.ChatTemplateFile, "ExtraArgs": o.ExtraArgs,
"TensorSplit": o.TensorSplit, "VaePath": o.VaePath,
} {
if got != "" {
t.Errorf("%s = %q, want cleared", name, got)
}
}
if o.OverrideTensor != "3,1" || o.T5Path != "D:/t5.gguf" {
t.Errorf("real values must survive: %q / %q", o.OverrideTensor, o.T5Path)
}
}
// The whole point, end to end: a variant of a model that pins a chat template
// can run on the gguf's baked-in one.
func TestBuildCmdLines_VariantDropsInheritedChatTemplate(t *testing.T) {
model := Override{ChatTemplateFile: "C:/my/tmpl.jinja", ExtraArgs: "--verbose"}
for _, c := range []struct {
name string
variant VariantSpec
wantTemplate string // "" => the flag must be absent
wantArgs string
}{
{"untouched variant inherits", VariantSpec{Name: "v"}, "C:/my/tmpl.jinja", "--verbose"},
{"variant pins its own", VariantSpec{Name: "v", ChatTemplateFile: "C:/other.jinja"}, "C:/other.jinja", "--verbose"},
{"none drops it", VariantSpec{Name: "v", ChatTemplateFile: "none"}, "", "--verbose"},
{"none drops extra args independently", VariantSpec{Name: "v", ExtraArgs: "none"}, "C:/my/tmpl.jinja", ""},
} {
eff := model
v := c.variant
mergeInheritStrings(&eff, &v)
if eff.ChatTemplateFile != c.wantTemplate {
t.Errorf("%s: template = %q, want %q", c.name, eff.ChatTemplateFile, c.wantTemplate)
}
if eff.ExtraArgs != c.wantArgs {
t.Errorf("%s: extraArgs = %q, want %q", c.name, eff.ExtraArgs, c.wantArgs)
}
s := Settings{}
s.applyDefaults()
prof := profile{Name: "t", Ctx: 8192}
got := strings.Join(buildCmdLines(s, Metadata{Architecture: "qwen35moe"}, GgufRow{FullPath: "/m.gguf"}, prof, 8192, 99, 0, "q8_0", "q8_0", false, &eff), " ")
if c.wantTemplate == "" {
if strings.Contains(got, "--chat-template-file") {
t.Errorf("%s: flag must be absent, got:\n%s", c.name, got)
}
} else if !strings.Contains(got, `--chat-template-file "`+c.wantTemplate+`"`) {
t.Errorf("%s: want %s in:\n%s", c.name, c.wantTemplate, got)
}
}
}