47 lines
1.3 KiB
Go
47 lines
1.3 KiB
Go
package tools
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestShellQuote covers the standard case and apostrophes: a value
|
|
// containing ' must still be safely shell-quoted (the '\” trick).
|
|
func TestShellQuote(t *testing.T) {
|
|
for _, in := range []string{"", "hello", "don't", "it's a 'test'", "a'b'c"} {
|
|
got := shellQuote(in)
|
|
if !strings.HasPrefix(got, "'") || !strings.HasSuffix(got, "'") {
|
|
t.Errorf("shellQuote(%q) = %q: not single-quoted", in, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestSedInPlaceEscapesApostrophe ensures that a replace whose text
|
|
// contains an apostrophe doesn't break the shell quoting. This runs the
|
|
// generated command for real against a temp file.
|
|
func TestSedInPlaceEscapesApostrophe(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := dir + "/app.conf"
|
|
if err := os.WriteFile(path, []byte("name: don't panic\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expr := "s/don't/can't/"
|
|
cmd := sedInPlace("", expr, path)
|
|
|
|
out, err := exec.Command("sh", "-c", cmd).CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("sed command failed: %v\n%s\ncmd=%s", err, out, cmd)
|
|
}
|
|
|
|
content, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(string(content), "can't panic") {
|
|
t.Errorf("expected replacement with apostrophe, got %q", content)
|
|
}
|
|
}
|