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 "testing" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 "go.skia.org/skia/bazel/exporter/build_proto/analysis_v2" 14 "go.skia.org/skia/bazel/exporter/build_proto/build" 15 "google.golang.org/protobuf/encoding/prototext" 16) 17 18func TestMakeCanonicalRuleName_ValidInput_Success(t *testing.T) { 19 test := func(name, input, expected string) { 20 t.Run(name, func(t *testing.T) { 21 actual, err := makeCanonicalRuleName(input) 22 require.NoError(t, err) 23 assert.Equal(t, expected, actual) 24 }) 25 } 26 27 test("AlreadyCanonicalNoPath", "//:core", "//:core") 28 test("AlreadyCanonicalWithPath", "//foo/bar:wiz", "//foo/bar:wiz") 29 test("NoRepoDefaultTarget", "//tools/flags", "//tools/flags:flags") 30 test("RepoWithDefaultTarget", "@libpng", "@libpng//:libpng") 31} 32 33func TestMakeCanonicalRuleName_InvalidInput_ReturnError(t *testing.T) { 34 test := func(name, input string) { 35 t.Run(name, func(t *testing.T) { 36 _, err := makeCanonicalRuleName(input) 37 assert.Error(t, err) 38 }) 39 } 40 41 test("EmptyString", "") 42 test("InvalidRepoName", "@@repo") 43 test("InvalidTargetName", "//:::target_name") 44} 45 46func TestParseRule_ValidRules_Success(t *testing.T) { 47 48 test := func(name, rule, expectedRepo, expectedPath, expectedTarget string) { 49 t.Run(name, func(t *testing.T) { 50 repo, path, target, err := parseRule(rule) 51 require.NoError(t, err) 52 assert.Equal(t, expectedRepo, repo) 53 assert.Equal(t, expectedPath, path) 54 assert.Equal(t, expectedTarget, target) 55 }) 56 } 57 58 test("TargetAtRoot", "//:core", "", "/", "core") 59 test("PathWithTarget", "//foo/bar:wiz", "", "/foo/bar", "wiz") 60 test("PathWithFile", "@abseil_cpp//absl/algorithm:algorithm.h", "@abseil_cpp", "/absl/algorithm", "algorithm.h") 61 test("DirDefaultTarget", "//tools/flags", "", "/tools/flags", "flags") 62 test("RepoDefaultTarget", "@libpng", "@libpng", "/", "libpng") 63 test("TargetWithPath", "//src/sksl:generated/sksl_compute.dehydrated.sksl", "", "/src/sksl", "generated/sksl_compute.dehydrated.sksl") 64} 65 66func TestParseLocation_ValidInput_Success(t *testing.T) { 67 path, line, pos, err := parseLocation("/path/to/file.txt:12:875") 68 require.NoError(t, err) 69 assert.Equal(t, "/path/to/file.txt", path) 70 assert.Equal(t, 12, line) 71 assert.Equal(t, 875, pos) 72} 73 74func TestGetLocationDir_ValidInput_Success(t *testing.T) { 75 path, err := getLocationDir("/path/to/file.txt:12:875") 76 require.NoError(t, err) 77 assert.Equal(t, "/path/to", path) 78} 79 80func TestGetRuleSimpleName_ValidInput_Success(t *testing.T) { 81 test := func(name, rule, expectedName string) { 82 t.Run(name, func(t *testing.T) { 83 cmakeName, err := getRuleSimpleName(rule) 84 require.NoError(t, err) 85 assert.Equal(t, expectedName, cmakeName) 86 }) 87 } 88 89 test("PathWithTarget", "//include/private/chromium:private_hdrs", "include_private_chromium_private_hdrs") 90 test("PathWithHost", "@repo//path/to/dir:file.txt", "at_repo_path_to_dir_file.txt") 91 test("RootTarget", "//:core", "core") 92 test("HostTarget", "@repo//:deps", "at_repo_deps") 93 test("DirDefaultTarget", "//tools/flags", "tools_flags_flags") // Input rule shorthand for "//tools/flags:flags". 94 test("RepoDefaultTarget", "@libpng", "at_libpng_libpng") // Input rule shorthand for "@libpng//:libpng". 95} 96 97func TestGetRuleStringArrayAttribute_NoAttrib_ReturnsNilSlice(t *testing.T) { 98 var rule build.Rule 99 slice, err := getRuleStringArrayAttribute(&rule, "missing-attrib") 100 assert.NoError(t, err) 101 assert.Empty(t, slice) 102} 103 104func TestAppendUnique_NotPresent_Appended(t *testing.T) { 105 slice := appendUnique([]string{"one"}, "two") 106 assert.Equal(t, []string{"one", "two"}, slice) 107} 108 109func TestAppendUnique_Present_NotAppended(t *testing.T) { 110 slice := appendUnique([]string{"one", "two"}, "two") 111 assert.Equal(t, []string{"one", "two"}, slice) 112} 113 114func TestIsExternalRule_IsExternal_ExpectTrue(t *testing.T) { 115 assert.True(t, isExternalRule("@abseil_cpp//absl/algorithm:algorithm.h")) 116} 117 118func TestIsExternalRule_IsInternal_ExpectFalse(t *testing.T) { 119 assert.False(t, isExternalRule("//:core")) 120} 121 122func TestIsFileRule_InvalidRule_ReturnsFalse(t *testing.T) { 123 assert.False(t, isFileTarget("")) 124} 125 126func TestIsFileRule_ValidFileRule_ReturnsTrue(t *testing.T) { 127 assert.True(t, isFileTarget("//dir/path:hello.c")) 128} 129 130func TestIsFileRule_ValidNonFileRule_ReturnsFalse(t *testing.T) { 131 assert.False(t, isFileTarget("//dir/path:hello")) 132} 133 134func TestFindRule_RuleExists_Success(t *testing.T) { 135 qr := analysis_v2.CqueryResult{} 136 err := prototext.Unmarshal([]byte(textProto), &qr) 137 require.NoError(t, err) 138 139 r := findRule(&qr, "//src/apps:hello") 140 require.NotNil(t, r) 141 assert.Equal(t, "//src/apps:hello", r.GetName()) 142} 143 144func TestFindRule_RuleDoesntExists_ReturnsNil(t *testing.T) { 145 qr := analysis_v2.CqueryResult{} 146 err := prototext.Unmarshal([]byte(textProto), &qr) 147 require.NoError(t, err) 148 149 assert.Nil(t, findRule(&qr, "//path/to:nonexistent_rule")) 150} 151 152func TestFindRule_InvalidRule_ReturnsNil(t *testing.T) { 153 qr := analysis_v2.CqueryResult{} 154 err := prototext.Unmarshal([]byte(textProto), &qr) 155 require.NoError(t, err) 156 157 assert.Nil(t, findRule(&qr, "")) 158} 159 160func TestGetFilePathFromFileTarget_ValidPaths_ReturnsPath(t *testing.T) { 161 test := func(name, target, expected string) { 162 t.Run(name, func(t *testing.T) { 163 path, err := getFilePathFromFileTarget(target) 164 require.NoError(t, err) 165 assert.Equal(t, expected, path) 166 }) 167 } 168 169 test("FileInDir", "//src/core:source.cpp", "src/core/source.cpp") 170 test("RootFile", "//:source.cpp", "source.cpp") 171} 172 173func TestGetFilePathFromFileTarget_InvalidTarget_ReturnsError(t *testing.T) { 174 test := func(name, target string) { 175 t.Run(name, func(t *testing.T) { 176 _, err := getFilePathFromFileTarget(target) 177 require.Error(t, err) 178 }) 179 } 180 181 test("EmptyString", "") 182 test("InvalidTarget", "//") 183 test("NoFile", "//src/core:srcs") 184 test("DefaultTarget", "//src/core") 185} 186