1// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package bp2build
16
17import (
18	"android/soong/android"
19	"android/soong/sh"
20	"strings"
21	"testing"
22)
23
24func TestShBinaryLoadStatement(t *testing.T) {
25	testCases := []struct {
26		bazelTargets           BazelTargets
27		expectedLoadStatements string
28	}{
29		{
30			bazelTargets: BazelTargets{
31				BazelTarget{
32					name:      "sh_binary_target",
33					ruleClass: "sh_binary",
34					// Note: no bzlLoadLocation for native rules
35					// TODO(ruperts): Could open source the existing, experimental Starlark sh_ rules?
36				},
37			},
38			expectedLoadStatements: ``,
39		},
40	}
41
42	for _, testCase := range testCases {
43		actual := testCase.bazelTargets.LoadStatements()
44		expected := testCase.expectedLoadStatements
45		if actual != expected {
46			t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
47		}
48	}
49
50}
51
52func TestShBinaryBp2Build(t *testing.T) {
53	testCases := []struct {
54		description                        string
55		moduleTypeUnderTest                string
56		moduleTypeUnderTestFactory         android.ModuleFactory
57		moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
58		preArchMutators                    []android.RegisterMutatorFunc
59		depsMutators                       []android.RegisterMutatorFunc
60		bp                                 string
61		expectedBazelTargets               []string
62		filesystem                         map[string]string
63		dir                                string
64	}{
65		{
66			description:                        "sh_binary test",
67			moduleTypeUnderTest:                "sh_binary",
68			moduleTypeUnderTestFactory:         sh.ShBinaryFactory,
69			moduleTypeUnderTestBp2BuildMutator: sh.ShBinaryBp2Build,
70			bp: `sh_binary {
71    name: "foo",
72    src: "foo.sh",
73    bazel_module: { bp2build_available: true },
74}`,
75			expectedBazelTargets: []string{`sh_binary(
76    name = "foo",
77    srcs = ["foo.sh"],
78)`},
79		},
80	}
81
82	dir := "."
83	for _, testCase := range testCases {
84		filesystem := make(map[string][]byte)
85		toParse := []string{
86			"Android.bp",
87		}
88		for f, content := range testCase.filesystem {
89			if strings.HasSuffix(f, "Android.bp") {
90				toParse = append(toParse, f)
91			}
92			filesystem[f] = []byte(content)
93		}
94		config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
95		ctx := android.NewTestContext(config)
96		ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
97		for _, m := range testCase.depsMutators {
98			ctx.DepsBp2BuildMutators(m)
99		}
100		ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
101		ctx.RegisterForBazelConversion()
102
103		_, errs := ctx.ParseFileList(dir, toParse)
104		if Errored(t, testCase.description, errs) {
105			continue
106		}
107		_, errs = ctx.ResolveDependencies(config)
108		if Errored(t, testCase.description, errs) {
109			continue
110		}
111
112		checkDir := dir
113		if testCase.dir != "" {
114			checkDir = testCase.dir
115		}
116		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
117		bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
118		if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
119			t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
120		} else {
121			for i, target := range bazelTargets {
122				if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
123					t.Errorf(
124						"%s: Expected generated Bazel target to be '%s', got '%s'",
125						testCase.description,
126						w,
127						g,
128					)
129				}
130			}
131		}
132	}
133}
134