mirror of
https://github.com/go-gitea/gitea.git
synced 2025-10-22 08:04:37 +02:00
And by the way, remove the legacy TODO, split large functions into small ones, and add more tests
202 lines
6.6 KiB
Go
202 lines
6.6 KiB
Go
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package repository
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGiteaTemplate(t *testing.T) {
|
|
giteaTemplate := []byte(`
|
|
# Header
|
|
|
|
# All .go files
|
|
**.go
|
|
|
|
# All text files in /text/
|
|
text/*.txt
|
|
|
|
# All files in modules folders
|
|
**/modules/*
|
|
`)
|
|
|
|
gt := newGiteaTemplateFileMatcher("", giteaTemplate)
|
|
assert.Len(t, gt.globs, 3)
|
|
|
|
tt := []struct {
|
|
Path string
|
|
Match bool
|
|
}{
|
|
{Path: "main.go", Match: true},
|
|
{Path: "sub/sub/foo.go", Match: true},
|
|
|
|
{Path: "a.txt", Match: false},
|
|
{Path: "text/a.txt", Match: true},
|
|
{Path: "sub/text/a.txt", Match: false},
|
|
{Path: "text/a.json", Match: false},
|
|
|
|
{Path: "a/b/c/modules/README.md", Match: true},
|
|
{Path: "a/b/c/modules/d/README.md", Match: false},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
assert.Equal(t, tc.Match, gt.Match(tc.Path), "path: %s", tc.Path)
|
|
}
|
|
}
|
|
|
|
func TestFilePathSanitize(t *testing.T) {
|
|
assert.Equal(t, "test_CON", filePathSanitize("test_CON"))
|
|
assert.Equal(t, "test CON", filePathSanitize("test CON "))
|
|
assert.Equal(t, "__/traverse/__", filePathSanitize(".. /traverse/ .."))
|
|
assert.Equal(t, "./__/a/_git/b_", filePathSanitize("./../a/.git/ b: "))
|
|
assert.Equal(t, "_", filePathSanitize("CoN"))
|
|
assert.Equal(t, "_", filePathSanitize("LpT1"))
|
|
assert.Equal(t, "_", filePathSanitize("CoM1"))
|
|
assert.Equal(t, "_", filePathSanitize("\u0000"))
|
|
assert.Equal(t, "目标", filePathSanitize("目标"))
|
|
// unlike filepath.Clean, it only sanitizes, doesn't change the separator layout
|
|
assert.Equal(t, "", filePathSanitize("")) //nolint:testifylint // for easy reading
|
|
assert.Equal(t, ".", filePathSanitize("."))
|
|
assert.Equal(t, "/", filePathSanitize("/"))
|
|
}
|
|
|
|
func TestProcessGiteaTemplateFile(t *testing.T) {
|
|
tmpDir := filepath.Join(t.TempDir(), "gitea-template-test")
|
|
|
|
assertFileContent := func(path, expected string) {
|
|
data, err := os.ReadFile(filepath.Join(tmpDir, path))
|
|
if expected == "" {
|
|
assert.ErrorIs(t, err, os.ErrNotExist)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assert.Equal(t, expected, string(data), "file content mismatch for %s", path)
|
|
}
|
|
|
|
assertSymLink := func(path, expected string) {
|
|
link, err := os.Readlink(filepath.Join(tmpDir, path))
|
|
if expected == "" {
|
|
assert.ErrorIs(t, err, os.ErrNotExist)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assert.Equal(t, expected, link, "symlink target mismatch for %s", path)
|
|
}
|
|
|
|
require.NoError(t, os.MkdirAll(tmpDir+"/.gitea", 0o755))
|
|
require.NoError(t, os.WriteFile(tmpDir+"/.gitea/template", []byte("*\ninclude/**"), 0o644))
|
|
require.NoError(t, os.MkdirAll(tmpDir+"/sub", 0o755))
|
|
require.NoError(t, os.MkdirAll(tmpDir+"/include/foo/bar", 0o755))
|
|
|
|
require.NoError(t, os.WriteFile(tmpDir+"/sub/link-target", []byte("link target content from ${TEMPLATE_NAME}"), 0o644))
|
|
require.NoError(t, os.WriteFile(tmpDir+"/include/foo/bar/test.txt", []byte("include subdir ${TEMPLATE_NAME}"), 0o644))
|
|
|
|
// case-1
|
|
{
|
|
require.NoError(t, os.WriteFile(tmpDir+"/normal", []byte("normal content"), 0o644))
|
|
require.NoError(t, os.WriteFile(tmpDir+"/template", []byte("template from ${TEMPLATE_NAME}"), 0o644))
|
|
}
|
|
|
|
// case-2
|
|
{
|
|
require.NoError(t, os.Symlink(tmpDir+"/sub/link-target", tmpDir+"/link"))
|
|
}
|
|
|
|
// case-3
|
|
{
|
|
require.NoError(t, os.WriteFile(tmpDir+"/subst-${REPO_NAME}", []byte("dummy subst repo name"), 0o644))
|
|
}
|
|
|
|
// case-4
|
|
assertSubstTemplateName := func(normalContent, toLinkContent, fromLinkContent string) {
|
|
assertFileContent("subst-${TEMPLATE_NAME}-normal", normalContent)
|
|
assertFileContent("subst-${TEMPLATE_NAME}-to-link", toLinkContent)
|
|
assertFileContent("subst-${TEMPLATE_NAME}-from-link", fromLinkContent)
|
|
}
|
|
{
|
|
// will succeed
|
|
require.NoError(t, os.WriteFile(tmpDir+"/subst-${TEMPLATE_NAME}-normal", []byte("dummy subst template name normal"), 0o644))
|
|
// will skil if the path subst result is a link
|
|
require.NoError(t, os.WriteFile(tmpDir+"/subst-${TEMPLATE_NAME}-to-link", []byte("dummy subst template name to link"), 0o644))
|
|
require.NoError(t, os.Symlink(tmpDir+"/sub/link-target", tmpDir+"/subst-TemplateRepoName-to-link"))
|
|
// will be skipped since the source is a symlink
|
|
require.NoError(t, os.Symlink(tmpDir+"/sub/link-target", tmpDir+"/subst-${TEMPLATE_NAME}-from-link"))
|
|
// pre-check
|
|
assertSubstTemplateName("dummy subst template name normal", "dummy subst template name to link", "link target content from ${TEMPLATE_NAME}")
|
|
}
|
|
|
|
// process the template files
|
|
{
|
|
templateRepo := &repo_model.Repository{Name: "TemplateRepoName"}
|
|
generatedRepo := &repo_model.Repository{Name: "/../.gIt/name"}
|
|
fileMatcher, _ := readGiteaTemplateFile(tmpDir)
|
|
err := processGiteaTemplateFile(t.Context(), tmpDir, templateRepo, generatedRepo, fileMatcher)
|
|
require.NoError(t, err)
|
|
assertFileContent("include/foo/bar/test.txt", "include subdir TemplateRepoName")
|
|
}
|
|
|
|
// the lin target should never be modified, and since it is in a subdirectory, it is not affected by the template either
|
|
assertFileContent("sub/link-target", "link target content from ${TEMPLATE_NAME}")
|
|
|
|
// case-1
|
|
{
|
|
assertFileContent("no-such", "")
|
|
assertFileContent("normal", "normal content")
|
|
assertFileContent("template", "template from TemplateRepoName")
|
|
}
|
|
|
|
// case-2
|
|
{
|
|
// symlink with templates should be preserved (not read or write)
|
|
assertSymLink("link", tmpDir+"/sub/link-target")
|
|
}
|
|
|
|
// case-3
|
|
{
|
|
assertFileContent("subst-${REPO_NAME}", "")
|
|
assertFileContent("subst-/__/_gIt/name", "dummy subst repo name")
|
|
}
|
|
|
|
// case-4
|
|
{
|
|
// the paths with templates should have been removed, subst to a regular file, succeed, the link is preserved
|
|
assertSubstTemplateName("", "", "link target content from ${TEMPLATE_NAME}")
|
|
assertFileContent("subst-TemplateRepoName-normal", "dummy subst template name normal")
|
|
// subst to a link, skip, and the target is unchanged
|
|
assertSymLink("subst-TemplateRepoName-to-link", tmpDir+"/sub/link-target")
|
|
// subst from a link, skip, and the target is unchanged
|
|
assertSymLink("subst-${TEMPLATE_NAME}-from-link", tmpDir+"/sub/link-target")
|
|
}
|
|
}
|
|
|
|
func TestTransformers(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
expected string
|
|
}{
|
|
{"SNAKE", "abc_def_xyz"},
|
|
{"KEBAB", "abc-def-xyz"},
|
|
{"CAMEL", "abcDefXyz"},
|
|
{"PASCAL", "AbcDefXyz"},
|
|
{"LOWER", "abc_def-xyz"},
|
|
{"UPPER", "ABC_DEF-XYZ"},
|
|
{"TITLE", "Abc_def-Xyz"},
|
|
}
|
|
|
|
input := "Abc_Def-XYZ"
|
|
assert.Len(t, globalVars().defaultTransformers, len(cases))
|
|
for i, c := range cases {
|
|
tf := globalVars().defaultTransformers[i]
|
|
require.Equal(t, c.name, tf.Name)
|
|
assert.Equal(t, c.expected, tf.Transform(input), "case %s", c.name)
|
|
}
|
|
}
|