1 // Copyright 2014 Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package blueprint 16 17 import ( 18 "reflect" 19 "testing" 20 ) 21 22 var ninjaParseTestCases = []struct { 23 input string 24 vars []string 25 strs []string 26 err string 27 }{ 28 { 29 input: "abc def $ghi jkl", 30 vars: []string{"ghi"}, 31 strs: []string{"abc def ", " jkl"}, 32 }, 33 { 34 input: "abc def $ghi$jkl", 35 vars: []string{"ghi", "jkl"}, 36 strs: []string{"abc def ", "", ""}, 37 }, 38 { 39 input: "foo $012_-345xyz_! bar", 40 vars: []string{"012_-345xyz_"}, 41 strs: []string{"foo ", "! bar"}, 42 }, 43 { 44 input: "foo ${012_-345xyz_} bar", 45 vars: []string{"012_-345xyz_"}, 46 strs: []string{"foo ", " bar"}, 47 }, 48 { 49 input: "foo ${012_-345xyz_} bar", 50 vars: []string{"012_-345xyz_"}, 51 strs: []string{"foo ", " bar"}, 52 }, 53 { 54 input: "foo $$ bar", 55 vars: nil, 56 strs: []string{"foo $$ bar"}, 57 }, 58 { 59 input: "$foo${bar}", 60 vars: []string{"foo", "bar"}, 61 strs: []string{"", "", ""}, 62 }, 63 { 64 input: "$foo$$", 65 vars: []string{"foo"}, 66 strs: []string{"", "$$"}, 67 }, 68 { 69 input: "foo bar", 70 vars: nil, 71 strs: []string{"foo bar"}, 72 }, 73 { 74 input: "foo $ bar", 75 err: "invalid character after '$' at byte offset 5", 76 }, 77 { 78 input: "foo $", 79 err: "unexpected end of string after '$'", 80 }, 81 { 82 input: "foo ${} bar", 83 err: "empty variable name at byte offset 6", 84 }, 85 { 86 input: "foo ${abc!} bar", 87 err: "invalid character in variable name at byte offset 9", 88 }, 89 { 90 input: "foo ${abc", 91 err: "unexpected end of string in variable name", 92 }, 93 } 94 95 func TestParseNinjaString(t *testing.T) { 96 for _, testCase := range ninjaParseTestCases { 97 scope := newLocalScope(nil, "namespace") 98 expectedVars := []Variable{} 99 for _, varName := range testCase.vars { 100 v, err := scope.LookupVariable(varName) 101 if err != nil { 102 v, err = scope.AddLocalVariable(varName, "") 103 if err != nil { 104 t.Fatalf("error creating scope: %s", err) 105 } 106 } 107 expectedVars = append(expectedVars, v) 108 } 109 110 output, err := parseNinjaString(scope, testCase.input) 111 if err == nil { 112 if !reflect.DeepEqual(output.variables, expectedVars) { 113 t.Errorf("incorrect variable list:") 114 t.Errorf(" input: %q", testCase.input) 115 t.Errorf(" expected: %#v", expectedVars) 116 t.Errorf(" got: %#v", output.variables) 117 } 118 if !reflect.DeepEqual(output.strings, testCase.strs) { 119 t.Errorf("incorrect string list:") 120 t.Errorf(" input: %q", testCase.input) 121 t.Errorf(" expected: %#v", testCase.strs) 122 t.Errorf(" got: %#v", output.strings) 123 } 124 } 125 var errStr string 126 if err != nil { 127 errStr = err.Error() 128 } 129 if err != nil && err.Error() != testCase.err { 130 t.Errorf("unexpected error:") 131 t.Errorf(" input: %q", testCase.input) 132 t.Errorf(" expected: %q", testCase.err) 133 t.Errorf(" got: %q", errStr) 134 } 135 } 136 } 137 138 func TestParseNinjaStringWithImportedVar(t *testing.T) { 139 ImpVar := &staticVariable{name_: "ImpVar"} 140 impScope := newScope(nil) 141 impScope.AddVariable(ImpVar) 142 scope := newScope(nil) 143 scope.AddImport("impPkg", impScope) 144 145 input := "abc def ${impPkg.ImpVar} ghi" 146 output, err := parseNinjaString(scope, input) 147 if err != nil { 148 t.Fatalf("unexpected error: %s", err) 149 } 150 151 expect := []Variable{ImpVar} 152 if !reflect.DeepEqual(output.variables, expect) { 153 t.Errorf("incorrect output:") 154 t.Errorf(" input: %q", input) 155 t.Errorf(" expected: %#v", expect) 156 t.Errorf(" got: %#v", output) 157 } 158 } 159