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/mock" 14 "github.com/stretchr/testify/require" 15 "go.skia.org/infra/go/skerr" 16 "go.skia.org/skia/bazel/exporter/interfaces/mocks" 17) 18 19const workspaceTestWorkspaceDir = "/path/to/workspace" 20 21// This input test data (in textproto format) started as output of 22// a bazel cquery call - like: 23// 24// bazel cquery --noimplicit_deps 'kind("rule", deps(//:core))' --output textproto > out.txt 25// 26// and then hand edited to create a small valid query result with specific 27// files, copts, and other cc_library/cc_binary rule attributes. 28const workspaceTestTextProto = `results { 29 target { 30 type: RULE 31 rule { 32 name: "//src/libs:sum" 33 rule_class: "cc_library" 34 location: "/path/to/workspace/src/libs/BUILD.bazel:8:11" 35 attribute { 36 name: "copts" 37 type: STRING_LIST 38 string_list_value: "-O2" 39 explicitly_specified: true 40 nodep: false 41 } 42 attribute { 43 name: "defines" 44 type: STRING_LIST 45 string_list_value: "SUMDEF" 46 explicitly_specified: false 47 nodep: false 48 } 49 attribute { 50 name: "includes" 51 type: STRING_LIST 52 string_list_value: "." 53 explicitly_specified: false 54 nodep: false 55 } 56 attribute { 57 name: "linkopts" 58 type: STRING_LIST 59 string_list_value: "-L/library/dir" 60 explicitly_specified: false 61 nodep: false 62 } 63 attribute { 64 name: "name" 65 type: STRING 66 string_value: "sum" 67 explicitly_specified: true 68 nodep: false 69 } 70 attribute { 71 name: "srcs" 72 type: LABEL_LIST 73 string_list_value: "//src/libs:sum.cpp" 74 explicitly_specified: true 75 nodep: false 76 } 77 attribute { 78 name: "hdrs" 79 type: LABEL_LIST 80 string_list_value: "//src/libs:sum.h" 81 explicitly_specified: true 82 nodep: false 83 } 84 attribute { 85 name: "visibility" 86 type: STRING_LIST 87 string_list_value: "//visibility:public" 88 explicitly_specified: true 89 nodep: true 90 } 91 } 92 }, 93 } 94 results { 95 target { 96 type: RULE 97 rule { 98 name: "//src/apps:hello" 99 rule_class: "cc_binary" 100 location: "/path/to/workspace/src/apps/BUILD.bazel:8:11" 101 attribute { 102 name: "copts" 103 type: STRING_LIST 104 string_list_value: "-O1" 105 explicitly_specified: true 106 nodep: false 107 } 108 attribute { 109 name: "defines" 110 type: STRING_LIST 111 string_list_value: "APPDEF" 112 explicitly_specified: false 113 nodep: false 114 } 115 attribute { 116 name: "linkopts" 117 type: STRING_LIST 118 string_list_value: "-L/app/dir" 119 explicitly_specified: false 120 nodep: false 121 } 122 attribute { 123 name: "name" 124 type: STRING 125 string_value: "hello" 126 explicitly_specified: true 127 nodep: false 128 } 129 attribute { 130 name: "srcs" 131 type: LABEL_LIST 132 string_list_value: "//src/apps:hello-world.cpp" 133 explicitly_specified: true 134 nodep: false 135 } 136 attribute { 137 name: "deps" 138 type: LABEL_LIST 139 string_list_value: "//src/libs:sum" 140 explicitly_specified: false 141 nodep: false 142 } 143 attribute { 144 name: "visibility" 145 type: STRING_LIST 146 string_list_value: "//visibility:public" 147 explicitly_specified: true 148 nodep: true 149 } 150 } 151 } 152 }` 153 154// Return the workspace (cmakeWorkspace) for the test data. 155// 156// Note: this helper function makes no test assertions as the 157// Export function is already tested. 158func getTestWorkspace(t *testing.T) (cmakeWorkspace, error) { 159 protoData, err := textProtoToProtobuf(workspaceTestTextProto) 160 if err != nil { 161 return cmakeWorkspace{}, skerr.Wrap(err) 162 } 163 164 // Export to CMake buffer. 165 fs := mocks.NewFileSystem(t) 166 fs.On("OpenFile", mock.Anything).Return(new(bytes.Buffer), nil).Once() 167 e := NewCMakeExporter("projName", workspaceTestWorkspaceDir, "CMakeLists.txt", fs) 168 qcmd := mocks.NewQueryCommand(t) 169 qcmd.On("Read", mock.Anything).Return(protoData, nil) 170 err = e.Export(qcmd) 171 if err != nil { 172 return cmakeWorkspace{}, skerr.Wrap(err) 173 } 174 175 return e.workspace, nil 176} 177 178func TestIsGetRule_ValidName_ReturnsRule(t *testing.T) { 179 workspace, err := getTestWorkspace(t) 180 require.NoError(t, err) 181 182 r := workspace.getRule("//src/libs:sum") 183 require.NotNil(t, r) 184 assert.Equal(t, "//src/libs:sum", r.getName()) 185} 186 187func TestIsGetRule_InvalidName_ReturnsNil(t *testing.T) { 188 workspace, err := getTestWorkspace(t) 189 require.NoError(t, err) 190 191 r := workspace.getRule("//non/existent:rule") 192 assert.Nil(t, r) 193} 194 195func TestCreateRule_ValidBazelRule_NotNil(t *testing.T) { 196 workspace, err := getTestWorkspace(t) 197 require.NoError(t, err) 198 199 // Get the rule from the existing workspace (since we can't make one) 200 cmakeRule := workspace.getRule("//src/libs:sum") 201 require.NotNil(t, cmakeRule) 202 203 otherWorkspace := newCMakeWorkspace() 204 require.NotNil(t, otherWorkspace) 205 otherCMakeRule := otherWorkspace.createRule(cmakeRule.rule) 206 require.NotNil(t, otherCMakeRule) 207} 208 209func TestIsRuleWritten_NotWritten_ReturnsFalse(t *testing.T) { 210 var state writeState 211 assert.False(t, state.isRuleWritten("//unwritten:rule")) 212} 213 214func TestIsRuleWritten_Written_ReturnsTrue(t *testing.T) { 215 var state writeState 216 state.setRuleWritten("//written:rule") 217 assert.True(t, state.isRuleWritten("//written:rule")) 218} 219