Files
90CNServer/pvf/internal/version/repository_test.go
T
hanfuit 645b64fe21 DNF90 服务端与启动器完整源码(含 GM 工具功能增强)
服务端(Go):
- GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面
- GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新
- 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新)
- 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍
- 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0)
- 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算

启动器(Python/JS):
- 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭
- GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐)
- 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
2026-11-04 14:31:55 +08:00

149 lines
3.9 KiB
Go

package version
import (
"bytes"
"os"
"path/filepath"
"testing"
"pvfine/internal/pvf"
)
func makeVersionFixture(t *testing.T) (string, *pvf.Archive, Snapshot) {
t.Helper()
a := pvf.New()
if _, err := a.AddFileText("skill/a.stk", "[name]\n`初始`", pvf.TypeScript); err != nil {
t.Fatal(err)
}
if _, err := a.AddFileText("text/name.str", "初始名称", pvf.TypeUnicode); err != nil {
t.Fatal(err)
}
path := filepath.Join(t.TempDir(), "Script.pvf")
if err := a.SaveAs(path); err != nil {
t.Fatal(err)
}
parsed, err := pvf.Open(path)
if err != nil {
t.Fatal(err)
}
snapshot, err := SnapshotFromArchive(parsed)
if err != nil {
t.Fatal(err)
}
return path, parsed, snapshot
}
func TestRepositoryCommitReopenAndMaterialize(t *testing.T) {
basePath, archive, base := makeVersionFixture(t)
baseHash, err := HashFile(basePath)
if err != nil {
t.Fatal(err)
}
root := SidecarPath(basePath)
repo, err := Init(root, basePath, baseHash, base)
if err != nil {
t.Fatal(err)
}
rootCommit, err := repo.Head()
if err != nil {
t.Fatal(err)
}
index, ok := archive.Find("skill/a.stk")
if !ok {
t.Fatal("fixture file missing")
}
if err := archive.SetText(index, "[name]\n`修改后`"); err != nil {
t.Fatal(err)
}
after, err := SnapshotFromArchive(archive)
if err != nil {
t.Fatal(err)
}
changes := Diff(base, after)
if len(changes) != 1 || changes[0].Operation != OperationModify {
t.Fatalf("changes = %#v", changes)
}
content, err := ContentSnapshotFromArchive(archive, []string{"skill/a.stk"})
if err != nil {
t.Fatal(err)
}
objects := map[string][]byte{}
for _, value := range content {
objects[value.Hash] = ContentObject(value)
}
commit, err := repo.Commit("修改技能名称", changes, objects)
if err != nil {
t.Fatal(err)
}
if commit.ParentID == "" || commit.ChangeCount != 1 {
t.Fatalf("commit = %#v", commit)
}
paths, err := repo.ChangedPathsBetween(rootCommit.ID, commit.ID)
if err != nil || len(paths) != 1 || paths[0] != "skill/a.stk" {
t.Fatalf("changed paths forward = %#v err=%v", paths, err)
}
paths, err = repo.ChangedPathsBetween(commit.ID, rootCommit.ID)
if err != nil || len(paths) != 1 || paths[0] != "skill/a.stk" {
t.Fatalf("changed paths reverse = %#v err=%v", paths, err)
}
materialized, err := repo.Snapshot(commit.ID)
if err != nil {
t.Fatal(err)
}
if materialized["skill/a.stk"].Hash != after["skill/a.stk"].Hash {
t.Fatalf("materialized = %#v after = %#v", materialized, after)
}
if materialized["text/name.str"].Hash != base["text/name.str"].Hash {
t.Fatalf("unchanged file was changed: %#v", materialized["text/name.str"])
}
if err := repo.Close(); err != nil {
t.Fatal(err)
}
reopened, err := Open(root)
if err != nil {
t.Fatal(err)
}
defer reopened.Close()
head, err := reopened.Head()
if err != nil || head.ID != commit.ID {
t.Fatalf("head = %#v err=%v", head, err)
}
history, next, err := reopened.History(0, 10)
if err != nil || next >= 0 || len(history) != 2 {
t.Fatalf("history = %#v next=%d err=%v", history, next, err)
}
got, err := reopened.Snapshot("")
if err != nil {
t.Fatal(err)
}
if TreeHash(got) != TreeHash(after) {
t.Fatalf("reopened tree hash = %s want %s", TreeHash(got), TreeHash(after))
}
}
func TestObjectStoreDeduplicatesAndRejectsInvalidHash(t *testing.T) {
store := newObjectStore(filepath.Join(t.TempDir(), "objects"))
raw := []byte("object")
first, err := store.Put(raw)
if err != nil {
t.Fatal(err)
}
second, err := store.Put(raw)
if err != nil || first != second {
t.Fatalf("duplicate object = %q %q err=%v", first, second, err)
}
got, err := store.Read(first)
if err != nil || !bytes.Equal(got, raw) {
t.Fatalf("read object = %q err=%v", got, err)
}
if _, err := store.Read("not-a-hash"); err == nil {
t.Fatal("invalid hash unexpectedly accepted")
}
if _, err := os.Stat(filepath.Join(store.root, first[:2], first[2:])); err != nil {
t.Fatal(err)
}
}