Files
forge/modules/util/shellquote_test.go
zeekayandHanzo Dev aa87442fdd Record upstream authorship centrally in NOTICE instead of in every file header
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the
Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in
NOTICE, alongside LICENSE. The header lint accepts any copyright line above the
SPDX line, so it no longer demands an upstream one.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 17:50:35 -07:00

94 lines
2.6 KiB
Go

// Copyright 2026 Hanzo AI, Inc. All rights reserved.
// SPDX-License-Identifier: MIT
package util
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestShellEscape(t *testing.T) {
tests := []struct {
name string
toEscape string
want string
}{
{
"Simplest case - nothing to escape",
"a/b/c/d",
"a/b/c/d",
}, {
"Prefixed tilde - with normal stuff - should not escape",
"~/src/go/forge/forge",
"~/src/go/forge/forge",
}, {
"Typical windows path with spaces - should get doublequote escaped",
`C:\Program Files\Forge v1.13 - I like lots of spaces\forge`,
`"C:\\Program Files\\Forge v1.13 - I like lots of spaces\\forge"`,
}, {
"Forward-slashed windows path with spaces - should get doublequote escaped",
"C:/Program Files/Forge v1.13 - I like lots of spaces/forge",
`"C:/Program Files/Forge v1.13 - I like lots of spaces/forge"`,
}, {
"Prefixed tilde - but then a space filled path",
"~git/Forge v1.13/forge",
`~git/"Forge v1.13/forge"`,
}, {
"Bangs are unfortunately not predictable so need to be singlequoted",
"C:/Program Files/Forge!/forge",
`'C:/Program Files/Forge!/forge'`,
}, {
"Newlines are just irritating",
"/home/git/Forge\n\nWHY-WOULD-YOU-DO-THIS\n\nHanzo/forge",
"'/home/git/Forge\n\nWHY-WOULD-YOU-DO-THIS\n\nHanzo/forge'",
}, {
"Similarly we should nicely handle multiple single quotes if we have to single-quote",
"'!''!'''!''!'!'",
`\''!'\'\''!'\'\'\''!'\'\''!'\''!'\'`,
}, {
"Double quote < ...",
"~/<forge",
"~/\"<forge\"",
}, {
"Double quote > ...",
"~/forge>",
"~/\"forge>\"",
}, {
"Double quote and escape $ ...",
"~/$forge",
"~/\"\\$forge\"",
}, {
"Double quote {...",
"~/{forge",
"~/\"{forge\"",
}, {
"Double quote }...",
"~/forge}",
"~/\"forge}\"",
}, {
"Double quote ()...",
"~/(forge)",
"~/\"(forge)\"",
}, {
"Double quote and escape `...",
"~/forge`",
"~/\"forge\\`\"",
}, {
"Double quotes can handle a number of things without having to escape them but not everything ...",
"~/<forge> ${forge} `forge` [forge] (forge) \"forge\" \\forge\\ 'forge'",
"~/\"<forge> \\${forge} \\`forge\\` [forge] (forge) \\\"forge\\\" \\\\forge\\\\ 'forge'\"",
}, {
"Single quotes don't need to escape except for '...",
"~/<forge> ${forge} `forge` (forge) !forge! \"forge\" \\forge\\ 'forge'",
"~/'<forge> ${forge} `forge` (forge) !forge! \"forge\" \\forge\\ '\\''forge'\\'",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, ShellEscape(tt.toEscape))
})
}
}