1 /*
2  * Copyright (C) 2017 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
18 
19 import org.junit.Assert.assertEquals
20 import org.junit.Test
21 import java.io.PrintWriter
22 import java.io.StringWriter
23 
24 @Suppress("PrivatePropertyName")
25 class OptionsTest : DriverTest() {
26     private val DESCRIPTION = """
27 $PROGRAM_NAME extracts metadata from source code to generate artifacts such as the signature
28 files, the SDK stub files, external annotations etc.
29 """.trimIndent()
30 
31     private val FLAGS = """
32 Usage: $PROGRAM_NAME <flags>
33 
34 General:
35 --help                                 This message.
36 --version                              Show the version of metalava.
37 --quiet                                Only include vital output
38 --verbose                              Include extra diagnostic output
39 --color                                Attempt to colorize the output (defaults to true if
40                                        ${"$"}TERM is xterm)
41 --no-color                             Do not attempt to colorize the output
42 
43 API sources:
44 --source-files <files>                 A comma separated list of source files to be
45                                        parsed. Can also be @ followed by a path to a text
46                                        file containing paths to the full set of files to
47                                        parse.
48 --source-path <paths>                  One or more directories (separated by `:`)
49                                        containing source files (within a package
50                                        hierarchy)
51 --classpath <paths>                    One or more directories or jars (separated by `:`)
52                                        containing classes that should be on the classpath
53                                        when parsing the source files
54 --merge-annotations <file>             An external annotations file (using IntelliJ's
55                                        external annotations database format) to merge and
56                                        overlay the sources. A subset of .jaif files is
57                                        also supported.
58 --input-api-jar <file>                 A .jar file to read APIs from directly
59 --manifest <file>                      A manifest file, used to for check permissions to
60                                        cross check APIs
61 --hide-package <package>               Remove the given packages from the API even if they
62                                        have not been marked with @hide
63 --show-annotation <annotation class>   Include the given annotation in the API analysis
64 --show-unannotated                     Include un-annotated public APIs in the signature
65                                        file as well
66 --java-source <level>                  Sets the source level for Java source files;
67                                        default is 1.8.
68 
69 Documentation:
70 --public                               Only include elements that are public
71 --protected                            Only include elements that are public or protected
72 --package                              Only include elements that are public, protected or
73                                        package protected
74 --private                              Include all elements except those that are marked
75                                        hidden
76 --hidden                               Include all elements, including hidden
77 
78 Extracting Signature Files:
79 --api <file>                           Generate a signature descriptor file
80 --private-api <file>                   Generate a signature descriptor file listing the
81                                        exact private APIs
82 --dex-api <file>                       Generate a DEX signature descriptor file listing
83                                        the APIs
84 --private-dex-api <file>               Generate a DEX signature descriptor file listing
85                                        the exact private APIs
86 --removed-api <file>                   Generate a signature descriptor file for APIs that
87                                        have been removed
88 --output-kotlin-nulls[=yes|no]         Controls whether nullness annotations should be
89                                        formatted as in Kotlin (with "?" for nullable
90                                        types, "" for non nullable types, and "!" for
91                                        unknown. The default is yes.
92 --output-default-values[=yes|no]       Controls whether default values should be included
93                                        in signature files. The default is yes.
94 --compatible-output=[yes|no]           Controls whether to keep signature files compatible
95                                        with the historical format (with its various
96                                        quirks) or to generate the new format (which will
97                                        also include annotations that are part of the API,
98                                        etc.)
99 --omit-common-packages[=yes|no]        Skip common package prefixes like java.lang.* and
100                                        kotlin.* in signature files, along with packages
101                                        for well known annotations like @Nullable and
102                                        @NonNull.
103 --proguard <file>                      Write a ProGuard keep file for the API
104 --sdk-values <dir>                     Write SDK values files to the given directory
105 
106 Generating Stubs:
107 --stubs <dir>                          Generate stub source files for the API
108 --doc-stubs <dir>                      Generate documentation stub source files for the
109                                        API. Documentation stub files are similar to
110                                        regular stub files, but there are some differences.
111                                        For example, in the stub files, we'll use special
112                                        annotations like @RecentlyNonNull instead of
113                                        @NonNull to indicate that an element is recently
114                                        marked as non null, whereas in the documentation
115                                        stubs we'll just list this as @NonNull. Another
116                                        difference is that @doconly elements are included
117                                        in documentation stubs, but not regular stubs,
118                                        etc.
119 --exclude-annotations                  Exclude annotations such as @Nullable from the stub
120                                        files
121 --write-stubs-source-list <file>       Write the list of generated stub files into the
122                                        given source list file. If generating documentation
123                                        stubs and you haven't also specified
124                                        --write-doc-stubs-source-list, this list will refer
125                                        to the documentation stubs; otherwise it's the
126                                        non-documentation stubs.
127 --write-doc-stubs-source-list <file>   Write the list of generated doc stub files into the
128                                        given source list file
129 --register-artifact <api-file> <id>    Registers the given id for the packages found in
130                                        the given signature file. metalava will inject an
131                                        @artifactId <id> tag into every top level stub
132                                        class in that API.
133 
134 Diffs and Checks:
135 --previous-api <signature file>        A signature file for the previous version of this
136                                        API to apply diffs with
137 --input-kotlin-nulls[=yes|no]          Whether the signature file being read should be
138                                        interpreted as having encoded its types using
139                                        Kotlin style types: a suffix of "?" for nullable
140                                        types, no suffix for non nullable types, and "!"
141                                        for unknown. The default is no.
142 --check-compatibility                  Check compatibility with the previous API
143 --check-kotlin-interop                 Check API intended to be used from both Kotlin and
144                                        Java for interoperability issues
145 --current-api <signature file>         A signature file for the current version of this
146                                        API to check compatibility with. If not specified,
147                                        --previous-api will be used instead.
148 --migrate-nullness                     Compare nullness information with the previous API
149                                        and mark newly annotated APIs as under migration.
150 --warnings-as-errors                   Promote all warnings to errors
151 --lints-as-errors                      Promote all API lint warnings to errors
152 --error <id>                           Report issues of the given id as errors
153 --warning <id>                         Report issues of the given id as warnings
154 --lint <id>                            Report issues of the given id as having
155                                        lint-severity
156 --hide <id>                            Hide/skip issues of the given id
157 
158 Statistics:
159 --annotation-coverage-stats            Whether metalava should emit coverage statistics
160                                        for annotations, listing the percentage of the API
161                                        that has been annotated with nullness information.
162 --annotation-coverage-of <paths>       One or more jars (separated by `:`) containing
163                                        existing apps that we want to measure annotation
164                                        coverage statistics for. The set of API usages in
165                                        those apps are counted up and the most frequently
166                                        used APIs that are missing annotation metadata are
167                                        listed in descending order.
168 --skip-java-in-coverage-report         In the coverage annotation report, skip java.** and
169                                        kotlin.** to narrow the focus down to the Android
170                                        framework APIs.
171 --write-class-coverage-to <path>       Specifies a file to write the annotation coverage
172                                        report for classes to.
173 --write-member-coverage-to <path>      Specifies a file to write the annotation coverage
174                                        report for members to.
175 
176 Extracting Annotations:
177 --extract-annotations <zipfile>        Extracts source annotations from the source files
178                                        and writes them into the given zip file
179 
180 Injecting API Levels:
181 --apply-api-levels <api-versions.xml>  Reads an XML file containing API level descriptions
182                                        and merges the information into the documentation
183 
184 Extracting API Levels:
185 --generate-api-levels <xmlfile>        Reads android.jar SDK files and generates an XML
186                                        file recording the API level for each class, method
187                                        and field
188 --android-jar-pattern <pattern>        Patterns to use to locate Android JAR files. The
189                                        default is
190                                        ${"$"}ANDROID_HOME/platforms/android-%/android.jar.
191 --current-version                      Sets the current API level of the current source
192                                        code
193 --current-codename                     Sets the code name for the current source code
194 --current-jar                          Points to the current API jar, if any
195 
196 """.trimIndent()
197 
198     @Test
Test invalid argumentsnull199     fun `Test invalid arguments`() {
200         val args = listOf("--no-color", "--blah-blah-blah")
201 
202         val stdout = StringWriter()
203         val stderr = StringWriter()
204         com.android.tools.metalava.run(
205             args = args.toTypedArray(),
206             stdout = PrintWriter(stdout),
207             stderr = PrintWriter(stderr)
208         )
209         assertEquals(BANNER + "\n\n", stdout.toString())
210         assertEquals(
211             """
212 
213 Invalid argument --blah-blah-blah
214 
215 $FLAGS
216 
217 """.trimIndent(), stderr.toString()
218         )
219     }
220 
221     @Test
Test helpnull222     fun `Test help`() {
223         val args = listOf("--no-color", "--help")
224 
225         val stdout = StringWriter()
226         val stderr = StringWriter()
227         com.android.tools.metalava.run(
228             args = args.toTypedArray(),
229             stdout = PrintWriter(stdout),
230             stderr = PrintWriter(stderr)
231         )
232         assertEquals("", stderr.toString())
233         assertEquals(
234             """
235 $BANNER
236 
237 
238 $DESCRIPTION
239 
240 $FLAGS
241 
242 """.trimIndent(), stdout.toString()
243         )
244     }
245 }