xref: /aosp_15_r20/tools/metalava/metalava/src/test/java/com/android/tools/metalava/cli/common/BaseOptionGroupTest.kt (revision 115816f9299ab6ddd6b9673b81f34e707f6bacab)
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tools.metalava.cli.common
18 
19 import com.android.tools.metalava.ProgressTracker
20 import com.android.tools.metalava.testing.TemporaryFolderOwner
21 import com.github.ajalt.clikt.core.CliktCommand
22 import com.github.ajalt.clikt.core.context
23 import com.github.ajalt.clikt.core.subcommands
24 import com.github.ajalt.clikt.parameters.groups.OptionGroup
25 import com.github.ajalt.clikt.parameters.groups.provideDelegate
26 import org.junit.Assert
27 import org.junit.Rule
28 import org.junit.Test
29 import org.junit.rules.TemporaryFolder
30 
31 /** Base class for tests of [OptionGroup] classes. */
32 abstract class BaseOptionGroupTest<O : OptionGroup>(
33     private val expectedHelp: String,
34 ) : TemporaryFolderOwner {
35 
36     @get:Rule override val temporaryFolder = TemporaryFolder()
37 
createOptionsnull38     protected abstract fun createOptions(): O
39 
40     /**
41      * Run a test on the [OptionGroup] of type [O].
42      *
43      * Generally this will use the [OptionGroup] created by [createOptions] but that can be
44      * overridden for a test by providing an [optionGroup] parameter directly.
45      */
46     protected fun runTest(
47         vararg args: String,
48         optionGroup: O? = null,
49         test: Result<O>.() -> Unit,
50     ) {
51         val testFactory = { optionGroup ?: createOptions() }
52         val command = MockCommand(testFactory)
53         val (executionEnvironment, stdout, stderr) = ExecutionEnvironment.forTest()
54         val rootCommand = MetalavaCommand(executionEnvironment, null, ProgressTracker())
55         rootCommand.subcommands(command)
56         rootCommand.process(arrayOf("mock") + args)
57         val result =
58             Result(
59                 options = command.options,
60                 stdout = removeBoilerplate(stdout.toString()),
61                 stderr = removeBoilerplate(stderr.toString()),
62             )
63         result.test()
64     }
65 
66     /** Remove various different forms of boilerplate text. */
removeBoilerplatenull67     private fun removeBoilerplate(out: String) =
68         out.trim()
69             .removePrefix("Aborting: ")
70             .removePrefix("Usage: metalava mock [options]")
71             .trim()
72             .removePrefix("Error: ")
73 
74     data class Result<O : OptionGroup>(
75         val options: O,
76         val stdout: String,
77         val stderr: String,
78     )
79 
80     @Test
81     fun `Test help`() {
82         runTest { Assert.assertEquals(expectedHelp, stdout) }
83     }
84 }
85 
86 private class MockCommand<O : OptionGroup>(factory: () -> O) :
87     CliktCommand(printHelpOnEmptyArgs = true) {
88     val options by factory()
89 
90     init {
<lambda>null91         context {
92             localization = MetalavaLocalization()
93             helpFormatter = MetalavaHelpFormatter(::plainTerminal, localization)
94         }
95     }
96 
runnull97     override fun run() {}
98 }
99