blob: 2cab0a579cc1859830b4ce1f657789a04f94d665 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.resource.impl;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.Util;
import com.google.gwt.util.tools.Utility;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Tests {@link ResourceOracleImpl}.
*
* <pre>
* Important states to test:
* - No class path entries
* - A single class path entries
* - init/add/update/remove
* - Multiple class path entries
* - init/add/update/remove
* - same as previous with shadowing
* - same as previous with superceding
* </pre>
*/
public class ResourceOracleImplTest extends AbstractResourceOrientedTestBase {
// Starts empty but can change during tests.
private static class MOCK_CPE0 extends MockClassPathEntry {
public MOCK_CPE0() {
super("/cpe0/");
}
}
private static class MOCK_CPE3 extends MockClassPathEntry {
public MOCK_CPE3() {
super("/cpe3/");
}
}
private static class ResourceOracleSnapshot {
private final Set<String> pathNames;
private final Map<String, Resource> resourceMap;
private final Set<Resource> resources;
public ResourceOracleSnapshot(ResourceOracleImpl oracle) {
resources = oracle.getResources();
resourceMap = oracle.getResourceMap();
pathNames = oracle.getPathNames();
}
public void assertCollectionsConsistent(int expectedSize) {
assertEquals(expectedSize, resources.size());
assertEquals(resources.size(), resourceMap.size());
assertEquals(resources.size(), pathNames.size());
// Ensure every resource is in the map correctly.
for (Resource r : resources) {
assertSame(r, resourceMap.get(r.getPath()));
}
// Ensure that every resource path is in the set.
for (Resource r : resources) {
assertTrue(pathNames.contains(r.getPath()));
}
}
public void assertNotSameCollections(ResourceOracleSnapshot other) {
assertNotSame(resourceMap, other.resourceMap);
assertNotSame(resources, other.resources);
assertNotSame(pathNames, other.pathNames);
}
public void assertPathIncluded(String path) {
assertNotNull(findResourceWithPath(path));
}
/**
* Asserts that a resource having the specified path is present and that it
* was contributed by the specified classpath entry.
*/
public void assertPathIncluded(String expectedPath,
ClassPathEntry expectedCpe) {
AbstractResource r = findResourceWithPath(expectedPath);
assertNotNull(r);
ClassPathEntry actualCpe = r.getClassPathEntry();
assertEquals(expectedCpe.getLocation(), actualCpe.getLocation());
}
public void assertPathNotIncluded(String path) {
assertNull(findResourceWithPath(path));
}
public void assertSameCollections(ResourceOracleSnapshot other) {
assertResourcesEqual(resourceMap, other.resourceMap);
assertResourcesEqual(resources, other.resources);
assertEquals(pathNames, other.pathNames);
}
public AbstractResource findResourceWithPath(String path) {
for (Resource r : resources) {
if (r.getPath().equals(path)) {
return (AbstractResource) r;
}
}
return null;
}
@SuppressWarnings("deprecation")
public void assertResourcesGetURL() {
for (Resource resource : resources) {
URL url = resource.getURL();
assertNotNull("Resource " + resource + " had a null getURL()", url);
InputStream is = resource.openContents();
assertNotNull(is);
String urlString = Util.readURLAsString(url);
String inputString = Util.readStreamAsString(is);
assertEquals(urlString, inputString);
assertNotNull(urlString);
assertNotNull(inputString);
}
}
}
public static void assertResourcesEqual(Collection<Resource> expected,
Collection<Resource> actual) {
Set<String> expectedLocs = new HashSet<String>();
for (Resource resource : expected) {
expectedLocs.add(resource.getLocation());
}
Set<String> actualLocs = new HashSet<String>();
for (Resource resource : actual) {
actualLocs.add(resource.getLocation());
}
assertEquals(expectedLocs, actualLocs);
}
public static void assertResourcesEqual(Map<String, Resource> expected,
Map<String, Resource> actual) {
assertResourcesEqual(expected.values(), actual.values());
}
private static PathPrefix makeJavaLangPrefix() {
return new PathPrefix("java/lang/", null, false);
}
private static PathPrefix makeBarPrefix() {
return new PathPrefix("org/example/bar/client/", null, false);
}
private static PathPrefix makeRerootBarPrefix() {
return new PathPrefix("org/example/bar/client/", null, true);
}
private static PathPrefix makeRerootFooPrefix() {
return new PathPrefix("org/example/foo/client/", null, true);
}
private static PathPrefix makeTranslatablePrefix() {
return new PathPrefix("translatable/", null, true);
}
public void testCachingOfJarResources() throws IOException,
URISyntaxException {
TreeLogger logger = createTestTreeLogger();
File jarFile = findFile("com/google/gwt/dev/resource/impl/testdata/cpe1.jar");
ClassPathEntry cpe1jar = ZipFileClassPathEntry.get(jarFile);
// test basic caching
PathPrefixSet pps1 = new PathPrefixSet();
pps1.add(new PathPrefix("com/google/gwt/", null, false));
Map<AbstractResource, PathPrefix> resourceMap1 = cpe1jar.findApplicableResources(
logger, pps1);
assertSame(resourceMap1, cpe1jar.findApplicableResources(logger, pps1));
// test that cache is invalidated if PathPrefixSet is modified.
pps1.add(new PathPrefix("com/google/gwt/user/", null, false));
Map<AbstractResource, PathPrefix> resourceMap2 = cpe1jar.findApplicableResources(
logger, pps1);
assertNotSame(resourceMap1, resourceMap2);
PathPrefixSet pps2 = new PathPrefixSet();
pps2.add(new PathPrefix("org/example/bar/", null, false));
Map<AbstractResource, PathPrefix> resourceMap3 = cpe1jar.findApplicableResources(
logger, pps2);
// check that the entry did go in the cache
assertSame(resourceMap3, cpe1jar.findApplicableResources(logger, pps2));
// check that the cache does not thrash
assertSame(resourceMap2, cpe1jar.findApplicableResources(logger, pps1));
assertSame(resourceMap3, cpe1jar.findApplicableResources(logger, pps2));
}
public void testGetUrlOnResources() throws URISyntaxException, IOException {
ClassPathEntry cpe1jar = getClassPathEntry1AsJar();
ClassPathEntry cpe1dir = getClassPathEntry1AsDirectory();
ClassPathEntry cpe1zip = getClassPathEntry1AsZip();
ClassPathEntry cpe2jar = getClassPathEntry2AsJar();
ClassPathEntry cpe2dir = getClassPathEntry2AsDirectory();
ClassPathEntry cpe2zip = getClassPathEntry2AsZip();
testGetURLOnResourcesInCPE(cpe1jar);
testGetURLOnResourcesInCPE(cpe1dir);
testGetURLOnResourcesInCPE(cpe1zip);
testGetURLOnResourcesInCPE(cpe2jar);
testGetURLOnResourcesInCPE(cpe2dir);
testGetURLOnResourcesInCPE(cpe2zip);
}
private void testGetURLOnResourcesInCPE(ClassPathEntry cpe) {
TreeLogger logger = createTestTreeLogger();
ResourceOracleImpl oracle = createResourceOracle(cpe);
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
s.assertResourcesGetURL();
}
/**
* Test that ResourceOracleImpl preserves the order in which the same logical
* resource is occurs in multiple ClassPathEntries.
*
* @throws URISyntaxException
* @throws IOException
*/
public void testClassPathOrderIsHonored() throws IOException,
URISyntaxException {
TreeLogger logger = createTestTreeLogger();
ClassPathEntry cpe1jar = getClassPathEntry1AsJar();
ClassPathEntry cpe2jar = getClassPathEntry2AsJar();
ClassPathEntry[] cp12 = new ClassPathEntry[]{cpe1jar, cpe2jar};
ClassPathEntry[] cp21 = new ClassPathEntry[]{cpe2jar, cpe1jar};
String resKeyNormal = "org/example/bar/client/BarClient2.txt";
String resKeyReroot = "BarClient2.txt";
testResourceInCPE(logger, resKeyNormal, cpe1jar, cp12, makeBarPrefix());
testResourceInCPE(logger, resKeyReroot, cpe1jar, cp12,
makeRerootBarPrefix());
testResourceInCPE(logger, resKeyNormal, cpe2jar, cp21, makeBarPrefix());
testResourceInCPE(logger, resKeyReroot, cpe2jar, cp21,
makeRerootBarPrefix());
}
public void testNoClassPathEntries() {
TreeLogger logger = createTestTreeLogger();
ResourceOracleImpl oracle = createResourceOracle(new MOCK_CPE0());
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
s.assertCollectionsConsistent(0);
}
/**
* Test that ResourceOracleImpl prefers the order of path prefixes over
* ClassPathEntries.
* <p>
* cpe1 contains org/example/bar/client/BarClient1.txt and cpe2 contains
* org/example/foo/client/BarClient1.txt
*
* @throws URISyntaxException
* @throws IOException
*/
public void testPathPrefixOrderPreferredOverClasspath() throws IOException,
URISyntaxException {
TreeLogger logger = createTestTreeLogger();
ClassPathEntry cpe1jar = getClassPathEntry1AsJar();
ClassPathEntry cpe2jar = getClassPathEntry2AsJar();
ClassPathEntry[] cp12 = new ClassPathEntry[]{cpe1jar, cpe2jar};
ClassPathEntry[] cp21 = new ClassPathEntry[]{cpe2jar, cpe1jar};
String keyReroot = "BarClient1.txt";
// Resource in cpe2 wins because pp2 comes later.
testResourceInCPE(logger, keyReroot, cpe2jar, cp12, makeRerootBarPrefix(),
makeRerootFooPrefix());
// Order of specifying classpath is reversed, it still matches cpe2.
testResourceInCPE(logger, keyReroot, cpe2jar, cp21, makeRerootBarPrefix(),
makeRerootFooPrefix());
// Resource in cpe1 wins because pp1 comes later.
testResourceInCPE(logger, keyReroot, cpe1jar, cp12, makeRerootFooPrefix(),
makeRerootBarPrefix());
// Order of specifying classpath is reversed, it still matches cpe1.
testResourceInCPE(logger, keyReroot, cpe1jar, cp21, makeRerootFooPrefix(),
makeRerootBarPrefix());
}
/**
* Tests the actual reading of resources.
*
* @throws URISyntaxException
* @throws IOException
*/
public void testReadingResource() throws IOException, URISyntaxException {
ClassPathEntry cpe1jar = getClassPathEntry1AsJar();
ClassPathEntry cpe1dir = getClassPathEntry1AsDirectory();
ClassPathEntry cpe1zip = getClassPathEntry1AsZip();
ClassPathEntry cpe2jar = getClassPathEntry2AsJar();
ClassPathEntry cpe2dir = getClassPathEntry2AsDirectory();
ClassPathEntry cpe2zip = getClassPathEntry2AsZip();
testReadingResource(cpe1jar, cpe2jar);
testReadingResource(cpe1dir, cpe2jar);
testReadingResource(cpe1zip, cpe2jar);
testReadingResource(cpe1jar, cpe2dir);
testReadingResource(cpe1dir, cpe2dir);
testReadingResource(cpe1zip, cpe2dir);
testReadingResource(cpe1jar, cpe2zip);
testReadingResource(cpe1dir, cpe2zip);
testReadingResource(cpe1zip, cpe2zip);
}
/**
* Verify that duplicate entries are removed from the classpath, and that
* multiple ResourceOracleImpls created from the same classloader return the
* same list of ClassPathEntries.
*
* @throws MalformedURLException
*/
public void testRemoveDuplicates() {
TreeLogger logger = createTestTreeLogger();
URL cpe1 = findUrl("com/google/gwt/dev/resource/impl/testdata/cpe1.jar");
URL cpe2 = findUrl("com/google/gwt/dev/resource/impl/testdata/cpe2.zip");
URLClassLoader classLoader = new URLClassLoader(new URL[]{
cpe1, cpe2, cpe2, cpe1, cpe2,}, null);
ResourceOracleImpl oracle = new ResourceOracleImpl(logger, classLoader);
List<ClassPathEntry> classPath = oracle.getClassPath();
assertEquals(2, classPath.size());
assertJarEntry(classPath.get(0), "cpe1.jar");
assertJarEntry(classPath.get(1), "cpe2.zip");
oracle = new ResourceOracleImpl(logger, classLoader);
List<ClassPathEntry> classPath2 = oracle.getClassPath();
assertEquals(2, classPath2.size());
for (int i = 0; i < 2; ++i) {
assertSame(classPath.get(i), classPath2.get(i));
}
}
public void testResourceAddition() throws IOException, URISyntaxException {
ClassPathEntry cpe1mock = getClassPathEntry1AsMock();
ClassPathEntry cpe1jar = getClassPathEntry1AsJar();
ClassPathEntry cpe1dir = getClassPathEntry1AsDirectory();
ClassPathEntry cpe1zip = getClassPathEntry1AsZip();
ClassPathEntry cpe2mock = getClassPathEntry2AsMock();
ClassPathEntry cpe2jar = getClassPathEntry2AsJar();
ClassPathEntry cpe2dir = getClassPathEntry2AsDirectory();
ClassPathEntry cpe2zip = getClassPathEntry2AsZip();
testResourceAddition(cpe1jar, cpe2jar);
testResourceAddition(cpe1dir, cpe2jar);
testResourceAddition(cpe1mock, cpe2jar);
testResourceAddition(cpe1zip, cpe2jar);
testResourceAddition(cpe1jar, cpe2dir);
testResourceAddition(cpe1dir, cpe2dir);
testResourceAddition(cpe1mock, cpe2dir);
testResourceAddition(cpe1zip, cpe2dir);
testResourceAddition(cpe1jar, cpe2mock);
testResourceAddition(cpe1dir, cpe2mock);
testResourceAddition(cpe1mock, cpe2mock);
testResourceAddition(cpe1zip, cpe2mock);
testResourceAddition(cpe1jar, cpe2zip);
testResourceAddition(cpe1dir, cpe2zip);
testResourceAddition(cpe1mock, cpe2zip);
testResourceAddition(cpe1zip, cpe2zip);
}
public void testResourceDeletion() throws IOException, URISyntaxException {
ClassPathEntry cpe1mock = getClassPathEntry1AsMock();
ClassPathEntry cpe1jar = getClassPathEntry1AsJar();
ClassPathEntry cpe1dir = getClassPathEntry1AsDirectory();
ClassPathEntry cpe1zip = getClassPathEntry1AsZip();
ClassPathEntry cpe2mock = getClassPathEntry2AsMock();
ClassPathEntry cpe2jar = getClassPathEntry2AsJar();
ClassPathEntry cpe2dir = getClassPathEntry2AsDirectory();
ClassPathEntry cpe2zip = getClassPathEntry2AsZip();
testResourceDeletion(cpe1jar, cpe2jar);
testResourceDeletion(cpe1dir, cpe2jar);
testResourceDeletion(cpe1mock, cpe2jar);
testResourceDeletion(cpe1zip, cpe2jar);
testResourceDeletion(cpe1jar, cpe2dir);
testResourceDeletion(cpe1dir, cpe2dir);
testResourceDeletion(cpe1mock, cpe2dir);
testResourceDeletion(cpe1zip, cpe2dir);
testResourceDeletion(cpe1jar, cpe2mock);
testResourceDeletion(cpe1dir, cpe2mock);
testResourceDeletion(cpe1mock, cpe2mock);
testResourceDeletion(cpe1zip, cpe2mock);
testResourceDeletion(cpe1jar, cpe2zip);
testResourceDeletion(cpe1dir, cpe2zip);
testResourceDeletion(cpe1mock, cpe2zip);
testResourceDeletion(cpe1zip, cpe2zip);
}
public void testResourceModification() throws IOException, URISyntaxException {
ClassPathEntry cpe1mock = getClassPathEntry1AsMock();
ClassPathEntry cpe1jar = getClassPathEntry1AsJar();
ClassPathEntry cpe1dir = getClassPathEntry1AsDirectory();
ClassPathEntry cpe1zip = getClassPathEntry1AsZip();
ClassPathEntry cpe2mock = getClassPathEntry2AsMock();
ClassPathEntry cpe2jar = getClassPathEntry2AsJar();
ClassPathEntry cpe2dir = getClassPathEntry2AsDirectory();
ClassPathEntry cpe2zip = getClassPathEntry2AsZip();
testResourceModification(cpe1jar, cpe2jar);
testResourceModification(cpe1dir, cpe2jar);
testResourceModification(cpe1mock, cpe2jar);
testResourceModification(cpe1zip, cpe2jar);
testResourceModification(cpe1jar, cpe2dir);
testResourceModification(cpe1dir, cpe2dir);
testResourceModification(cpe1mock, cpe2dir);
testResourceModification(cpe1zip, cpe2dir);
testResourceModification(cpe1jar, cpe2mock);
testResourceModification(cpe1dir, cpe2mock);
testResourceModification(cpe1mock, cpe2mock);
testResourceModification(cpe1zip, cpe2mock);
testResourceModification(cpe1jar, cpe2zip);
testResourceModification(cpe1dir, cpe2zip);
testResourceModification(cpe1mock, cpe2zip);
testResourceModification(cpe1zip, cpe2zip);
/*
* TODO(bruce): figure out a good way to test real resource modifications of
* jar files and directories
*/
}
/**
* Ensure refresh is stable when multiple classpaths + multiple path prefixes
* all include the same resource.
*/
public void testStableRefreshOnBlot() {
TreeLogger logger = createTestTreeLogger();
ClassPathEntry cpe1 = getClassPathEntry1AsMock();
ClassPathEntry cpe2 = getClassPathEntry2AsMock();
testResourceInCPE(logger, "org/example/bar/client/BarClient2.txt", cpe1,
new ClassPathEntry[]{cpe1, cpe2}, makeBarPrefix(), new PathPrefix(
"org/example/bar/", null, false));
}
/**
* Ensure refresh is stable when multiple classpaths + multiple path prefixes
* all include the same resource.
*/
public void testSuperSourceSupercedesSource() {
TreeLogger logger = createTestTreeLogger();
MockClassPathEntry cpe1 = new MockClassPathEntry("/cpe1/");
cpe1.addResource("java/lang/Object.java");
MockClassPathEntry cpe2 = new MockClassPathEntry("/cpe2/");
cpe2.addResource("translatable/java/lang/Object.java");
// Ensure the translatable overrides the basic despite swapping CPE order.
testResourceInCPE(logger, "java/lang/Object.java", cpe2,
new ClassPathEntry[]{cpe1, cpe2}, makeJavaLangPrefix(),
makeTranslatablePrefix());
testResourceInCPE(logger, "java/lang/Object.java", cpe2,
new ClassPathEntry[]{cpe2, cpe1}, makeJavaLangPrefix(),
makeTranslatablePrefix());
// Ensure the translatable overrides the basic despite swapping PPS order.
testResourceInCPE(logger, "java/lang/Object.java", cpe2,
new ClassPathEntry[]{cpe1, cpe2}, makeTranslatablePrefix(),
makeJavaLangPrefix());
testResourceInCPE(logger, "java/lang/Object.java", cpe2,
new ClassPathEntry[]{cpe2, cpe1}, makeTranslatablePrefix(),
makeJavaLangPrefix());
}
private void assertJarEntry(ClassPathEntry classPathEntry, String expected) {
assertTrue("Should be instance of ZipFileClassPathEntry",
classPathEntry instanceof ZipFileClassPathEntry);
ZipFileClassPathEntry zipCPE = (ZipFileClassPathEntry) classPathEntry;
String jar = zipCPE.getLocation();
assertTrue("URL should contain " + expected, jar.contains(expected));
}
/**
* Creates an array of class path entries, setting up each one with a
* well-known set of client prefixes.
*/
private ResourceOracleImpl createResourceOracle(ClassPathEntry... entries) {
PathPrefixSet pps = new PathPrefixSet();
pps.add(new PathPrefix("com/google/gwt/user/client/", null));
pps.add(new PathPrefix("org/example/bar/client/", null));
pps.add(new PathPrefix("org/example/foo/client/", null));
pps.add(new PathPrefix("com/google/gwt/i18n/client/", null));
List<ClassPathEntry> classPath = new ArrayList<ClassPathEntry>();
for (ClassPathEntry entry : entries) {
classPath.add(entry);
}
ResourceOracleImpl oracle = new ResourceOracleImpl(classPath);
oracle.setPathPrefixes(pps);
return oracle;
}
private ResourceOracleSnapshot refreshAndSnapshot(TreeLogger logger,
ResourceOracleImpl oracle) {
ResourceOracleImpl.refresh(logger, oracle);
ResourceOracleSnapshot snapshot1 = new ResourceOracleSnapshot(oracle);
ResourceOracleImpl.refresh(logger, oracle);
ResourceOracleSnapshot snapshot2 = new ResourceOracleSnapshot(oracle);
snapshot1.assertSameCollections(snapshot2);
return snapshot1;
}
private void testReadingResource(ClassPathEntry cpe1, ClassPathEntry cpe2)
throws IOException {
TreeLogger logger = createTestTreeLogger();
ResourceOracleImpl oracle = createResourceOracle(cpe1, cpe2);
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
s.assertCollectionsConsistent(10);
s.assertPathIncluded("com/google/gwt/user/client/Command.java", cpe1);
s.assertPathIncluded("com/google/gwt/i18n/client/Messages.java", cpe2);
{
/*
* Read a resource in cpe1.
*/
AbstractResource res = s.findResourceWithPath("com/google/gwt/user/client/Command.java");
BufferedReader rdr = null;
try {
InputStream is = res.openContents();
assertNotNull(is);
rdr = new BufferedReader(new InputStreamReader(is));
assertTrue(rdr.readLine().indexOf(
"package com.google.gwt.dev.resource.impl.testdata.cpe1.com.google.gwt.user.client;") >= 0);
} finally {
Utility.close(rdr);
}
}
{
/*
* Read a resource in cpe2.
*/
AbstractResource res = s.findResourceWithPath("com/google/gwt/i18n/client/Messages.java");
BufferedReader rdr = null;
try {
InputStream is = res.openContents();
assertNotNull(is);
rdr = new BufferedReader(new InputStreamReader(is));
assertTrue(rdr.readLine().indexOf(
"package com.google.gwt.dev.resource.impl.testdata.cpe2.com.google.gwt.i18n.client;") >= 0);
} finally {
Utility.close(rdr);
}
}
{
/*
* TODO: Try to read an invalid resource and watch it fail as intended.
*/
}
}
private void testResourceAddition(ClassPathEntry cpe1, ClassPathEntry cpe2) {
TreeLogger logger = createTestTreeLogger();
MOCK_CPE0 cpe0 = new MOCK_CPE0();
MOCK_CPE3 cpe3 = new MOCK_CPE3();
ResourceOracleImpl oracle = createResourceOracle(cpe0, cpe1, cpe2, cpe3);
{
/*
* Ensure it's correct as a baseline. These tests have hard-coded
* assumptions about the contents of each classpath entry.
*/
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
s.assertCollectionsConsistent(10);
s.assertPathIncluded("com/google/gwt/user/client/Command.java");
s.assertPathIncluded("com/google/gwt/user/client/Timer.java");
s.assertPathIncluded("com/google/gwt/user/client/ui/Widget.java");
s.assertPathIncluded("org/example/bar/client/BarClient1.txt");
s.assertPathIncluded("org/example/bar/client/BarClient2.txt");
s.assertPathIncluded("org/example/bar/client/BarClient3.txt");
s.assertPathIncluded("org/example/bar/client/etc/BarEtc.txt");
s.assertPathIncluded("org/example/foo/client/FooClient.java");
s.assertPathIncluded("com/google/gwt/i18n/client/Messages.java");
}
{
/*
* Add duplicate resources later in the classpath, which won't be found.
* Consequently, the collections' identities should not change.
*/
cpe3.addResource("com/google/gwt/user/client/Command.java");
cpe3.addResource("com/google/gwt/user/client/Timer.java");
cpe3.addResource("com/google/gwt/bar/client/etc/BarEtc.txt");
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
after.assertCollectionsConsistent(10);
after.assertSameCollections(before);
}
{
/*
* Add a unique resource later in the classpath, which will be found.
* Consequently, the collections' identities should change.
*/
cpe3.addResource("com/google/gwt/i18n/client/Constants.java");
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
after.assertCollectionsConsistent(11);
after.assertNotSameCollections(before);
after.assertPathIncluded("com/google/gwt/i18n/client/Constants.java");
}
}
private void testResourceDeletion(ClassPathEntry cpe1, ClassPathEntry cpe2) {
TreeLogger logger = createTestTreeLogger();
MOCK_CPE0 cpe0 = new MOCK_CPE0();
MOCK_CPE3 cpe3 = new MOCK_CPE3();
ResourceOracleImpl oracle = createResourceOracle(cpe0, cpe1, cpe2, cpe3);
/*
* Intentionally add some duplicate resources.
*/
cpe0.addResource("com/google/gwt/user/client/Command.java");
cpe0.addResource("com/google/gwt/i18n/client/Constants.java");
cpe3.addResource("com/google/gwt/user/client/Command.java");
cpe3.addResource("com/google/gwt/i18n/client/Constants.java");
{
/*
* Ensure it's correct as a baseline. These tests have hard-coded
* assumptions about the contents of each classpath entry.
*/
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
s.assertCollectionsConsistent(11);
s.assertPathIncluded("com/google/gwt/user/client/Command.java");
s.assertPathIncluded("com/google/gwt/user/client/Timer.java");
s.assertPathIncluded("com/google/gwt/user/client/ui/Widget.java");
s.assertPathIncluded("org/example/bar/client/BarClient1.txt");
s.assertPathIncluded("org/example/bar/client/BarClient2.txt");
s.assertPathIncluded("org/example/bar/client/BarClient3.txt");
s.assertPathIncluded("org/example/bar/client/etc/BarEtc.txt");
s.assertPathIncluded("org/example/foo/client/FooClient.java");
s.assertPathIncluded("com/google/gwt/i18n/client/Messages.java");
s.assertPathIncluded("com/google/gwt/i18n/client/Constants.java");
}
{
/*
* Remove a shadowed resource, which shouldn't have been found anyway.
* Consequently, the collections' identities should not change.
*/
cpe3.removeResource("com/google/gwt/user/client/Command.java");
cpe3.removeResource("com/google/gwt/i18n/client/Constants.java");
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
after.assertCollectionsConsistent(11);
after.assertSameCollections(before);
}
{
/*
* Remove a unique resource, which will no longer be found. We also add a
* new one to ensure that lack of size change doesn't confuse anything.
* Consequently, the collections' identities should change.
*/
cpe0.removeResource("com/google/gwt/i18n/client/Constants.java");
cpe3.addResource("com/google/gwt/user/client/Window.java");
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
after.assertCollectionsConsistent(11);
after.assertNotSameCollections(before);
after.assertPathIncluded("com/google/gwt/user/client/Window.java");
after.assertPathNotIncluded("com/google/gwt/i18n/client/Constants.java");
}
}
private void testResourceInCPE(TreeLogger logger, String resourceKey,
ClassPathEntry expectedCPE, ClassPathEntry[] classPath,
PathPrefix... pathPrefixes) {
ResourceOracleImpl oracle = new ResourceOracleImpl(Arrays.asList(classPath));
PathPrefixSet pps = new PathPrefixSet();
for (PathPrefix pathPrefix : pathPrefixes) {
pps.add(pathPrefix);
}
oracle.setPathPrefixes(pps);
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
s.assertPathIncluded(resourceKey, expectedCPE);
}
private void testResourceModification(ClassPathEntry cpe1, ClassPathEntry cpe2) {
TreeLogger logger = createTestTreeLogger();
MOCK_CPE0 cpe0 = new MOCK_CPE0();
MOCK_CPE3 cpe3 = new MOCK_CPE3();
ResourceOracleImpl oracle = createResourceOracle(cpe0, cpe1, cpe2, cpe3);
{
/*
* Baseline assumptions about the set of resources present by default.
*/
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
s.assertPathIncluded("com/google/gwt/user/client/Command.java", cpe1);
s.assertPathIncluded("com/google/gwt/user/client/Timer.java", cpe1);
}
// Add intentionally duplicate resources.
cpe0.addResource("com/google/gwt/user/client/Command.java");
cpe3.addResource("com/google/gwt/user/client/Timer.java");
{
/*
* Ensure that the dups have the effect we expect.
*/
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
s.assertPathIncluded("com/google/gwt/user/client/Command.java", cpe0);
s.assertPathIncluded("com/google/gwt/user/client/Timer.java", cpe1);
}
{
/*
* Change a mock resource that was shadowed to ensure that the change
* isn't observed.
*/
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
before.assertCollectionsConsistent(10);
cpe3.updateResource("com/google/gwt/user/client/Timer.java");
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
after.assertSameCollections(before);
}
{
/*
* Change a mock resource that was not shadowed to ensure that the change
* is observed.
*/
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
before.assertCollectionsConsistent(10);
cpe0.updateResource("com/google/gwt/user/client/Command.java");
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
after.assertNotSameCollections(before);
}
}
}