• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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