adding test

pull/4464/head
Sharif Elgamal 2019-06-18 11:19:05 -07:00
parent 8da5f2b4a6
commit 8308aa5156
No known key found for this signature in database
GPG Key ID: 23CC0225BD9FD702
4 changed files with 120 additions and 13 deletions

View File

@ -38,8 +38,8 @@ import (
// A list of strings to explicitly omit from translation files.
var blacklist = []string{"%s: %v"}
// currentState is a struct that represent the current state of the extraction process
type currentState struct {
// state is a struct that represent the current state of the extraction process
type state struct {
// The list of functions to check for
funcs map[string]struct{}
@ -60,7 +60,7 @@ type currentState struct {
}
// newExtractor initializes state for extraction
func newExtractor(functionsToCheck []string) *currentState {
func newExtractor(functionsToCheck []string) *state {
funcs := make(map[string]struct{})
fs := stack.New()
@ -69,7 +69,7 @@ func newExtractor(functionsToCheck []string) *currentState {
fs.Push(f)
}
return &currentState{
return &state{
funcs: funcs,
fs: fs,
translations: make(map[string]interface{}),
@ -78,6 +78,16 @@ func newExtractor(functionsToCheck []string) *currentState {
// TranslatableStrings finds all strings to that need to be translated in paths and prints them out to all json files in output
func TranslatableStrings(paths []string, functions []string, output string) {
cwd, err := os.Getwd()
if err != nil {
exit.WithError("Getting current working directory", err)
}
if strings.Contains(cwd, "cmd") {
fmt.Println("Run extract.go from the minikube root directory.")
os.Exit(1)
}
e := newExtractor(functions)
fmt.Println("Compiling translation strings...")
@ -100,7 +110,7 @@ func TranslatableStrings(paths []string, functions []string, output string) {
}
}
err := writeStringsToFiles(e, output)
err = writeStringsToFiles(e, output)
if err != nil {
exit.WithError("Writing translation files", err)
@ -114,7 +124,7 @@ func shouldCheckFile(path string) bool {
}
// inspectFile goes through the given file line by line looking for translatable strings
func inspectFile(e *currentState) error {
func inspectFile(e *state) error {
fset := token.NewFileSet()
r, err := ioutil.ReadFile(e.filename)
if err != nil {
@ -163,7 +173,7 @@ func inspectFile(e *currentState) error {
}
// checkStmt checks each line to see if it's a call to print a string out to the console
func checkStmt(stmt ast.Stmt, e *currentState) {
func checkStmt(stmt ast.Stmt, e *state) {
//fmt.Printf("%s: %s\n", stmt, reflect.TypeOf(stmt))
// If this line is an expression, see if it's a function call
@ -185,7 +195,7 @@ func checkStmt(stmt ast.Stmt, e *currentState) {
}
// checkIfStmt does if-statement-specific checks, especially relating to else stmts
func checkIfStmt(stmt *ast.IfStmt, e *currentState) {
func checkIfStmt(stmt *ast.IfStmt, e *state) {
for _, s := range stmt.Body.List {
checkStmt(s, e)
}
@ -206,7 +216,7 @@ func checkIfStmt(stmt *ast.IfStmt, e *currentState) {
}
// checkCallExpression takes a function call, and checks its arguments for strings
func checkCallExpression(expr *ast.ExprStmt, e *currentState) {
func checkCallExpression(expr *ast.ExprStmt, e *state) {
s, ok := expr.X.(*ast.CallExpr)
// This line isn't a function call
@ -253,7 +263,7 @@ func checkCallExpression(expr *ast.ExprStmt, e *currentState) {
}
// checkIdentForStringValye takes a identifier and sees if it's a variable assigned to a string
func checkIdentForStringValue(i *ast.Ident, e *currentState) bool {
func checkIdentForStringValue(i *ast.Ident, e *state) bool {
// This identifier is nil
if i.Obj == nil {
return false
@ -281,7 +291,7 @@ func checkIdentForStringValue(i *ast.Ident, e *currentState) bool {
}
// addStringToList takes a string, makes sure it's meant to be translated then adds it to the list if so
func addStringToList(s string, e *currentState) bool {
func addStringToList(s string, e *state) bool {
// Empty strings don't need translating
if len(s) <= 2 {
return false
@ -319,7 +329,7 @@ func addStringToList(s string, e *currentState) bool {
}
// writeStringsToFiles writes translations to all translation files in output
func writeStringsToFiles(e *currentState, output string) error {
func writeStringsToFiles(e *state, output string) error {
err := filepath.Walk(output, func(path string, info os.FileInfo, err error) error {
if err != nil {
return errors.Wrap(err, "accessing path")
@ -327,6 +337,9 @@ func writeStringsToFiles(e *currentState, output string) error {
if info.Mode().IsDir() {
return nil
}
if !strings.HasSuffix(path, ".json") {
return nil
}
fmt.Printf("Writing to %s\n", filepath.Base(path))
var currentTranslations map[string]interface{}
f, err := ioutil.ReadFile(path)
@ -361,7 +374,7 @@ func writeStringsToFiles(e *currentState, output string) error {
}
// addParentFuncToList adds the current parent function to the list of functions to inspect more closely.
func addParentFuncToList(e *currentState) {
func addParentFuncToList(e *state) {
if _, ok := e.funcs[e.parentFunc]; !ok {
e.funcs[e.parentFunc] = struct{}{}
e.fs.Push(e.parentFunc)

View File

@ -0,0 +1,42 @@
package extract
import (
"encoding/json"
"io/ioutil"
"reflect"
"testing"
)
func TestExtract(t *testing.T) {
// The file to scan
paths := []string{"testdata/sample_file.go"}
// The function we care about
functions := []string{"PrintToScreen"}
// The directory where the sample translation file is in
output := "testdata/"
expected := map[string]interface{}{
"Hint: This is not a URL, come on.": "",
"Holy cow I'm in a loop!": "Something else",
"This is a variable with a string assigned": "",
"This was a choice: %s": "Something",
"Wow another string: %s": "",
}
TranslatableStrings(paths, functions, output)
var got map[string]interface{}
f, err := ioutil.ReadFile("testdata/en-US.json")
if err != nil {
t.Fatalf("Reading json file: %s", err)
}
json.Unmarshal(f, &got)
if !reflect.DeepEqual(expected, got) {
t.Fatalf("Translation JSON not equal: expected %v, got %v", expected, got)
}
}

View File

@ -0,0 +1,4 @@
{
"Holy cow I'm in a loop!": "Something else",
"This was a choice: %s": "Something"
}

View File

@ -0,0 +1,48 @@
package extract
import "fmt"
func DoSomeStuff() {
// Test with a URL
PrintToScreenNoInterface("http://kubernetes.io")
// Test with something that Go thinks looks like a URL
PrintToScreenNoInterface("Hint: This is not a URL, come on.")
// Try with an integer
PrintToScreenNoInterface("5")
// Try with a sudo command
path := "."
PrintToScreen("sudo ls %s", path)
DoSomeOtherStuff(true, 4, "I think this should work")
v := "This is a variable with a string assigned"
PrintToScreenNoInterface(v)
}
func DoSomeOtherStuff(choice bool, i int, s string) {
// Let's try an if statement
if choice {
PrintToScreen("This was a choice: %s", s)
} else if i > 5 {
PrintToScreen("Wow another string: %s", i)
} else {
for i > 10 {
PrintToScreenNoInterface("Holy cow I'm in a loop!")
i = i + 1
}
}
}
func PrintToScreenNoInterface(s string) {
PrintToScreen(s, nil)
}
// This will be the function we'll focus the extractor on
func PrintToScreen(s string, i interface{}) {
fmt.Printf(s, i)
}