1package archesrv
2
3import (
4 "testing"
5
6 "arche/internal/object"
7)
8
9func TestParseSrvDiffLines_AddRemoveContext(t *testing.T) {
10 patch := `+added line
11-removed line
12 context line`
13
14 lines := parseSrvDiffLines(patch)
15 if len(lines) != 3 {
16 t.Fatalf("want 3 lines, got %d", len(lines))
17 }
18 if lines[0].Class != "diff-add" {
19 t.Errorf("line 0 class: want diff-add, got %q", lines[0].Class)
20 }
21 if lines[1].Class != "diff-del" {
22 t.Errorf("line 1 class: want diff-del, got %q", lines[1].Class)
23 }
24 if lines[2].Class != "" {
25 t.Errorf("line 2 class: want empty, got %q", lines[2].Class)
26 }
27}
28
29func TestParseSrvDiffLines_Headers(t *testing.T) {
30 cases := []struct {
31 line string
32 wantClass string
33 }{
34 {"--- a/foo.go", "diff-hdr"},
35 {"+++ b/foo.go", "diff-hdr"},
36 {"@@ -1,5 +1,6 @@", "diff-hdr"},
37 {"diff --git a/foo.go b/foo.go", "diff-hdr"},
38 }
39 for _, tc := range cases {
40 lines := parseSrvDiffLines(tc.line)
41 if len(lines) == 0 {
42 t.Fatalf("no lines parsed for %q", tc.line)
43 }
44 if lines[0].Class != tc.wantClass {
45 t.Errorf("line %q: want class %q, got %q", tc.line, tc.wantClass, lines[0].Class)
46 }
47 }
48}
49
50func TestParseSrvDiffLines_TextPreserved(t *testing.T) {
51 patch := "+hello world"
52 lines := parseSrvDiffLines(patch)
53 if len(lines) == 0 {
54 t.Fatal("expected at least one line")
55 }
56 if lines[0].Text != patch {
57 t.Errorf("text: want %q, got %q", patch, lines[0].Text)
58 }
59}
60
61func TestParseSrvDiffLines_EmptyInput(t *testing.T) {
62 lines := parseSrvDiffLines("")
63 if len(lines) != 1 {
64 t.Errorf("empty input: want 1 (empty) line, got %d", len(lines))
65 }
66 if lines[0].Text != "" || lines[0].Class != "" {
67 t.Errorf("unexpected non-empty line for empty input: %+v", lines[0])
68 }
69}
70
71func TestIsBinaryContent_NullByte(t *testing.T) {
72 if !isBinaryContent([]byte{0x68, 0x65, 0x00, 0x6c, 0x6f}) {
73 t.Error("expected binary when null byte present")
74 }
75}
76
77func TestIsBinaryContent_PlainText(t *testing.T) {
78 if isBinaryContent([]byte("hello, world\n")) {
79 t.Error("expected non-binary for plain text")
80 }
81}
82
83func TestIsBinaryContent_EmptySlice(t *testing.T) {
84 if isBinaryContent(nil) {
85 t.Error("nil slice should not be binary")
86 }
87 if isBinaryContent([]byte{}) {
88 t.Error("empty slice should not be binary")
89 }
90}
91
92func TestIsBinaryContent_AllFF(t *testing.T) {
93 if isBinaryContent([]byte{0xFF, 0xFE, 0xFD}) {
94 t.Error("0xFF without null should not be considered binary")
95 }
96}
97
98func TestModeStr(t *testing.T) {
99 cases := []struct {
100 mode object.EntryMode
101 want string
102 }{
103 {object.ModeFile, "file"},
104 {object.ModeExec, "exec"},
105 {object.ModeSymlink, "link"},
106 {object.ModeDir, "file"},
107 }
108 for _, tc := range cases {
109 got := modeStr(tc.mode)
110 if got != tc.want {
111 t.Errorf("modeStr(%v): want %q, got %q", tc.mode, tc.want, got)
112 }
113 }
114}