1/*
2 * Copyright (C) 2008 The Guava Authors
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.google.common.io;
18
19import static com.google.common.base.CharMatcher.WHITESPACE;
20import static com.google.common.truth.Truth.assertThat;
21
22import com.google.common.base.Charsets;
23import com.google.common.collect.ImmutableList;
24import com.google.common.testing.NullPointerTester;
25
26import junit.framework.TestSuite;
27
28import java.io.ByteArrayInputStream;
29import java.io.ByteArrayOutputStream;
30import java.io.DataInputStream;
31import java.io.File;
32import java.io.IOException;
33import java.io.PrintWriter;
34import java.net.URL;
35import java.net.URLClassLoader;
36import java.util.ArrayList;
37import java.util.List;
38
39/**
40 * Unit test for {@link Resources}.
41 *
42 * @author Chris Nokleberg
43 */
44public class ResourcesTest extends IoTestCase {
45
46  public static TestSuite suite() {
47    TestSuite suite = new TestSuite();
48    suite.addTest(ByteSourceTester.tests("Resources.asByteSource[URL]",
49        SourceSinkFactories.urlByteSourceFactory(), true));
50    suite.addTest(CharSourceTester.tests("Resources.asCharSource[URL, Charset]",
51        SourceSinkFactories.urlCharSourceFactory()));
52    suite.addTestSuite(ResourcesTest.class);
53    return suite;
54  }
55
56  public void testToString() throws IOException {
57    URL resource = getClass().getResource("testdata/i18n.txt");
58    assertEquals(I18N, Resources.toString(resource, Charsets.UTF_8));
59    assertThat(Resources.toString(resource, Charsets.US_ASCII))
60        .isNotEqualTo(I18N);
61  }
62
63  public void testToToByteArray() throws IOException {
64    byte[] data = Resources.toByteArray(classfile(Resources.class));
65    assertEquals(0xCAFEBABE,
66        new DataInputStream(new ByteArrayInputStream(data)).readInt());
67  }
68
69  public void testReadLines() throws IOException {
70    // TODO(chrisn): Check in a better resource
71    URL resource = getClass().getResource("testdata/i18n.txt");
72    assertEquals(ImmutableList.of(I18N),
73        Resources.readLines(resource, Charsets.UTF_8));
74  }
75
76  public void testReadLines_withLineProcessor() throws IOException {
77    URL resource = getClass().getResource("testdata/alice_in_wonderland.txt");
78    LineProcessor<List<String>> collectAndLowercaseAndTrim =
79        new LineProcessor<List<String>>() {
80          List<String> collector = new ArrayList<String>();
81          @Override
82          public boolean processLine(String line) {
83            collector.add(WHITESPACE.trimFrom(line));
84            return true;
85          }
86
87          @Override
88          public List<String> getResult() {
89            return collector;
90          }
91        };
92    List<String> result = Resources.readLines(resource, Charsets.US_ASCII,
93        collectAndLowercaseAndTrim);
94    assertEquals(3600, result.size());
95    assertEquals("ALICE'S ADVENTURES IN WONDERLAND", result.get(0));
96    assertEquals("THE END", result.get(result.size() - 1));
97  }
98
99  public void testCopyToOutputStream() throws IOException {
100    ByteArrayOutputStream out = new ByteArrayOutputStream();
101    URL resource = getClass().getResource("testdata/i18n.txt");
102    Resources.copy(resource, out);
103    assertEquals(I18N, out.toString("UTF-8"));
104  }
105
106  public void testGetResource_notFound() {
107    try {
108      Resources.getResource("no such resource");
109      fail();
110    } catch (IllegalArgumentException e) {
111      assertEquals("resource no such resource not found.", e.getMessage());
112    }
113  }
114
115  public void testGetResource() {
116    assertNotNull(
117        Resources.getResource("com/google/common/io/testdata/i18n.txt"));
118  }
119
120  public void testGetResource_relativePath_notFound() {
121    try {
122      Resources.getResource(
123          getClass(), "com/google/common/io/testdata/i18n.txt");
124      fail();
125    } catch (IllegalArgumentException e) {
126      assertEquals("resource com/google/common/io/testdata/i18n.txt" +
127          " relative to com.google.common.io.ResourcesTest not found.",
128          e.getMessage());
129    }
130  }
131
132  public void testGetResource_relativePath() {
133    assertNotNull(Resources.getResource(getClass(), "testdata/i18n.txt"));
134  }
135
136  public void testGetResource_contextClassLoader() throws IOException {
137    // Check that we can find a resource if it is visible to the context class
138    // loader, even if it is not visible to the loader of the Resources class.
139
140    File tempFile = createTempFile();
141    PrintWriter writer = new PrintWriter(tempFile, "UTF-8");
142    writer.println("rud a chur ar an méar fhada");
143    writer.close();
144
145    // First check that we can't find it without setting the context loader.
146    // This is a sanity check that the test doesn't spuriously pass because
147    // the resource is visible to the system class loader.
148    try {
149      Resources.getResource(tempFile.getName());
150      fail("Should get IllegalArgumentException");
151    } catch (IllegalArgumentException expected) {
152    }
153
154    // Now set the context loader to one that should find the resource.
155    URL baseUrl = tempFile.getParentFile().toURI().toURL();
156    URLClassLoader loader = new URLClassLoader(new URL[] {baseUrl});
157    ClassLoader oldContextLoader =
158        Thread.currentThread().getContextClassLoader();
159    try {
160      Thread.currentThread().setContextClassLoader(loader);
161      URL url = Resources.getResource(tempFile.getName());
162      String text = Resources.toString(url, Charsets.UTF_8);
163      assertEquals("rud a chur ar an méar fhada\n", text);
164    } finally {
165      Thread.currentThread().setContextClassLoader(oldContextLoader);
166    }
167  }
168
169  public void testGetResource_contextClassLoaderNull() {
170    ClassLoader oldContextLoader =
171        Thread.currentThread().getContextClassLoader();
172    try {
173      Thread.currentThread().setContextClassLoader(null);
174      assertNotNull(
175          Resources.getResource("com/google/common/io/testdata/i18n.txt"));
176      try {
177        Resources.getResource("no such resource");
178        fail("Should get IllegalArgumentException");
179      } catch (IllegalArgumentException expected) {
180      }
181    } finally {
182      Thread.currentThread().setContextClassLoader(oldContextLoader);
183    }
184  }
185
186  public void testNulls() {
187    new NullPointerTester()
188        .setDefault(URL.class, classfile(ResourcesTest.class))
189        .testAllPublicStaticMethods(Resources.class);
190  }
191
192  private static URL classfile(Class<?> c) {
193    return c.getResource(c.getSimpleName() + ".class");
194  }
195}
196