• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 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 java
16
17import (
18	"slices"
19	"strconv"
20	"strings"
21	"testing"
22
23	"android/soong/android"
24)
25
26func TestKotlin(t *testing.T) {
27	t.Parallel()
28	bp := `
29		java_library {
30			name: "foo",
31			srcs: ["a.java", "b.kt"],
32			static_libs: ["quz"],
33		}
34
35		java_library {
36			name: "bar",
37			srcs: ["b.kt"],
38			libs: ["foo"],
39			static_libs: ["baz"],
40		}
41
42		java_library {
43			name: "baz",
44			srcs: ["c.java"],
45			static_libs: ["quz"],
46		}
47
48		java_library {
49			name: "quz",
50			srcs: ["d.kt"],
51		}`
52
53	kotlinStdlibTurbineJars := []string{
54		"out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine/kotlin-stdlib.jar",
55		"out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine/kotlin-stdlib-jdk7.jar",
56		"out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/turbine/kotlin-stdlib-jdk8.jar",
57		"out/soong/.intermediates/default/java/kotlin-annotations/android_common/turbine/kotlin-annotations.jar",
58	}
59
60	kotlinStdlibJavacJars := []string{
61		"out/soong/.intermediates/default/java/kotlin-stdlib/android_common/javac/kotlin-stdlib.jar",
62		"out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/javac/kotlin-stdlib-jdk7.jar",
63		"out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/javac/kotlin-stdlib-jdk8.jar",
64		"out/soong/.intermediates/default/java/kotlin-annotations/android_common/javac/kotlin-annotations.jar",
65	}
66
67	bootclasspathTurbineJars := []string{
68		"out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine/stable.core.platform.api.stubs.jar",
69		"out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine/core-lambda-stubs.jar",
70	}
71
72	frameworkTurbineJars := []string{
73		"out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
74		"out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
75	}
76
77	testCases := []struct {
78		name string
79
80		preparer android.FixturePreparer
81
82		fooKotlincInputs        []string
83		fooJavacInputs          []string
84		fooKotlincClasspath     []string
85		fooJavacClasspath       []string
86		fooCombinedInputs       []string
87		fooHeaderCombinedInputs []string
88
89		barKotlincInputs        []string
90		barKotlincClasspath     []string
91		barCombinedInputs       []string
92		barHeaderCombinedInputs []string
93	}{
94		{
95			name:             "transitive classpath",
96			preparer:         android.NullFixturePreparer,
97			fooKotlincInputs: []string{"a.java", "b.kt"},
98			fooJavacInputs:   []string{"a.java"},
99			fooKotlincClasspath: slices.Concat(
100				bootclasspathTurbineJars,
101				frameworkTurbineJars,
102				[]string{"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar"},
103				kotlinStdlibTurbineJars,
104			),
105			fooJavacClasspath: slices.Concat(
106				[]string{"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar"},
107				frameworkTurbineJars,
108				[]string{"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar"},
109				kotlinStdlibTurbineJars,
110			),
111			fooCombinedInputs: slices.Concat(
112				[]string{
113					"out/soong/.intermediates/foo/android_common/kotlin/foo.jar",
114					"out/soong/.intermediates/foo/android_common/javac/foo.jar",
115					"out/soong/.intermediates/quz/android_common/kotlin/quz.jar",
116				},
117				kotlinStdlibJavacJars,
118			),
119			fooHeaderCombinedInputs: slices.Concat(
120				[]string{
121					"out/soong/.intermediates/foo/android_common/turbine/foo.jar",
122					"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar",
123					"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
124				},
125				kotlinStdlibTurbineJars,
126			),
127
128			barKotlincInputs: []string{"b.kt"},
129			barKotlincClasspath: slices.Concat(
130				bootclasspathTurbineJars,
131				frameworkTurbineJars,
132				[]string{
133					"out/soong/.intermediates/foo/android_common/turbine/foo.jar",
134					"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar",
135					"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
136				},
137				kotlinStdlibTurbineJars,
138				[]string{"out/soong/.intermediates/baz/android_common/turbine/baz.jar"},
139			),
140			barCombinedInputs: slices.Concat(
141				[]string{
142					"out/soong/.intermediates/bar/android_common/kotlin/bar.jar",
143					"out/soong/.intermediates/baz/android_common/javac/baz.jar",
144					"out/soong/.intermediates/quz/android_common/kotlin/quz.jar",
145				},
146				kotlinStdlibJavacJars,
147			),
148			barHeaderCombinedInputs: slices.Concat(
149				[]string{
150					"out/soong/.intermediates/bar/android_common/kotlin_headers/bar.jar",
151					"out/soong/.intermediates/baz/android_common/turbine/baz.jar",
152					"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
153				},
154				kotlinStdlibTurbineJars,
155			),
156		},
157	}
158
159	for _, tt := range testCases {
160		t.Run(tt.name, func(t *testing.T) {
161			t.Parallel()
162			result := android.GroupFixturePreparers(
163				PrepareForTestWithJavaDefaultModules,
164				tt.preparer,
165			).RunTestWithBp(t, bp)
166			foo := result.ModuleForTests(t, "foo", "android_common")
167			fooKotlinc := foo.Rule("kotlinc")
168			android.AssertPathsRelativeToTopEquals(t, "foo kotlinc inputs", tt.fooKotlincInputs, fooKotlinc.Inputs)
169
170			fooKotlincClasspath := android.ContentFromFileRuleForTests(t, result.TestContext, foo.Output("kotlinc/classpath.rsp"))
171			android.AssertStringPathsRelativeToTopEquals(t, "foo kotlinc classpath", result.Config, tt.fooKotlincClasspath, strings.Fields(fooKotlincClasspath))
172
173			fooJavac := foo.Rule("javac")
174			android.AssertPathsRelativeToTopEquals(t, "foo javac inputs", tt.fooJavacInputs, fooJavac.Inputs)
175
176			fooJavacClasspath := fooJavac.Args["classpath"]
177			android.AssertStringPathsRelativeToTopEquals(t, "foo javac classpath", result.Config, tt.fooJavacClasspath,
178				strings.Split(strings.TrimPrefix(fooJavacClasspath, "-classpath "), ":"))
179
180			fooCombinedJar := foo.Output("combined/foo.jar")
181			android.AssertPathsRelativeToTopEquals(t, "foo combined inputs", tt.fooCombinedInputs, fooCombinedJar.Inputs)
182
183			fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar")
184			android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs)
185
186			bar := result.ModuleForTests(t, "bar", "android_common")
187			barKotlinc := bar.Rule("kotlinc")
188			android.AssertPathsRelativeToTopEquals(t, "bar kotlinc inputs", tt.barKotlincInputs, barKotlinc.Inputs)
189
190			barKotlincClasspath := android.ContentFromFileRuleForTests(t, result.TestContext, bar.Output("kotlinc/classpath.rsp"))
191			android.AssertStringPathsRelativeToTopEquals(t, "bar kotlinc classpath", result.Config, tt.barKotlincClasspath, strings.Fields(barKotlincClasspath))
192
193			barCombinedJar := bar.Output("combined/bar.jar")
194			android.AssertPathsRelativeToTopEquals(t, "bar combined inputs", tt.barCombinedInputs, barCombinedJar.Inputs)
195
196			barCombinedHeaderJar := bar.Output("turbine-combined/bar.jar")
197			android.AssertPathsRelativeToTopEquals(t, "bar header combined inputs", tt.barHeaderCombinedInputs, barCombinedHeaderJar.Inputs)
198		})
199	}
200}
201
202func TestKapt(t *testing.T) {
203	t.Parallel()
204	bp := `
205		java_library {
206			name: "foo",
207			srcs: ["a.java", "b.kt"],
208			plugins: ["bar", "baz"],
209			errorprone: {
210				extra_check_modules: ["my_check"],
211			},
212		}
213
214		java_plugin {
215			name: "bar",
216			processor_class: "com.bar",
217			srcs: ["b.java"],
218		}
219
220		java_plugin {
221			name: "baz",
222			processor_class: "com.baz",
223			srcs: ["b.java"],
224		}
225
226		java_plugin {
227			name: "my_check",
228			srcs: ["b.java"],
229		}
230	`
231	t.Run("", func(t *testing.T) {
232		t.Parallel()
233		ctx, _ := testJava(t, bp)
234
235		buildOS := ctx.Config().BuildOS.String()
236
237		foo := ctx.ModuleForTests(t, "foo", "android_common")
238		kaptStubs := foo.Rule("kapt")
239		turbineApt := foo.Description("turbine apt")
240		kotlinc := foo.Rule("kotlinc")
241		javac := foo.Rule("javac")
242
243		bar := ctx.ModuleForTests(t, "bar", buildOS+"_common").Rule("javac").Output.String()
244		baz := ctx.ModuleForTests(t, "baz", buildOS+"_common").Rule("javac").Output.String()
245
246		// Test that the kotlin and java sources are passed to kapt and kotlinc
247		if len(kaptStubs.Inputs) != 2 || kaptStubs.Inputs[0].String() != "a.java" || kaptStubs.Inputs[1].String() != "b.kt" {
248			t.Errorf(`foo kapt inputs %v != ["a.java", "b.kt"]`, kaptStubs.Inputs)
249		}
250		if len(kotlinc.Inputs) != 2 || kotlinc.Inputs[0].String() != "a.java" || kotlinc.Inputs[1].String() != "b.kt" {
251			t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, kotlinc.Inputs)
252		}
253
254		// Test that only the java sources are passed to turbine-apt and javac
255		if len(turbineApt.Inputs) != 1 || turbineApt.Inputs[0].String() != "a.java" {
256			t.Errorf(`foo turbine apt inputs %v != ["a.java"]`, turbineApt.Inputs)
257		}
258		if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
259			t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
260		}
261
262		// Test that the kapt stubs jar is a dependency of turbine-apt
263		if !inList(kaptStubs.Output.String(), turbineApt.Implicits.Strings()) {
264			t.Errorf("expected %q in turbine-apt implicits %v", kaptStubs.Output.String(), kotlinc.Implicits.Strings())
265		}
266
267		// Test that the turbine-apt srcjar is a dependency of kotlinc and javac rules
268		if !inList(turbineApt.Output.String(), kotlinc.Implicits.Strings()) {
269			t.Errorf("expected %q in kotlinc implicits %v", turbineApt.Output.String(), kotlinc.Implicits.Strings())
270		}
271		if !inList(turbineApt.Output.String(), javac.Implicits.Strings()) {
272			t.Errorf("expected %q in javac implicits %v", turbineApt.Output.String(), javac.Implicits.Strings())
273		}
274
275		// Test that the turbine-apt srcjar is extracted by the kotlinc and javac rules
276		if kotlinc.Args["srcJars"] != turbineApt.Output.String() {
277			t.Errorf("expected %q in kotlinc srcjars %v", turbineApt.Output.String(), kotlinc.Args["srcJars"])
278		}
279		if javac.Args["srcJars"] != turbineApt.Output.String() {
280			t.Errorf("expected %q in javac srcjars %v", turbineApt.Output.String(), kotlinc.Args["srcJars"])
281		}
282
283		// Test that the processors are passed to kapt
284		expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
285			" -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
286		if kaptStubs.Args["kaptProcessorPath"] != expectedProcessorPath {
287			t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kaptStubs.Args["kaptProcessorPath"])
288		}
289		expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
290		if kaptStubs.Args["kaptProcessor"] != expectedProcessor {
291			t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kaptStubs.Args["kaptProcessor"])
292		}
293
294		// Test that the processors are passed to turbine-apt
295		expectedProcessorPath = "--processorpath " + bar + " " + baz
296		if !strings.Contains(turbineApt.Args["turbineFlags"], expectedProcessorPath) {
297			t.Errorf("expected turbine-apt processorpath %q, got %q", expectedProcessorPath, turbineApt.Args["turbineFlags"])
298		}
299		expectedProcessor = "--processors com.bar com.baz"
300		if !strings.Contains(turbineApt.Args["turbineFlags"], expectedProcessor) {
301			t.Errorf("expected turbine-apt processor %q, got %q", expectedProcessor, turbineApt.Args["turbineFlags"])
302		}
303
304		// Test that the processors are not passed to javac
305		if javac.Args["processorpath"] != "" {
306			t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
307		}
308		if javac.Args["processor"] != "-proc:none" {
309			t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
310		}
311	})
312
313	t.Run("errorprone", func(t *testing.T) {
314		t.Parallel()
315		env := map[string]string{
316			"RUN_ERROR_PRONE": "true",
317		}
318
319		result := android.GroupFixturePreparers(
320			PrepareForTestWithJavaDefaultModules,
321			android.FixtureMergeEnv(env),
322		).RunTestWithBp(t, bp)
323
324		buildOS := result.Config.BuildOS.String()
325
326		kapt := result.ModuleForTests(t, "foo", "android_common").Rule("kapt")
327		javac := result.ModuleForTests(t, "foo", "android_common").Description("javac")
328		errorprone := result.ModuleForTests(t, "foo", "android_common").Description("errorprone")
329
330		bar := result.ModuleForTests(t, "bar", buildOS+"_common").Description("javac").Output.String()
331		baz := result.ModuleForTests(t, "baz", buildOS+"_common").Description("javac").Output.String()
332		myCheck := result.ModuleForTests(t, "my_check", buildOS+"_common").Description("javac").Output.String()
333
334		// Test that the errorprone plugins are not passed to kapt
335		expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
336			" -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
337		if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
338			t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
339		}
340		expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
341		if kapt.Args["kaptProcessor"] != expectedProcessor {
342			t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
343		}
344
345		// Test that the errorprone plugins are not passed to javac
346		if javac.Args["processorpath"] != "" {
347			t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
348		}
349		if javac.Args["processor"] != "-proc:none" {
350			t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
351		}
352
353		// Test that the errorprone plugins are passed to errorprone
354		expectedProcessorPath = "-processorpath " + myCheck
355		if errorprone.Args["processorpath"] != expectedProcessorPath {
356			t.Errorf("expected processorpath %q, got %q", expectedProcessorPath, errorprone.Args["processorpath"])
357		}
358		if errorprone.Args["processor"] != "-proc:none" {
359			t.Errorf("expected processor '-proc:none', got %q", errorprone.Args["processor"])
360		}
361	})
362}
363
364func TestKaptEncodeFlags(t *testing.T) {
365	t.Parallel()
366	// Compares the kaptEncodeFlags against the results of the example implementation at
367	// https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
368	tests := []struct {
369		in  [][2]string
370		out string
371	}{
372		{
373			// empty input
374			in:  [][2]string{},
375			out: "rO0ABXcEAAAAAA==",
376		},
377		{
378			// common input
379			in: [][2]string{
380				{"-source", "1.8"},
381				{"-target", "1.8"},
382			},
383			out: "rO0ABXcgAAAAAgAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjg=",
384		},
385		{
386			// input that serializes to a 255 byte block
387			in: [][2]string{
388				{"-source", "1.8"},
389				{"-target", "1.8"},
390				{"a", strings.Repeat("b", 218)},
391			},
392			out: "rO0ABXf/AAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA2mJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi",
393		},
394		{
395			// input that serializes to a 256 byte block
396			in: [][2]string{
397				{"-source", "1.8"},
398				{"-target", "1.8"},
399				{"a", strings.Repeat("b", 219)},
400			},
401			out: "rO0ABXoAAAEAAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA22JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYg==",
402		},
403		{
404			// input that serializes to a 257 byte block
405			in: [][2]string{
406				{"-source", "1.8"},
407				{"-target", "1.8"},
408				{"a", strings.Repeat("b", 220)},
409			},
410			out: "rO0ABXoAAAEBAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA3GJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI=",
411		},
412	}
413
414	for i, test := range tests {
415		t.Run(strconv.Itoa(i), func(t *testing.T) {
416			t.Parallel()
417			got := kaptEncodeFlags(test.in)
418			if got != test.out {
419				t.Errorf("\nwant %q\n got %q", test.out, got)
420			}
421		})
422	}
423}
424
425func TestKotlinCompose(t *testing.T) {
426	t.Parallel()
427	result := android.GroupFixturePreparers(
428		PrepareForTestWithJavaDefaultModules,
429	).RunTestWithBp(t, `
430		java_library {
431			name: "androidx.compose.runtime_runtime",
432		}
433
434		kotlin_plugin {
435			name: "kotlin-compose-compiler-plugin",
436		}
437
438		java_library {
439			name: "withcompose",
440			srcs: ["a.kt"],
441			plugins: ["plugin"],
442			static_libs: ["androidx.compose.runtime_runtime"],
443		}
444
445		java_library {
446			name: "nocompose",
447			srcs: ["a.kt"],
448		}
449
450		java_plugin {
451			name: "plugin",
452		}
453	`)
454
455	buildOS := result.Config.BuildOS.String()
456
457	composeCompiler := result.ModuleForTests(t, "kotlin-compose-compiler-plugin", buildOS+"_common").Rule("combineJar").Output
458	withCompose := result.ModuleForTests(t, "withcompose", "android_common")
459	noCompose := result.ModuleForTests(t, "nocompose", "android_common")
460
461	android.AssertStringListContains(t, "missing compose compiler dependency",
462		withCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
463
464	android.AssertStringDoesContain(t, "missing compose compiler plugin",
465		withCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
466
467	android.AssertStringListContains(t, "missing kapt compose compiler dependency",
468		withCompose.Rule("kapt").Implicits.Strings(), composeCompiler.String())
469
470	android.AssertStringListDoesNotContain(t, "unexpected compose compiler dependency",
471		noCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
472
473	android.AssertStringDoesNotContain(t, "unexpected compose compiler plugin",
474		noCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
475}
476
477func TestKotlinPlugin(t *testing.T) {
478	t.Parallel()
479	result := android.GroupFixturePreparers(
480		PrepareForTestWithJavaDefaultModules,
481	).RunTestWithBp(t, `
482		kotlin_plugin {
483			name: "kotlin_plugin",
484		}
485
486		java_library {
487			name: "with_kotlin_plugin",
488			srcs: ["a.kt"],
489			plugins: ["plugin"],
490			kotlin_plugins: ["kotlin_plugin"],
491		}
492
493		java_library {
494			name: "no_kotlin_plugin",
495			srcs: ["a.kt"],
496		}
497
498		java_plugin {
499			name: "plugin",
500		}
501	`)
502
503	buildOS := result.Config.BuildOS.String()
504
505	kotlinPlugin := result.ModuleForTests(t, "kotlin_plugin", buildOS+"_common").Rule("combineJar").Output
506	withKotlinPlugin := result.ModuleForTests(t, "with_kotlin_plugin", "android_common")
507	noKotlinPlugin := result.ModuleForTests(t, "no_kotlin_plugin", "android_common")
508
509	android.AssertStringListContains(t, "missing plugin compiler dependency",
510		withKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
511
512	android.AssertStringDoesContain(t, "missing kotlin plugin",
513		withKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String())
514
515	android.AssertStringListContains(t, "missing kapt kotlin plugin dependency",
516		withKotlinPlugin.Rule("kapt").Implicits.Strings(), kotlinPlugin.String())
517
518	android.AssertStringListDoesNotContain(t, "unexpected kotlin plugin dependency",
519		noKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
520
521	android.AssertStringDoesNotContain(t, "unexpected kotlin plugin",
522		noKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String())
523}
524