blob: b546218a3c589f3c1da6566a38b7677a5407083d [file] [log] [blame]
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package generate
import (
"os"
"reflect"
"runtime"
"testing"
)
type splitTest struct {
in string
out []string
}
// Same as above, except including source line number to set
type splitTestWithLine struct {
in string
out []string
lineNumber int
}
const anyLineNo = 0
var splitTests = []splitTest{
{"", nil},
{"x", []string{"x"}},
{" a b\tc ", []string{"a", "b", "c"}},
{` " a " `, []string{" a "}},
{"$GOARCH", []string{runtime.GOARCH}},
{"$GOOS", []string{runtime.GOOS}},
{"$GOFILE", []string{"proc.go"}},
{"$GOPACKAGE", []string{"sys"}},
{"a $XXNOTDEFINEDXX b", []string{"a", "", "b"}},
{"/$XXNOTDEFINED/", []string{"//"}},
{"/$DOLLAR/", []string{"/$/"}},
{"yacc -o $GOARCH/yacc_$GOFILE", []string{"go", "tool", "yacc", "-o", runtime.GOARCH + "/yacc_proc.go"}},
}
func TestGenerateCommandParse(t *testing.T) {
g := &Generator{
r: nil, // Unused here.
path: "/usr/ken/sys/proc.go",
dir: "/usr/ken/sys",
file: "proc.go",
pkg: "sys",
commands: make(map[string][]string),
}
g.setEnv()
g.setShorthand([]string{"-command", "yacc", "go", "tool", "yacc"})
for _, test := range splitTests {
// First with newlines.
got := g.split("//go:generate " + test.in + "\n")
if !reflect.DeepEqual(got, test.out) {
t.Errorf("split(%q): got %q expected %q", test.in, got, test.out)
}
// Then with CRLFs, thank you Windows.
got = g.split("//go:generate " + test.in + "\r\n")
if !reflect.DeepEqual(got, test.out) {
t.Errorf("split(%q): got %q expected %q", test.in, got, test.out)
}
}
}
// These environment variables will be undefined before the splitTestWithLine tests
var undefEnvList = []string{
"_XYZZY_",
}
// These environment variables will be defined before the splitTestWithLine tests
var defEnvMap = map[string]string{
"_PLUGH_": "SomeVal",
"_X": "Y",
}
// TestGenerateCommandShortHand - similar to TestGenerateCommandParse,
// except:
// 1. if the result starts with -command, record that shorthand
// before moving on to the next test.
// 2. If a source line number is specified, set that in the parser
// before executing the test. i.e., execute the split as if it
// processing that source line.
func TestGenerateCommandShorthand(t *testing.T) {
g := &Generator{
r: nil, // Unused here.
path: "/usr/ken/sys/proc.go",
dir: "/usr/ken/sys",
file: "proc.go",
pkg: "sys",
commands: make(map[string][]string),
}
var inLine string
var expected, got []string
g.setEnv()
// Set up the system environment variables
for i := range undefEnvList {
os.Unsetenv(undefEnvList[i])
}
for k := range defEnvMap {
os.Setenv(k, defEnvMap[k])
}
// simple command from environment variable
inLine = "//go:generate -command CMD0 \"ab${_X}cd\""
expected = []string{"-command", "CMD0", "abYcd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
// try again, with an extra level of indirection (should leave variable in command)
inLine = "//go:generate -command CMD0 \"ab${DOLLAR}{_X}cd\""
expected = []string{"-command", "CMD0", "ab${_X}cd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
// Now the interesting part, record that output as a command
g.setShorthand(got)
// see that the command still substitutes correctly from env. variable
inLine = "//go:generate CMD0"
expected = []string{"abYcd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
// Now change the value of $X and see if the recorded definition is
// still intact (vs. having the $_X already substituted out)
os.Setenv("_X", "Z")
inLine = "//go:generate CMD0"
expected = []string{"abZcd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
// What if the variable is now undefined? Should be empty substitution.
os.Unsetenv("_X")
inLine = "//go:generate CMD0"
expected = []string{"abcd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
// Try another undefined variable as an extra check
os.Unsetenv("_Z")
inLine = "//go:generate -command CMD1 \"ab${_Z}cd\""
expected = []string{"-command", "CMD1", "abcd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
g.setShorthand(got)
inLine = "//go:generate CMD1"
expected = []string{"abcd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
const val = "someNewValue"
os.Setenv("_Z", val)
// try again with the properly-escaped variable.
inLine = "//go:generate -command CMD2 \"ab${DOLLAR}{_Z}cd\""
expected = []string{"-command", "CMD2", "ab${_Z}cd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
g.setShorthand(got)
inLine = "//go:generate CMD2"
expected = []string{"ab" + val + "cd"}
got = g.split(inLine + "\n")
if !reflect.DeepEqual(got, expected) {
t.Errorf("split(%q): got %q expected %q", inLine, got, expected)
}
}
// Command-related tests for TestGenerateCommandShortHand2
// -- Note line numbers included to check substitutions from "build-in" variable - $GOLINE
var splitTestsLines = []splitTestWithLine{
{"-command TEST1 $GOLINE", []string{"-command", "TEST1", "22"}, 22},
{"-command TEST2 ${DOLLAR}GOLINE", []string{"-command", "TEST2", "$GOLINE"}, 26},
{"TEST1", []string{"22"}, 33},
{"TEST2", []string{"66"}, 66},
{"TEST1 ''", []string{"22", "''"}, 99},
{"TEST2 ''", []string{"44", "''"}, 44},
}
// TestGenerateCommandShortHand - similar to TestGenerateCommandParse,
// except:
// 1. if the result starts with -command, record that shorthand
// before moving on to the next test.
// 2. If a source line number is specified, set that in the parser
// before executing the test. i.e., execute the split as if it
// processing that source line.
func TestGenerateCommandShortHand2(t *testing.T) {
g := &Generator{
r: nil, // Unused here.
path: "/usr/ken/sys/proc.go",
dir: "/usr/ken/sys",
file: "proc.go",
pkg: "sys",
commands: make(map[string][]string),
}
g.setEnv()
for _, test := range splitTestsLines {
// if the test specified a line number, reflect that
if test.lineNumber != anyLineNo {
g.lineNum = test.lineNumber
g.setEnv()
}
// First with newlines.
got := g.split("//go:generate " + test.in + "\n")
if !reflect.DeepEqual(got, test.out) {
t.Errorf("split(%q): got %q expected %q", test.in, got, test.out)
}
// Then with CRLFs, thank you Windows.
got = g.split("//go:generate " + test.in + "\r\n")
if !reflect.DeepEqual(got, test.out) {
t.Errorf("split(%q): got %q expected %q", test.in, got, test.out)
}
if got[0] == "-command" { // record commands
g.setShorthand(got)
}
}
}