github.com/googleapis/api-linter@v1.65.2/locations/file_locations_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 locations
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/google/go-cmp/cmp"
    21  	"github.com/jhump/protoreflect/desc"
    22  	"github.com/jhump/protoreflect/desc/builder"
    23  	dpb "google.golang.org/protobuf/types/descriptorpb"
    24  )
    25  
    26  func TestLocations(t *testing.T) {
    27  	f := parse(t, `
    28  		// proto3 rules!
    29  		syntax = "proto3";
    30  
    31  		import "google/api/resource.proto";
    32  
    33  		package google.api.linter;
    34  
    35  		option csharp_namespace = "Google.Api.Linter";
    36  		option java_package = "com.google.api.linter";
    37  		option php_namespace = "Google\\Api\\Linter";
    38  		option ruby_package = "Google::Api::Linter";
    39  		option cc_enable_arenas = false;
    40  
    41  		message Foo {
    42  			string bar = 1;
    43  		}
    44  	`)
    45  
    46  	// Test the file location functions.
    47  	t.Run("File", func(t *testing.T) {
    48  		tests := []struct {
    49  			testName string
    50  			fx       func(f *desc.FileDescriptor) *dpb.SourceCodeInfo_Location
    51  			idxFx    func(f *desc.FileDescriptor, i int) *dpb.SourceCodeInfo_Location
    52  			idx      int
    53  			wantSpan []int32
    54  		}{
    55  			{
    56  				testName: "Syntax",
    57  				fx:       FileSyntax,
    58  				wantSpan: []int32{1, 0, int32(len("syntax = \"proto3\";"))},
    59  			},
    60  			{
    61  				testName: "Package",
    62  				fx:       FilePackage,
    63  				wantSpan: []int32{5, 0, int32(len("package google.api.linter;"))},
    64  			},
    65  			{
    66  				testName: "CsharpNamespace",
    67  				fx:       FileCsharpNamespace,
    68  				wantSpan: []int32{7, 0, int32(len(`option csharp_namespace = "Google.Api.Linter";`))},
    69  			},
    70  			{
    71  				testName: "JavaPackage",
    72  				fx:       FileJavaPackage,
    73  				wantSpan: []int32{8, 0, int32(len(`option java_package = "com.google.api.linter";`))},
    74  			},
    75  			{
    76  				testName: "PhpNamespace",
    77  				fx:       FilePhpNamespace,
    78  				wantSpan: []int32{9, 0, int32(len(`option php_namespace = "Google\\Api\\Linter";`))},
    79  			},
    80  			{
    81  				testName: "RubyPackage",
    82  				fx:       FileRubyPackage,
    83  				wantSpan: []int32{10, 0, int32(len(`option ruby_package = "Google::Api::Linter";`))},
    84  			},
    85  			{
    86  				testName: "Import",
    87  				idxFx:    FileImport,
    88  				idx:      0,
    89  				wantSpan: []int32{3, 0, int32(len(`import "google/api/resource.proto";`))},
    90  			},
    91  			{
    92  				testName: "CCEnableArenas",
    93  				fx:       FileCCEnableArenas,
    94  				wantSpan: []int32{11, 0, int32(len(`option cc_enable_arenas = false;`))},
    95  			},
    96  		}
    97  		for _, test := range tests {
    98  			t.Run(test.testName, func(t *testing.T) {
    99  				var l *dpb.SourceCodeInfo_Location
   100  				if test.fx != nil {
   101  					l = test.fx(f)
   102  				} else {
   103  					l = test.idxFx(f, test.idx)
   104  				}
   105  				if diff := cmp.Diff(l.Span, test.wantSpan); diff != "" {
   106  					t.Errorf(diff)
   107  				}
   108  			})
   109  		}
   110  	})
   111  
   112  	// Test bogus locations.
   113  	t.Run("Bogus", func(t *testing.T) {
   114  		tests := []struct {
   115  			testName string
   116  			path     []int
   117  		}{
   118  			{"NotFound", []int{6, 0}},
   119  		}
   120  		for _, test := range tests {
   121  			t.Run(test.testName, func(t *testing.T) {
   122  				if loc := pathLocation(f, test.path...); loc != nil {
   123  					t.Errorf("%v", loc)
   124  				}
   125  			})
   126  		}
   127  	})
   128  }
   129  
   130  func TestMissingLocations(t *testing.T) {
   131  	m, err := builder.NewMessage("Foo").Build()
   132  	if err != nil {
   133  		t.Fatalf("%v", err)
   134  	}
   135  	f := m.GetFile()
   136  	tests := []struct {
   137  		testName string
   138  		fx       func(f *desc.FileDescriptor) *dpb.SourceCodeInfo_Location
   139  	}{
   140  		{"Syntax", FileSyntax},
   141  		{"Package", FilePackage},
   142  	}
   143  	for _, test := range tests {
   144  		t.Run(test.testName, func(t *testing.T) {
   145  			if diff := cmp.Diff(test.fx(f).Span, []int32{0, 0, 0}); diff != "" {
   146  				t.Errorf(diff)
   147  			}
   148  		})
   149  	}
   150  }