1// Copyright 2022 Google LLC 2// 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5 6package exporter 7 8import ( 9 "bytes" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 "go.skia.org/skia/bazel/exporter/build_proto/analysis_v2" 15 "google.golang.org/protobuf/encoding/prototext" 16) 17 18// This input test data (in textproto format) started as output of 19// a bazel cquery call - like: 20// 21// bazel cquery --noimplicit_deps 'kind("rule", deps(//:core))' --output textproto > out.txt 22// 23// and then hand edited to create a small valid query result with specific 24// files, copts, and other cc_library/cc_binary rule attributes. 25const ruleTestTextProto = `results { 26 target { 27 type: RULE 28 rule { 29 name: "//src/libs:sum" 30 rule_class: "cc_library" 31 location: "/path/to/workspace/src/libs/BUILD.bazel:8:11" 32 attribute { 33 name: "copts" 34 type: STRING_LIST 35 string_list_value: "-O2" 36 explicitly_specified: true 37 nodep: false 38 } 39 attribute { 40 name: "defines" 41 type: STRING_LIST 42 string_list_value: "SUMDEF" 43 explicitly_specified: false 44 nodep: false 45 } 46 attribute { 47 name: "includes" 48 type: STRING_LIST 49 string_list_value: "." 50 explicitly_specified: false 51 nodep: false 52 } 53 attribute { 54 name: "linkopts" 55 type: STRING_LIST 56 string_list_value: "-L/library/dir" 57 explicitly_specified: false 58 nodep: false 59 } 60 attribute { 61 name: "name" 62 type: STRING 63 string_value: "sum" 64 explicitly_specified: true 65 nodep: false 66 } 67 attribute { 68 name: "srcs" 69 type: LABEL_LIST 70 string_list_value: "//src/libs:sum.cpp" 71 explicitly_specified: true 72 nodep: false 73 } 74 attribute { 75 name: "hdrs" 76 type: LABEL_LIST 77 string_list_value: "//src/libs:sum.h" 78 explicitly_specified: true 79 nodep: false 80 } 81 attribute { 82 name: "visibility" 83 type: STRING_LIST 84 string_list_value: "//visibility:public" 85 explicitly_specified: true 86 nodep: true 87 } 88 } 89 }, 90 } 91 results { 92 target { 93 type: RULE 94 rule { 95 name: "//src/apps:hello" 96 rule_class: "cc_binary" 97 location: "/path/to/workspace/src/apps/BUILD.bazel:8:11" 98 attribute { 99 name: "copts" 100 type: STRING_LIST 101 string_list_value: "-O1" 102 explicitly_specified: true 103 nodep: false 104 } 105 attribute { 106 name: "defines" 107 type: STRING_LIST 108 string_list_value: "APPDEF" 109 explicitly_specified: false 110 nodep: false 111 } 112 attribute { 113 name: "linkopts" 114 type: STRING_LIST 115 string_list_value: "-L/app/dir" 116 explicitly_specified: false 117 nodep: false 118 } 119 attribute { 120 name: "name" 121 type: STRING 122 string_value: "hello" 123 explicitly_specified: true 124 nodep: false 125 } 126 attribute { 127 name: "srcs" 128 type: LABEL_LIST 129 explicitly_specified: true 130 nodep: false 131 } 132 attribute { 133 name: "deps" 134 type: LABEL_LIST 135 string_list_value: "//src/libs:sum" 136 explicitly_specified: false 137 nodep: false 138 } 139 attribute { 140 name: "visibility" 141 type: STRING_LIST 142 string_list_value: "//visibility:public" 143 explicitly_specified: true 144 nodep: true 145 } 146 } 147 } 148 }` 149 150func TestGetName_MatchingValue(t *testing.T) { 151 qr := analysis_v2.CqueryResult{} 152 err := prototext.Unmarshal([]byte(ruleTestTextProto), &qr) 153 require.NoError(t, err) 154 155 r := findRule(&qr, "//src/apps:hello") 156 require.NotNil(t, r) 157 assert.Equal(t, "//src/apps:hello", r.GetName()) 158 159 cr := newCMakeRule(r) 160 assert.Equal(t, r.GetName(), cr.getName()) 161} 162 163func TestHasSrcs_SourcesExist_ReturnsTrue(t *testing.T) { 164 qr := analysis_v2.CqueryResult{} 165 err := prototext.Unmarshal([]byte(ruleTestTextProto), &qr) 166 require.NoError(t, err) 167 168 r := findRule(&qr, "//src/libs:sum") 169 require.NotNil(t, r) 170 assert.Equal(t, "//src/libs:sum", r.GetName()) 171 172 cr := newCMakeRule(r) 173 assert.True(t, cr.hasSrcs()) 174} 175 176func TestHasSrcs_NoSources_ReturnsFalse(t *testing.T) { 177 qr := analysis_v2.CqueryResult{} 178 err := prototext.Unmarshal([]byte(ruleTestTextProto), &qr) 179 require.NoError(t, err) 180 181 r := findRule(&qr, "//src/apps:hello") 182 require.NotNil(t, r) 183 assert.Equal(t, "//src/apps:hello", r.GetName()) 184 185 cr := newCMakeRule(r) 186 assert.False(t, cr.hasSrcs()) 187} 188 189func TestHasDependency_DependencyExist_ReturnsTrue(t *testing.T) { 190 qr := analysis_v2.CqueryResult{} 191 err := prototext.Unmarshal([]byte(ruleTestTextProto), &qr) 192 require.NoError(t, err) 193 194 r := findRule(&qr, "//src/apps:hello") 195 require.NotNil(t, r) 196 assert.Equal(t, "//src/apps:hello", r.GetName()) 197 198 cr := newCMakeRule(r) 199 require.NoError(t, cr.addDependency("//dependency/name")) 200 assert.True(t, cr.hasDependency("//dependency/name")) 201} 202 203func TestHasDependency_NoDependency_ReturnsFalse(t *testing.T) { 204 qr := analysis_v2.CqueryResult{} 205 err := prototext.Unmarshal([]byte(ruleTestTextProto), &qr) 206 require.NoError(t, err) 207 208 r := findRule(&qr, "//src/apps:hello") 209 require.NotNil(t, r) 210 assert.Equal(t, "//src/apps:hello", r.GetName()) 211 212 cr := newCMakeRule(r) 213 assert.False(t, cr.hasDependency("//dependency/name")) 214} 215 216func TestSetContents_SetContents_WriteSucceeds(t *testing.T) { 217 cr := newCMakeRule(nil) 218 cr.setContents([]byte("Contents Value\n")) 219 var writeBuff bytes.Buffer 220 nb, err := cr.write(&writeBuff) 221 require.NoError(t, err) 222 assert.Equal(t, 15, nb) 223 assert.Equal(t, []byte("Contents Value\n"), writeBuff.Bytes()) 224} 225