github.com/googleapis/api-linter@v1.65.2/rules/internal/testutils/parse_test.go (about) 1 // Copyright 2019 Google LLC 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 // https://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 testutils 16 17 import ( 18 "sync" 19 "testing" 20 21 "github.com/jhump/protoreflect/desc" 22 ) 23 24 func TestParseProtoStrings(t *testing.T) { 25 fd := ParseProtoStrings(t, map[string]string{"test.proto": ` 26 syntax = "proto3"; 27 28 import "google/protobuf/timestamp.proto"; 29 30 message Foo { 31 int32 bar = 1; 32 int64 baz = 2; 33 } 34 35 message Spam { 36 string eggs = 2; 37 google.protobuf.Timestamp create_time = 3; 38 } 39 `})["test.proto"] 40 if !fd.IsProto3() { 41 t.Errorf("Expected a proto3 file descriptor.") 42 } 43 tests := []struct { 44 name string 45 descriptor desc.Descriptor 46 }{ 47 {"Foo", fd.GetMessageTypes()[0]}, 48 {"bar", fd.GetMessageTypes()[0].GetFields()[0]}, 49 {"baz", fd.GetMessageTypes()[0].GetFields()[1]}, 50 {"Spam", fd.GetMessageTypes()[1]}, 51 {"eggs", fd.GetMessageTypes()[1].GetFields()[0]}, 52 {"create_time", fd.GetMessageTypes()[1].GetFields()[1]}, 53 } 54 for _, test := range tests { 55 t.Run(test.name, func(t *testing.T) { 56 if got, want := test.descriptor.GetName(), test.name; got != want { 57 t.Errorf("Got %q, expected %q.", got, want) 58 } 59 }) 60 } 61 } 62 63 func TestParseProtoStringError(t *testing.T) { 64 canary := &testing.T{} 65 66 // t.Fatalf will exit the goroutine, so to test this, 67 // we run the test in a different goroutine. 68 wg := &sync.WaitGroup{} 69 wg.Add(1) 70 go func() { 71 defer wg.Done() 72 ParseProtoStrings(canary, map[string]string{"test.proto": ` 73 syntax = "proto3"; 74 message Foo {} 75 The quick brown fox jumped over the lazy dogs. 76 `}) 77 }() 78 wg.Wait() 79 80 // Verify that the testing.T object was given a failure. 81 if !canary.Failed() { 82 t.Errorf("Expected syntax error to cause a fatal error.") 83 } 84 } 85 86 func TestParseProto3String(t *testing.T) { 87 fd := ParseProto3String(t, ` 88 message Foo { 89 int32 bar = 1; 90 int64 baz = 2; 91 } 92 93 message Spam { 94 string eggs = 2; 95 } 96 `) 97 if !fd.IsProto3() { 98 t.Errorf("Expected a proto3 file descriptor.") 99 } 100 } 101 102 func TestParseProto3Tmpl(t *testing.T) { 103 tests := []struct { 104 MessageName string 105 Field1Name string 106 Field2Name string 107 }{ 108 {"Book", "title", "author"}, 109 {"Foo", "bar", "baz"}, 110 } 111 for _, test := range tests { 112 t.Run(test.MessageName, func(t *testing.T) { 113 fd := ParseProto3Tmpl(t, ` 114 message {{.MessageName}} { 115 string {{.Field1Name}} = 1; 116 string {{.Field2Name}} = 2; 117 } 118 `, test) 119 if !fd.IsProto3() { 120 t.Errorf("Expected a proto3 file descriptor.") 121 } 122 msg := fd.GetMessageTypes()[0] 123 if got, want := msg.GetName(), test.MessageName; got != want { 124 t.Errorf("Got %q for message name, expected %q.", got, want) 125 } 126 for i, fn := range []string{test.Field1Name, test.Field2Name} { 127 if got, want := msg.GetFields()[i].GetName(), fn; got != want { 128 t.Errorf("Got %q for field name %d; expected %q.", got, i+1, want) 129 } 130 } 131 }) 132 } 133 } 134 135 func TestParseProto3TmplSyntaxError(t *testing.T) { 136 canary := &testing.T{} 137 138 // t.Fatalf will exit the goroutine, so to test this, 139 // we run the test in a different goroutine. 140 wg := &sync.WaitGroup{} 141 wg.Add(1) 142 go func() { 143 defer wg.Done() 144 ParseProto3Tmpl(canary, ` 145 message {{.InvalidTmplVariable[0]}} {} 146 `, struct{}{}) 147 }() 148 wg.Wait() 149 150 // Verify that the testing.T object was given a failure. 151 if !canary.Failed() { 152 t.Errorf("Expected syntax error to cause a fatal error.") 153 } 154 } 155 156 func TestParseProto3TmplDataError(t *testing.T) { 157 canary := &testing.T{} 158 159 // t.Fatalf will exit the goroutine, so to test this, 160 // we run the test in a different goroutine. 161 wg := &sync.WaitGroup{} 162 wg.Add(1) 163 go func() { 164 defer wg.Done() 165 ParseProto3Tmpl(canary, ` 166 message {{.MissingVariable}} {} 167 `, struct{}{}) 168 }() 169 wg.Wait() 170 171 // Verify that the testing.T object was given a failure. 172 if !canary.Failed() { 173 t.Errorf("Expected missing data to cause a fatal error.") 174 } 175 }