[UI] Adjust trailing EOL behavior for empty file

- Follow up #4835
- Currently for empty files (file size is shown in the file header) the
"No EOL" information is being shown, even though it doesn't really
make sense to show that for empty files.
- Add integration test.
- Ref: https://codeberg.org/Codeberg/Community/issues/1612#issuecomment-2169437
This commit is contained in:
Gusted 2024-08-19 17:47:59 +02:00
parent 3b8ac4388a
commit e9a89a188e
No known key found for this signature in database
GPG key ID: FD821B732837125F
3 changed files with 33 additions and 28 deletions

View file

@ -564,15 +564,16 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
// empty: 0 lines; "a": 1 line; "a\n": 1 line; "a\nb": 2 lines; // empty: 0 lines; "a": 1 line; "a\n": 1 line; "a\nb": 2 lines;
// When rendering, the last empty line is not rendered in U and isn't counted towards the number of lines. // When rendering, the last empty line is not rendered in U and isn't counted towards the number of lines.
// To tell users that the file not contains a trailing EOL, text with a tooltip is displayed in the file header. // To tell users that the file not contains a trailing EOL, text with a tooltip is displayed in the file header.
// Trailing EOL is only considered if the file has content.
// This NumLines is only used for the display on the UI: "xxx lines" // This NumLines is only used for the display on the UI: "xxx lines"
hasTrailingEOL := bytes.HasSuffix(buf, []byte{'\n'})
ctx.Data["HasTrailingEOL"] = hasTrailingEOL
ctx.Data["HasTrailingEOLSet"] = true
if len(buf) == 0 { if len(buf) == 0 {
ctx.Data["NumLines"] = 0 ctx.Data["NumLines"] = 0
} else { } else {
hasNoTrailingEOL := !bytes.HasSuffix(buf, []byte{'\n'})
ctx.Data["HasNoTrailingEOL"] = hasNoTrailingEOL
numLines := bytes.Count(buf, []byte{'\n'}) numLines := bytes.Count(buf, []byte{'\n'})
if !hasTrailingEOL { if hasNoTrailingEOL {
numLines++ numLines++
} }
ctx.Data["NumLines"] = numLines ctx.Data["NumLines"] = numLines

View file

@ -9,7 +9,7 @@
{{.NumLines}} {{ctx.Locale.TrN .NumLines "repo.line" "repo.lines"}} {{.NumLines}} {{ctx.Locale.TrN .NumLines "repo.line" "repo.lines"}}
</div> </div>
{{end}} {{end}}
{{if and .HasTrailingEOLSet (not .HasTrailingEOL)}} {{if .HasNoTrailingEOL}}
<div class="file-info-entry" data-tooltip-content="{{ctx.Locale.Tr "repo.no_eol.tooltip"}}"> <div class="file-info-entry" data-tooltip-content="{{ctx.Locale.Tr "repo.no_eol.tooltip"}}">
{{ctx.Locale.Tr "repo.no_eol.text"}} {{ctx.Locale.Tr "repo.no_eol.text"}}
</div> </div>

View file

@ -179,43 +179,47 @@ func TestRepoViewFileLines(t *testing.T) {
TreePath: "test-4", TreePath: "test-4",
ContentReader: strings.NewReader("Really two\nlines\n"), ContentReader: strings.NewReader("Really two\nlines\n"),
}, },
{
Operation: "create",
TreePath: "empty",
ContentReader: strings.NewReader(""),
},
{
Operation: "create",
TreePath: "seemingly-empty",
ContentReader: strings.NewReader("\n"),
},
}) })
defer f() defer f()
t.Run("No EOL", func(t *testing.T) { testEOL := func(t *testing.T, filename string, hasEOL bool) {
defer tests.PrintCurrentTest(t)() t.Helper()
req := NewRequestf(t, "GET", "%s/src/branch/main/%s", repo.Link(), filename)
req := NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-1")
resp := MakeRequest(t, req, http.StatusOK) resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc := NewHTMLParser(t, resp.Body)
fileInfo := htmlDoc.Find(".file-info").Text() fileInfo := htmlDoc.Find(".file-info").Text()
if hasEOL {
assert.NotContains(t, fileInfo, "No EOL")
} else {
assert.Contains(t, fileInfo, "No EOL") assert.Contains(t, fileInfo, "No EOL")
}
}
req = NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-3") t.Run("No EOL", func(t *testing.T) {
resp = MakeRequest(t, req, http.StatusOK) defer tests.PrintCurrentTest(t)()
htmlDoc = NewHTMLParser(t, resp.Body)
fileInfo = htmlDoc.Find(".file-info").Text() testEOL(t, "test-1", false)
assert.Contains(t, fileInfo, "No EOL") testEOL(t, "test-3", false)
}) })
t.Run("With EOL", func(t *testing.T) { t.Run("With EOL", func(t *testing.T) {
defer tests.PrintCurrentTest(t)() defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-2") testEOL(t, "test-2", true)
resp := MakeRequest(t, req, http.StatusOK) testEOL(t, "test-4", true)
htmlDoc := NewHTMLParser(t, resp.Body) testEOL(t, "empty", true)
testEOL(t, "seemingly-empty", true)
fileInfo := htmlDoc.Find(".file-info").Text()
assert.NotContains(t, fileInfo, "No EOL")
req = NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-4")
resp = MakeRequest(t, req, http.StatusOK)
htmlDoc = NewHTMLParser(t, resp.Body)
fileInfo = htmlDoc.Find(".file-info").Text()
assert.NotContains(t, fileInfo, "No EOL")
}) })
}) })
} }