// Copyright 2022 Google LLC // // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package exporter import ( "bytes" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.skia.org/infra/go/skerr" "go.skia.org/skia/bazel/exporter/interfaces/mocks" ) const workspaceTestWorkspaceDir = "/path/to/workspace" // This input test data (in textproto format) started as output of // a bazel cquery call - like: // // bazel cquery --noimplicit_deps 'kind("rule", deps(//:skia_public))' --output textproto > out.txt // // and then hand edited to create a small valid query result with specific // files, copts, and other cc_library/cc_binary rule attributes. const workspaceTestTextProto = `results { target { type: RULE rule { name: "//src/libs:sum" rule_class: "cc_library" location: "/path/to/workspace/src/libs/BUILD.bazel:8:11" attribute { name: "copts" type: STRING_LIST string_list_value: "-O2" explicitly_specified: true nodep: false } attribute { name: "defines" type: STRING_LIST string_list_value: "SUMDEF" explicitly_specified: false nodep: false } attribute { name: "includes" type: STRING_LIST string_list_value: "." explicitly_specified: false nodep: false } attribute { name: "linkopts" type: STRING_LIST string_list_value: "-L/library/dir" explicitly_specified: false nodep: false } attribute { name: "name" type: STRING string_value: "sum" explicitly_specified: true nodep: false } attribute { name: "srcs" type: LABEL_LIST string_list_value: "//src/libs:sum.cpp" explicitly_specified: true nodep: false } attribute { name: "hdrs" type: LABEL_LIST string_list_value: "//src/libs:sum.h" explicitly_specified: true nodep: false } attribute { name: "visibility" type: STRING_LIST string_list_value: "//visibility:public" explicitly_specified: true nodep: true } } }, } results { target { type: RULE rule { name: "//src/apps:hello" rule_class: "cc_binary" location: "/path/to/workspace/src/apps/BUILD.bazel:8:11" attribute { name: "copts" type: STRING_LIST string_list_value: "-O1" explicitly_specified: true nodep: false } attribute { name: "defines" type: STRING_LIST string_list_value: "APPDEF" explicitly_specified: false nodep: false } attribute { name: "linkopts" type: STRING_LIST string_list_value: "-L/app/dir" explicitly_specified: false nodep: false } attribute { name: "name" type: STRING string_value: "hello" explicitly_specified: true nodep: false } attribute { name: "srcs" type: LABEL_LIST string_list_value: "//src/apps:hello-world.cpp" explicitly_specified: true nodep: false } attribute { name: "deps" type: LABEL_LIST string_list_value: "//src/libs:sum" explicitly_specified: false nodep: false } attribute { name: "visibility" type: STRING_LIST string_list_value: "//visibility:public" explicitly_specified: true nodep: true } } } }` // Return the workspace (cmakeWorkspace) for the test data. // // Note: this helper function makes no test assertions as the // Export function is already tested. func getTestWorkspace(t *testing.T) (cmakeWorkspace, error) { protoData, err := textProtoToProtobuf(workspaceTestTextProto) if err != nil { return cmakeWorkspace{}, skerr.Wrap(err) } // Export to CMake buffer. fs := mocks.NewFileSystem(t) fs.On("OpenFile", mock.Anything).Return(new(bytes.Buffer), nil).Once() e := NewCMakeExporter("projName", workspaceTestWorkspaceDir, "CMakeLists.txt", fs) qcmd := mocks.NewQueryCommand(t) qcmd.On("Read", mock.Anything).Return(protoData, nil) err = e.Export(qcmd) if err != nil { return cmakeWorkspace{}, skerr.Wrap(err) } return e.workspace, nil } func TestIsGetRule_ValidName_ReturnsRule(t *testing.T) { workspace, err := getTestWorkspace(t) require.NoError(t, err) r := workspace.getRule("//src/libs:sum") require.NotNil(t, r) assert.Equal(t, "//src/libs:sum", r.getName()) } func TestIsGetRule_InvalidName_ReturnsNil(t *testing.T) { workspace, err := getTestWorkspace(t) require.NoError(t, err) r := workspace.getRule("//non/existent:rule") assert.Nil(t, r) } func TestCreateRule_ValidBazelRule_NotNil(t *testing.T) { workspace, err := getTestWorkspace(t) require.NoError(t, err) // Get the rule from the existing workspace (since we can't make one) cmakeRule := workspace.getRule("//src/libs:sum") require.NotNil(t, cmakeRule) otherWorkspace := newCMakeWorkspace() require.NotNil(t, otherWorkspace) otherCMakeRule := otherWorkspace.createRule(cmakeRule.rule) require.NotNil(t, otherCMakeRule) } func TestIsRuleWritten_NotWritten_ReturnsFalse(t *testing.T) { var state writeState assert.False(t, state.isRuleWritten("//unwritten:rule")) } func TestIsRuleWritten_Written_ReturnsTrue(t *testing.T) { var state writeState state.setRuleWritten("//written:rule") assert.True(t, state.isRuleWritten("//written:rule")) }