cli/pkg/githubtemplate/github_template_test.go
copilot-swe-agent[bot] dca59d52b6 Fix linting issues: canonicalheader, embeddedstructfieldcheck, iotamixing, makezero, testableexamples, wastedassign, usetesting, tparallel, unconvert, intrange, iface
- canonicalheader: fix cacheTTL header value to canonical form
- embeddedstructfieldcheck: move embedded fields before regular fields in 4 structs
- iotamixing: split const blocks mixing iota with non-iota constants
- makezero: use make([]T, 0, n) instead of make([]T, n) before appending
- testableexamples: add missing Output: comment to ExampleOption_UnwrapOrZero
- wastedassign: remove wasted initial assignments in 4 locations
- usetesting: replace os.MkdirTemp/os.Setenv with t.TempDir/t.Setenv in tests
- tparallel: add t.Parallel() to 8 top-level test functions
- unconvert: remove 16 unnecessary type conversions
- intrange: convert 3 for loops to use integer range syntax
- iface: consolidate identical EditPrompter and Prompt interfaces via type alias

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 11:05:52 +00:00

390 lines
7.7 KiB
Go

package githubtemplate
import (
"os"
"path"
"reflect"
"testing"
)
func TestFindNonLegacy(t *testing.T) {
tests := []struct {
name string
prepare []string
argName string
want []string
}{
{
name: "Legacy templates ignored",
prepare: []string{
"README.md",
"ISSUE_TEMPLATE",
"issue_template.md",
"issue_template.txt",
"pull_request_template.md",
".github/issue_template.md",
"docs/issue_template.md",
},
argName: "ISSUE_TEMPLATE",
want: []string{},
},
{
name: "Template folder in .github takes precedence",
prepare: []string{
"ISSUE_TEMPLATE.md",
"docs/ISSUE_TEMPLATE/abc.md",
"ISSUE_TEMPLATE/abc.md",
".github/ISSUE_TEMPLATE/abc.md",
},
argName: "ISSUE_TEMPLATE",
want: []string{".github/ISSUE_TEMPLATE/abc.md"},
},
{
name: "Template folder in root",
prepare: []string{
"ISSUE_TEMPLATE.md",
"docs/ISSUE_TEMPLATE/abc.md",
"ISSUE_TEMPLATE/abc.md",
},
argName: "ISSUE_TEMPLATE",
want: []string{"ISSUE_TEMPLATE/abc.md"},
},
{
name: "Template folder in docs",
prepare: []string{
"ISSUE_TEMPLATE.md",
"docs/ISSUE_TEMPLATE/abc.md",
},
argName: "ISSUE_TEMPLATE",
want: []string{"docs/ISSUE_TEMPLATE/abc.md"},
},
{
name: "Multiple templates in template folder",
prepare: []string{
".github/ISSUE_TEMPLATE/nope.md",
".github/PULL_REQUEST_TEMPLATE.md",
".github/PULL_REQUEST_TEMPLATE/one.md",
".github/PULL_REQUEST_TEMPLATE/two.md",
".github/PULL_REQUEST_TEMPLATE/three.md",
"docs/pull_request_template.md",
},
argName: "PuLl_ReQuEsT_TeMpLaTe",
want: []string{
".github/PULL_REQUEST_TEMPLATE/one.md",
".github/PULL_REQUEST_TEMPLATE/three.md",
".github/PULL_REQUEST_TEMPLATE/two.md",
},
},
{
name: "Empty template directories",
prepare: []string{
".github/ISSUE_TEMPLATE/.keep",
".docs/ISSUE_TEMPLATE/.keep",
"ISSUE_TEMPLATE/.keep",
},
argName: "ISSUE_TEMPLATE",
want: []string{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tmpdir := t.TempDir()
for _, p := range tt.prepare {
fp := path.Join(tmpdir, p)
_ = os.MkdirAll(path.Dir(fp), 0700)
file, err := os.Create(fp)
if err != nil {
t.Fatal(err)
}
file.Close()
}
want := make([]string, len(tt.want))
for i, w := range tt.want {
want[i] = path.Join(tmpdir, w)
}
if got := FindNonLegacy(tmpdir, tt.argName); !reflect.DeepEqual(got, want) {
t.Errorf("Find() = %v, want %v", got, want)
}
})
}
}
func TestFindLegacy(t *testing.T) {
tests := []struct {
name string
prepare []string
argName string
want string
}{
{
name: "Template in root",
prepare: []string{
"README.md",
"issue_template.md",
"issue_template.txt",
"pull_request_template.md",
"docs/issue_template.md",
},
argName: "ISSUE_TEMPLATE",
want: "issue_template.md",
},
{
name: "No extension",
prepare: []string{
"README.md",
"issue_template",
"docs/issue_template.md",
},
argName: "ISSUE_TEMPLATE",
want: "issue_template",
},
{
name: "Dash instead of underscore",
prepare: []string{
"README.md",
"issue-template.txt",
"docs/issue_template.md",
},
argName: "ISSUE_TEMPLATE",
want: "issue-template.txt",
},
{
name: "Template in .github takes precedence",
prepare: []string{
"ISSUE_TEMPLATE.md",
".github/issue_template.md",
"docs/issue_template.md",
},
argName: "ISSUE_TEMPLATE",
want: ".github/issue_template.md",
},
{
name: "Template in docs",
prepare: []string{
"README.md",
"docs/issue_template.md",
},
argName: "ISSUE_TEMPLATE",
want: "docs/issue_template.md",
},
{
name: "Non legacy templates ignored",
prepare: []string{
".github/PULL_REQUEST_TEMPLATE/abc.md",
"PULL_REQUEST_TEMPLATE/abc.md",
"docs/PULL_REQUEST_TEMPLATE/abc.md",
".github/PULL_REQUEST_TEMPLATE.md",
},
argName: "PuLl_ReQuEsT_TeMpLaTe",
want: ".github/PULL_REQUEST_TEMPLATE.md",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tmpdir := t.TempDir()
for _, p := range tt.prepare {
fp := path.Join(tmpdir, p)
_ = os.MkdirAll(path.Dir(fp), 0700)
file, err := os.Create(fp)
if err != nil {
t.Fatal(err)
}
file.Close()
}
want := path.Join(tmpdir, tt.want)
got := FindLegacy(tmpdir, tt.argName)
if got == "" {
t.Errorf("FindLegacy() = nil, want %v", want)
} else if got != want {
t.Errorf("FindLegacy() = %v, want %v", got, want)
}
})
}
}
func TestExtractName(t *testing.T) {
tmpfile, err := os.CreateTemp(t.TempDir(), "gh-cli")
if err != nil {
t.Fatal(err)
}
defer tmpfile.Close()
type args struct {
filePath string
}
tests := []struct {
name string
prepare string
args args
want string
}{
{
name: "Complete front-matter",
prepare: `---
name: Bug Report
about: This is how you report bugs
---
**Template contents**
`,
args: args{
filePath: tmpfile.Name(),
},
want: "Bug Report",
},
{
name: "Incomplete front-matter",
prepare: `---
about: This is how you report bugs
---
`,
args: args{
filePath: tmpfile.Name(),
},
want: path.Base(tmpfile.Name()),
},
{
name: "No front-matter",
prepare: `name: This is not yaml!`,
args: args{
filePath: tmpfile.Name(),
},
want: path.Base(tmpfile.Name()),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_ = os.WriteFile(tmpfile.Name(), []byte(tt.prepare), 0600)
if got := ExtractName(tt.args.filePath); got != tt.want {
t.Errorf("ExtractName() = %v, want %v", got, tt.want)
}
})
}
}
func TestExtractTitle(t *testing.T) {
tmpfile, err := os.CreateTemp(t.TempDir(), "gh-cli")
if err != nil {
t.Fatal(err)
}
defer tmpfile.Close()
type args struct {
filePath string
}
tests := []struct {
name string
prepare string
args args
want string
}{
{
name: "Complete front-matter",
prepare: `---
name: Bug Report
title: 'bug: '
about: This is how you report bugs
---
**Template contents**
`,
args: args{
filePath: tmpfile.Name(),
},
want: "bug: ",
},
{
name: "Incomplete front-matter",
prepare: `---
about: This is how you report bugs
---
`,
args: args{
filePath: tmpfile.Name(),
},
want: "",
},
{
name: "No front-matter",
prepare: `name: This is not yaml!`,
args: args{
filePath: tmpfile.Name(),
},
want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_ = os.WriteFile(tmpfile.Name(), []byte(tt.prepare), 0600)
if got := ExtractTitle(tt.args.filePath); got != tt.want {
t.Errorf("ExtractTitle() = %v, want %v", got, tt.want)
}
})
}
}
func TestExtractContents(t *testing.T) {
tmpfile, err := os.CreateTemp(t.TempDir(), "gh-cli")
if err != nil {
t.Fatal(err)
}
defer tmpfile.Close()
type args struct {
filePath string
}
tests := []struct {
name string
prepare string
args args
want string
}{
{
name: "Has front-matter",
prepare: `---
name: Bug Report
---
Template contents
---
More of template
`,
args: args{
filePath: tmpfile.Name(),
},
want: `Template contents
---
More of template
`,
},
{
name: "No front-matter",
prepare: `Template contents
---
More of template
---
Even more
`,
args: args{
filePath: tmpfile.Name(),
},
want: `Template contents
---
More of template
---
Even more
`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_ = os.WriteFile(tmpfile.Name(), []byte(tt.prepare), 0600)
if got := ExtractContents(tt.args.filePath); string(got) != tt.want {
t.Errorf("ExtractContents() = %v, want %v", string(got), tt.want)
}
})
}
}