1d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver/*
2d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * Copyright 2013, Google Inc.
3d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * All rights reserved.
4d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver *
5d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * Redistribution and use in source and binary forms, with or without
6d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * modification, are permitted provided that the following conditions are
7d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * met:
8d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver *
9d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver *     * Redistributions of source code must retain the above copyright
10d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * notice, this list of conditions and the following disclaimer.
11d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver *     * Redistributions in binary form must reproduce the above
12d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * copyright notice, this list of conditions and the following disclaimer
13d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * in the documentation and/or other materials provided with the
14d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * distribution.
15d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver *     * Neither the name of Google Inc. nor the names of its
16d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * contributors may be used to endorse or promote products derived from
17d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * this software without specific prior written permission.
18d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver *
19d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver */
31d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver
32d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruverpackage org.jf.util;
33d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver
34e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruverimport com.google.common.base.Strings;
35e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruverimport com.google.common.io.Files;
36d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruverimport junit.framework.Assert;
37d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruverimport org.junit.Test;
38d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver
39e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruverimport java.io.File;
403b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruverimport java.nio.charset.Charset;
413b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
42d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruverpublic class ClassFileNameHandlerTest {
433b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    private final Charset UTF8 = Charset.forName("UTF-8");
443b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
453b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    @Test
463b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    public void test1ByteEncodings() {
473b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        StringBuilder sb = new StringBuilder();
483b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        for (int i=0; i<100; i++) {
493b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver            sb.append((char)i);
503b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        }
513b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
523b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        String result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 5);
533b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(95, result.getBytes(UTF8).length);
543b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(95, result.length());
553b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    }
563b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
57d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver    @Test
583b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    public void test2ByteEncodings() {
59d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver        StringBuilder sb = new StringBuilder();
603b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        for (int i=0x80; i<0x80+100; i++) {
61d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver            sb.append((char)i);
62d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver        }
63d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver
643b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        // remove a total of 3 2-byte characters, and then add back in the 1-byte '#'
653b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        String result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 4);
663b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(200, sb.toString().getBytes(UTF8).length);
673b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(195, result.getBytes(UTF8).length);
683b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(98, result.length());
693b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
703b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        // remove a total of 3 2-byte characters, and then add back in the 1-byte '#'
713b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 5);
723b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(200, sb.toString().getBytes(UTF8).length);
733b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(195, result.getBytes(UTF8).length);
743b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(98, result.length());
753b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    }
763b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
773b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    @Test
783b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    public void test3ByteEncodings() {
793b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        StringBuilder sb = new StringBuilder();
803b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        for (int i=0x800; i<0x800+100; i++) {
813b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver            sb.append((char)i);
823b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        }
833b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
843b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        // remove a total of 3 3-byte characters, and then add back in the 1-byte '#'
853b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        String result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 6);
863b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(300, sb.toString().getBytes(UTF8).length);
873b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(292, result.getBytes(UTF8).length);
883b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(98, result.length());
893b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
903b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        // remove a total of 3 3-byte characters, and then add back in the 1-byte '#'
913b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 7);
923b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(300, sb.toString().getBytes(UTF8).length);
933b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(292, result.getBytes(UTF8).length);
943b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(98, result.length());
953b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    }
963b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
97e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    @Test
983b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver    public void test4ByteEncodings() {
993b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        StringBuilder sb = new StringBuilder();
1003b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        for (int i=0x10000; i<0x10000+100; i++) {
1013b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver            sb.appendCodePoint(i);
1023b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        }
1033b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver
1043b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        // we remove 3 codepoints == 6 characters == 12 bytes, and then add back in the 1-byte '#'
1053b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        String result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 8);
1063b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(400, sb.toString().getBytes(UTF8).length);
1073b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(389, result.getBytes(UTF8).length);
108e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        Assert.assertEquals(195, result.length());
109d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver
110e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        // we remove 2 codepoints == 4 characters == 8 bytes, and then add back in the 1-byte '#'
1113b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        result = ClassFileNameHandler.shortenPathComponent(sb.toString(), 7);
1123b5d84c3ae10f803e0281222e05eab31f8c9d2a6Ben Gruver        Assert.assertEquals(400, sb.toString().getBytes(UTF8).length);
113e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        Assert.assertEquals(393, result.getBytes(UTF8).length);
114e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        Assert.assertEquals(197, result.length());
115e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    }
116e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
117e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    @Test
118e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    public void testMultipleLongNames() {
119e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        String filenameFragment = Strings.repeat("a", 512);
120e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
121e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File tempDir = Files.createTempDir();
122e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        ClassFileNameHandler handler = new ClassFileNameHandler(tempDir, ".smali");
123e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
124e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        // put the differentiating character in the middle, where it will get stripped out by the filename shortening
125e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        // logic
126e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File file1 = handler.getUniqueFilenameForClass("La/a/" + filenameFragment  + "1" + filenameFragment + ";");
127e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file1, "a", "a", Strings.repeat("a", 124) + "#" + Strings.repeat("a", 118) + ".smali");
128e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
129e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File file2 = handler.getUniqueFilenameForClass("La/a/" + filenameFragment + "2" + filenameFragment + ";");
130e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file2, "a", "a", Strings.repeat("a", 124) + "#" + Strings.repeat("a", 118) + ".1.smali");
131e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
132e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        Assert.assertFalse(file1.getAbsolutePath().equals(file2.getAbsolutePath()));
133e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    }
134e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
135e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    @Test
136e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    public void testBasicFunctionality() {
137e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File tempDir = Files.createTempDir();
138e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        ClassFileNameHandler handler = new ClassFileNameHandler(tempDir, ".smali");
139e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
140e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File file = handler.getUniqueFilenameForClass("La/b/c/d;");
141e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "c", "d.smali");
142e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
143e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/c/e;");
144e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "c", "e.smali");
145e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
146e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/d/d;");
147e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "d", "d.smali");
148e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
149e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b;");
150e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b.smali");
151e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
152e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("Lb;");
153e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "b.smali");
154e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    }
155e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
156e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    @Test
157e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    public void testCaseInsensitiveFilesystem() {
158e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File tempDir = Files.createTempDir();
159e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        ClassFileNameHandler handler = new ClassFileNameHandler(tempDir, ".smali", false, false);
160e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
161e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File file = handler.getUniqueFilenameForClass("La/b/c;");
162e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "c.smali");
163e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
164e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/C;");
165e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "C.1.smali");
166e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
167e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/B/c;");
168e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "B.1", "c.smali");
169e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    }
170e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
171e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    @Test
172e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    public void testCaseSensitiveFilesystem() {
173e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File tempDir = Files.createTempDir();
174e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        ClassFileNameHandler handler = new ClassFileNameHandler(tempDir, ".smali", true, false);
175e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
176e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File file = handler.getUniqueFilenameForClass("La/b/c;");
177e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "c.smali");
178e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
179e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/C;");
180e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "C.smali");
181e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
182e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/B/c;");
183e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "B", "c.smali");
184e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    }
185e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
186e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    @Test
187e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    public void testWindowsReservedFilenames() {
188e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File tempDir = Files.createTempDir();
189e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        ClassFileNameHandler handler = new ClassFileNameHandler(tempDir, ".smali", false, true);
190e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
191e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File file = handler.getUniqueFilenameForClass("La/con/c;");
192e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "con#", "c.smali");
193e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
194e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/Con/c;");
195e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "Con#.1", "c.smali");
196e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
197e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/PRN;");
198e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "PRN#.smali");
199e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
200e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/prN;");
201e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "prN#.1.smali");
202e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
203e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/com0;");
204e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "com0.smali");
205e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
206e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        for (String reservedName: new String[] {"con", "prn", "aux", "nul", "com1", "com9", "lpt1", "lpt9"}) {
207e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver            file = handler.getUniqueFilenameForClass("L" + reservedName + ";");
208e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver            checkFilename(tempDir, file, reservedName +"#.smali");
209e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        }
210e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    }
211e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
212e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    @Test
213e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    public void testIgnoringWindowsReservedFilenames() {
214e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File tempDir = Files.createTempDir();
215e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        ClassFileNameHandler handler = new ClassFileNameHandler(tempDir, ".smali", true, false);
216e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
217e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        File file = handler.getUniqueFilenameForClass("La/con/c;");
218e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "con", "c.smali");
219e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
220e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/Con/c;");
221e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "Con", "c.smali");
222e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
223e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/PRN;");
224e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "PRN.smali");
225e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
226e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/prN;");
227e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "prN.smali");
228e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
229e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        file = handler.getUniqueFilenameForClass("La/b/com0;");
230e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        checkFilename(tempDir, file, "a", "b", "com0.smali");
231e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
232e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        for (String reservedName: new String[] {"con", "prn", "aux", "nul", "com1", "com9", "lpt1", "lpt9"}) {
233e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver            file = handler.getUniqueFilenameForClass("L" + reservedName + ";");
234e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver            checkFilename(tempDir, file, reservedName +".smali");
235e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        }
236e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    }
237e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver
238e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver    private void checkFilename(File base, File file, String... elements) {
239e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        for (int i=elements.length-1; i>=0; i--) {
240e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver            Assert.assertEquals(elements[i], file.getName());
241e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver            file = file.getParentFile();
242e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        }
243e032f1d8c7e291f3aa42ca05b6dad61a0f3765ccBen Gruver        Assert.assertEquals(base.getAbsolutePath(), file.getAbsolutePath());
244d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver    }
245d868692e33220a20685b8c68a2e01ff8e7f76580Ben Gruver}
246