1// Copyright 2018 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 15package parser 16 17import ( 18 "bytes" 19 "testing" 20) 21 22var parserTestCases = []struct { 23 name string 24 in string 25 out []Node 26}{ 27 { 28 name: "Escaped $", 29 in: `a$$ b: c`, 30 out: []Node{ 31 &Rule{ 32 Target: SimpleMakeString("a$ b", NoPos), 33 Prerequisites: SimpleMakeString("c", NoPos), 34 }, 35 }, 36 }, 37 { 38 name: "Simple warning", 39 in: `$(warning A warning)`, 40 out: []Node{ 41 &Variable{ 42 Name: SimpleMakeString("warning A warning", NoPos), 43 }, 44 }, 45 }, 46 { 47 name: "Warning with #", 48 in: `$(warning # A warning)`, 49 out: []Node{ 50 &Variable{ 51 Name: SimpleMakeString("warning # A warning", NoPos), 52 }, 53 }, 54 }, 55 { 56 name: "Findstring with #", 57 in: `$(findstring x,x a #)`, 58 out: []Node{ 59 &Variable{ 60 Name: SimpleMakeString("findstring x,x a #", NoPos), 61 }, 62 }, 63 }, 64 { 65 name: "If statement", 66 in: `ifeq (a,b) # comment 67endif`, 68 out: []Node{ 69 &Directive{ 70 NamePos: NoPos, 71 Name: "ifeq", 72 Args: SimpleMakeString("(a,b) ", NoPos), 73 EndPos: NoPos, 74 }, 75 &Comment{ 76 CommentPos: NoPos, 77 Comment: " comment", 78 }, 79 &Directive{ 80 NamePos: NoPos, 81 Name: "endif", 82 Args: SimpleMakeString("", NoPos), 83 EndPos: NoPos, 84 }, 85 }, 86 }, 87 { 88 name: "Blank line in rule's command", 89 in: `all: 90 echo first line 91 92 echo second line`, 93 out: []Node{ 94 &Rule{ 95 Target: SimpleMakeString("all", NoPos), 96 RecipePos: NoPos, 97 Recipe: "echo first line\necho second line", 98 Prerequisites: SimpleMakeString("", NoPos), 99 }, 100 }, 101 }, 102} 103 104func TestParse(t *testing.T) { 105 for _, test := range parserTestCases { 106 t.Run(test.name, func(t *testing.T) { 107 p := NewParser(test.name, bytes.NewBufferString(test.in)) 108 got, errs := p.Parse() 109 110 if len(errs) != 0 { 111 t.Fatalf("Unexpected errors while parsing: %v", errs) 112 } 113 114 if len(got) != len(test.out) { 115 t.Fatalf("length mismatch, expected %d nodes, got %d", len(test.out), len(got)) 116 } 117 118 for i := range got { 119 if got[i].Dump() != test.out[i].Dump() { 120 t.Errorf("incorrect node %d:\nexpected: %#v (%s)\n got: %#v (%s)", 121 i, test.out[i], test.out[i].Dump(), got[i], got[i].Dump()) 122 } 123 } 124 }) 125 } 126} 127 128func TestRuleEnd(t *testing.T) { 129 name := "ruleEndTest" 130 in := `all: 131ifeq (A, A) 132 echo foo 133 echo foo 134 echo foo 135 echo foo 136endif 137 echo bar 138` 139 p := NewParser(name, bytes.NewBufferString(in)) 140 got, errs := p.Parse() 141 if len(errs) != 0 { 142 t.Fatalf("Unexpected errors while parsing: %v", errs) 143 } 144 145 if got[0].End() < got[len(got)-1].Pos() { 146 t.Errorf("Rule's end (%d) is smaller than directive that inside of rule's start (%v)\n", got[0].End(), got[len(got)-1].Pos()) 147 } 148} 149