1/*
2 * Copyright (C) 2012 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
17package com.android.tools.lint.checks;
18
19import com.android.tools.lint.detector.api.Detector;
20import com.android.tools.lint.detector.api.Issue;
21
22@SuppressWarnings("javadoc")
23public class ButtonDetectorTest extends AbstractCheckTest {
24    private static Issue sTestIssue;
25
26    @Override
27    protected boolean isEnabled(Issue issue) {
28        return super.isEnabled(issue) && sTestIssue == null || issue == sTestIssue;
29
30    }
31
32    @Override
33    protected Detector getDetector() {
34        return new ButtonDetector();
35    }
36
37    public void testButtonOrder() throws Exception {
38        sTestIssue = ButtonDetector.ORDER;
39        assertEquals(
40            "res/layout/buttonbar.xml:12: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
41            "        <Button\n" +
42            "        ^\n" +
43            "res/layout/buttonbar.xml:44: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
44            "        <Button\n" +
45            "        ^\n" +
46            "res/layout/buttonbar.xml:92: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
47            "        <Button\n" +
48            "        ^\n" +
49            "res/layout/buttonbar.xml:124: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
50            "        <Button\n" +
51            "        ^\n" +
52            "res/layout/buttonbar.xml:140: Warning: OK button should be on the right (was \"Ok | CANCEL\", should be \"CANCEL | Ok\") [ButtonOrder]\n" +
53            "        <Button\n" +
54            "        ^\n" +
55            "res/layout/buttonbar.xml:156: Warning: OK button should be on the right (was \"OK | Abort\", should be \"Abort | OK\") [ButtonOrder]\n" +
56            "        <Button\n" +
57            "        ^\n" +
58            "res/layout/buttonbar.xml:177: Warning: Cancel button should be on the left (was \"Send | Cancel\", should be \"Cancel | Send\") [ButtonOrder]\n" +
59            "        <Button\n" +
60            "        ^\n" +
61            "0 errors, 7 warnings\n" +
62            "",
63
64            lintProject(
65                    "apicheck/minsdk14.xml=>AndroidManifest.xml",
66                    "res/layout/buttonbar.xml",
67                    "res/values/buttonbar-values.xml"));
68    }
69
70    public void testButtonOrder2() throws Exception {
71        // If the layout is in v14, it had better have the right order
72        sTestIssue = ButtonDetector.ORDER;
73        assertEquals(
74            "res/layout-v14/buttonbar.xml:12: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
75            "        <Button\n" +
76            "        ^\n" +
77            "res/layout-v14/buttonbar.xml:44: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
78            "        <Button\n" +
79            "        ^\n" +
80            "res/layout-v14/buttonbar.xml:92: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
81            "        <Button\n" +
82            "        ^\n" +
83            "res/layout-v14/buttonbar.xml:124: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
84            "        <Button\n" +
85            "        ^\n" +
86            "res/layout-v14/buttonbar.xml:140: Warning: OK button should be on the right (was \"Ok | CANCEL\", should be \"CANCEL | Ok\") [ButtonOrder]\n" +
87            "        <Button\n" +
88            "        ^\n" +
89            "res/layout-v14/buttonbar.xml:156: Warning: OK button should be on the right (was \"OK | Abort\", should be \"Abort | OK\") [ButtonOrder]\n" +
90            "        <Button\n" +
91            "        ^\n" +
92            "res/layout-v14/buttonbar.xml:177: Warning: Cancel button should be on the left (was \"Send | Cancel\", should be \"Cancel | Send\") [ButtonOrder]\n" +
93            "        <Button\n" +
94            "        ^\n" +
95            "0 errors, 7 warnings\n" +
96            "",
97
98            lintProject(
99                    "minsdk5targetsdk14.xml=>AndroidManifest.xml",
100                    "res/layout/buttonbar.xml=>res/layout-v14/buttonbar.xml",
101                    "res/values/buttonbar-values.xml"));
102    }
103
104    public void testButtonOrder3() throws Exception {
105        // Similar to test 3, but also complain if the -v version is *higher* than 14
106        sTestIssue = ButtonDetector.ORDER;
107        assertEquals(
108            "res/layout-v16/buttonbar.xml:12: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
109            "        <Button\n" +
110            "        ^\n" +
111            "res/layout-v16/buttonbar.xml:44: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
112            "        <Button\n" +
113            "        ^\n" +
114            "res/layout-v16/buttonbar.xml:92: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
115            "        <Button\n" +
116            "        ^\n" +
117            "res/layout-v16/buttonbar.xml:124: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
118            "        <Button\n" +
119            "        ^\n" +
120            "res/layout-v16/buttonbar.xml:140: Warning: OK button should be on the right (was \"Ok | CANCEL\", should be \"CANCEL | Ok\") [ButtonOrder]\n" +
121            "        <Button\n" +
122            "        ^\n" +
123            "res/layout-v16/buttonbar.xml:156: Warning: OK button should be on the right (was \"OK | Abort\", should be \"Abort | OK\") [ButtonOrder]\n" +
124            "        <Button\n" +
125            "        ^\n" +
126            "res/layout-v16/buttonbar.xml:177: Warning: Cancel button should be on the left (was \"Send | Cancel\", should be \"Cancel | Send\") [ButtonOrder]\n" +
127            "        <Button\n" +
128            "        ^\n" +
129            "0 errors, 7 warnings\n" +
130            "",
131
132            lintProject(
133                    "minsdk5targetsdk14.xml=>AndroidManifest.xml",
134                    "res/layout/buttonbar.xml=>res/layout-v16/buttonbar.xml",
135                    "res/values/buttonbar-values.xml"));
136    }
137
138    public void testButtonOrder4() throws Exception {
139        // Targeting 14 but using a layout that also needs to work for older platforms:
140        sTestIssue = ButtonDetector.ORDER;
141        assertEquals(
142            "res/layout/buttonbar.xml:12: Warning: Layout uses the wrong button order for API >= 14: Create a layout-v14/buttonbar.xml file with opposite order: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
143            "        <Button\n" +
144            "        ^\n" +
145            "res/layout/buttonbar.xml:44: Warning: Layout uses the wrong button order for API >= 14: Create a layout-v14/buttonbar.xml file with opposite order: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
146            "        <Button\n" +
147            "        ^\n" +
148            "res/layout/buttonbar.xml:92: Warning: Layout uses the wrong button order for API >= 14: Create a layout-v14/buttonbar.xml file with opposite order: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
149            "        <Button\n" +
150            "        ^\n" +
151            "res/layout/buttonbar.xml:124: Warning: Layout uses the wrong button order for API >= 14: Create a layout-v14/buttonbar.xml file with opposite order: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
152            "        <Button\n" +
153            "        ^\n" +
154            "res/layout/buttonbar.xml:140: Warning: Layout uses the wrong button order for API >= 14: Create a layout-v14/buttonbar.xml file with opposite order: OK button should be on the right (was \"Ok | CANCEL\", should be \"CANCEL | Ok\") [ButtonOrder]\n" +
155            "        <Button\n" +
156            "        ^\n" +
157            "res/layout/buttonbar.xml:156: Warning: Layout uses the wrong button order for API >= 14: Create a layout-v14/buttonbar.xml file with opposite order: OK button should be on the right (was \"OK | Abort\", should be \"Abort | OK\") [ButtonOrder]\n" +
158            "        <Button\n" +
159            "        ^\n" +
160            "res/layout/buttonbar.xml:177: Warning: Layout uses the wrong button order for API >= 14: Create a layout-v14/buttonbar.xml file with opposite order: Cancel button should be on the left (was \"Send | Cancel\", should be \"Cancel | Send\") [ButtonOrder]\n" +
161            "        <Button\n" +
162            "        ^\n" +
163            "0 errors, 7 warnings\n" +
164            "",
165
166            lintProject(
167                    "minsdk5targetsdk14.xml=>AndroidManifest.xml",
168                    "res/layout/buttonbar.xml",
169                    "res/values/buttonbar-values.xml"));
170    }
171
172    public void testButtonOrder5() throws Exception {
173        // If the layout is in a non-ICS folder and has the wrong button order,
174        // but there is a v14 version of the layout, don't complain about the non-v14 version
175        sTestIssue = ButtonDetector.ORDER;
176        assertEquals(
177            "No warnings.",
178
179            lintProject(
180                    "minsdk5targetsdk14.xml=>AndroidManifest.xml",
181                    "res/layout/buttonbar.xml",
182                    "res/layout/layout1.xml=>res/layout-v14/buttonbar.xml",
183                    "res/values/buttonbar-values.xml"));
184    }
185
186    public void testButtonOrderRelativeLayout() throws Exception {
187        sTestIssue = ButtonDetector.ORDER;
188        assertEquals(
189            "No warnings.",
190
191            lintProject("res/layout/buttonbar2.xml", "res/values/buttonbar-values.xml"));
192    }
193
194    public void testButtonOrderRelativeLayout2() throws Exception {
195        sTestIssue = ButtonDetector.ORDER;
196        assertEquals(
197            "res/layout/buttonbar3.xml:27: Warning: Cancel button should be on the left [ButtonOrder]\n" +
198            "        <Button\n" +
199            "        ^\n" +
200            "0 errors, 1 warnings\n" +
201            "",
202
203            lintProject(
204                    "apicheck/minsdk14.xml=>AndroidManifest.xml",
205                    "res/layout/buttonbar3.xml",
206                    "res/values/buttonbar-values.xml"));
207    }
208
209    public void testButtonOrderRelativeLayout3() throws Exception {
210        sTestIssue = ButtonDetector.ORDER;
211        assertEquals(
212            "No warnings.",
213
214            lintProject("res/layout/buttonbar4.xml", "res/values/buttonbar-values.xml"));
215    }
216
217
218    public void testCase() throws Exception {
219        sTestIssue = ButtonDetector.CASE;
220        assertEquals(
221            "res/values/buttonbar-values.xml:9: Warning: The standard Android way to capitalize Ok is \"OK\" (tip: use @android:string/ok instead) [ButtonCase]\n" +
222            "    <string name=\"resume2\"> Ok </string>\n" +
223            "                            ^\n" +
224            "res/values/buttonbar-values.xml:10: Warning: The standard Android way to capitalize CANCEL is \"Cancel\" (tip: use @android:string/ok instead) [ButtonCase]\n" +
225            "    <string name=\"giveup2\">\"CANCEL\"</string>\n" +
226            "                           ^\n" +
227            "0 errors, 2 warnings\n" +
228            "",
229
230            lintProject("res/layout/buttonbar.xml", "res/values/buttonbar-values.xml"));
231    }
232
233    public void testBack() throws Exception {
234        sTestIssue = ButtonDetector.BACKBUTTON;
235        assertEquals(
236            "res/layout/buttonbar.xml:183: Warning: Back buttons are not standard on Android; see design guide's navigation section [BackButton]\n" +
237            "    <Button\n" +
238            "    ^\n" +
239            "0 errors, 1 warnings\n" +
240            "",
241
242            lintProject("res/layout/buttonbar.xml", "res/values/buttonbar-values.xml"));
243    }
244
245    public void testOldApp() throws Exception {
246        // Target SDK < 14 - no warnings on button order
247        sTestIssue = ButtonDetector.ORDER;
248        assertEquals(
249                "No warnings.",
250
251        lintProject(
252                "minsdk5targetsdk9.xml=>AndroidManifest.xml",
253                "res/layout/buttonbar.xml",
254                "res/values/buttonbar-values.xml"));
255    }
256
257    public void testEnglishLocales() throws Exception {
258        sTestIssue = ButtonDetector.ORDER;
259        assertEquals(
260            "res/layout-en-rGB/buttonbar.xml:12: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
261            "        <Button\n" +
262            "        ^\n" +
263            "res/layout-en-rGB/buttonbar.xml:44: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
264            "        <Button\n" +
265            "        ^\n" +
266            "res/layout-en-rGB/buttonbar.xml:92: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
267            "        <Button\n" +
268            "        ^\n" +
269            "res/layout-en-rGB/buttonbar.xml:124: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
270            "        <Button\n" +
271            "        ^\n" +
272            "res/layout-en-rGB/buttonbar.xml:140: Warning: OK button should be on the right (was \"Ok | CANCEL\", should be \"CANCEL | Ok\") [ButtonOrder]\n" +
273            "        <Button\n" +
274            "        ^\n" +
275            "res/layout-en-rGB/buttonbar.xml:156: Warning: OK button should be on the right (was \"OK | Abort\", should be \"Abort | OK\") [ButtonOrder]\n" +
276            "        <Button\n" +
277            "        ^\n" +
278            "res/layout-en-rGB/buttonbar.xml:177: Warning: Cancel button should be on the left (was \"Send | Cancel\", should be \"Cancel | Send\") [ButtonOrder]\n" +
279            "        <Button\n" +
280            "        ^\n" +
281            "0 errors, 7 warnings\n" +
282            "",
283
284            lintProject(
285                    "apicheck/minsdk14.xml=>AndroidManifest.xml",
286                    "res/layout/buttonbar.xml=>res/layout-en-rGB/buttonbar.xml",
287                    "res/values/buttonbar-values.xml=>res/values-en-rGB/buttonbar-values.xml"));
288    }
289
290    public void testOtherLocales() throws Exception {
291        sTestIssue = ButtonDetector.ORDER;
292        assertEquals(
293            // Hardcoded values only
294            "res/layout-de/buttonbar.xml:12: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
295            "        <Button\n" +
296            "        ^\n" +
297            "res/layout-de/buttonbar.xml:44: Warning: OK button should be on the right (was \"OK | Cancel\", should be \"Cancel | OK\") [ButtonOrder]\n" +
298            "        <Button\n" +
299            "        ^\n" +
300            "0 errors, 2 warnings\n" +
301            "",
302
303            lintProject(
304                    "apicheck/minsdk14.xml=>AndroidManifest.xml",
305                    "res/layout/buttonbar.xml=>res/layout-de/buttonbar.xml",
306                    "res/values/buttonbar-values.xml=>res/values-de/buttonbar-values.xml"));
307    }
308
309    public void testOtherLocales2() throws Exception {
310        sTestIssue = ButtonDetector.CASE;
311        assertEquals(
312                "No warnings.",
313
314                lintProject("res/layout/buttonbar.xml=>res/layout-de/buttonbar.xml",
315                        "res/values/buttonbar-values.xml=>res/values-de/buttonbar-values.xml"));
316    }
317}
318