diff options
author | mpociecha <michal.pociecha@gmail.com> | 2014-11-29 17:41:32 +0100 |
---|---|---|
committer | mpociecha <michal.pociecha@gmail.com> | 2014-11-30 22:31:31 +0100 |
commit | af295c53a9c9bc3d579abd5678aba62210d23ada (patch) | |
tree | 5fc10c80481847f98b8bf2868994bd3cb4421ed3 /test/junit | |
parent | 1545d2aead61e8c85f554d00b58d5a6536d5d5d8 (diff) | |
download | scala-af295c53a9c9bc3d579abd5678aba62210d23ada.tar.gz scala-af295c53a9c9bc3d579abd5678aba62210d23ada.tar.bz2 scala-af295c53a9c9bc3d579abd5678aba62210d23ada.zip |
Add the flat classpath type aggregating flat classpath instances
There's added AggregateFlatClassPath - an equivalent of
MergedClassPath from the old implementation. It is supposed to group
classpath instances handling different files being directories, zips
or jars.
Unlike in the case of the old (recursive) implementation, there won't
be a deep, nested hierarchy of classpath instances - just one root
(aggregate) and a flat structure of its children.
AggregateFlatClassPath ensures the distinction of classpath entries
and merges corresponding entries for class and source files into one
entry. This is required as SymbolLoaders class makes use of this kind
of ClassRepresentation.
There are also added unit tests which check whether
AggregateFlatClassPath obtains correct entries from classpath
instances specified in a constructor and whether it preserves the
ordering in the case of repeated entries. There's added a test type
of flat classpath using VirtualFiles so it's easy to check the real
behaviour.
Diffstat (limited to 'test/junit')
-rw-r--r-- | test/junit/scala/tools/nsc/classpath/AggregateFlatClassPathTest.scala | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/test/junit/scala/tools/nsc/classpath/AggregateFlatClassPathTest.scala b/test/junit/scala/tools/nsc/classpath/AggregateFlatClassPathTest.scala new file mode 100644 index 0000000000..9a004d5e0e --- /dev/null +++ b/test/junit/scala/tools/nsc/classpath/AggregateFlatClassPathTest.scala @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2014 Contributor. All rights reserved. + */ +package scala.tools.nsc.classpath + +import java.net.URL +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import scala.reflect.io.VirtualFile +import scala.tools.nsc.io.AbstractFile + +/** + * Tests whether AggregateFlatClassPath returns correct entries taken from + * cp instances used during creating it and whether it preserves the ordering + * (in the case of the repeated entry for a class or a source it returns the first one). + */ +@RunWith(classOf[JUnit4]) +class AggregateFlatClassPathTest { + + private class TestFlatClassPath extends FlatClassPath { + override def packages(inPackage: String): Seq[PackageEntry] = unsupported + override def sources(inPackage: String): Seq[SourceFileEntry] = unsupported + override def classes(inPackage: String): Seq[ClassFileEntry] = unsupported + + override def list(inPackage: String): FlatClassPathEntries = unsupported + override def findClassFile(name: String): Option[AbstractFile] = unsupported + + override def asClassPathStrings: Seq[String] = unsupported + override def asSourcePathString: String = unsupported + override def asURLs: Seq[URL] = unsupported + } + + private case class TestClassPath(virtualPath: String, classesInPackage: EntryNamesInPackage*) extends TestFlatClassPath { + + override def classes(inPackage: String): Seq[ClassFileEntry] = + for { + entriesWrapper <- classesInPackage if entriesWrapper.inPackage == inPackage + name <- entriesWrapper.names + } yield classFileEntry(virtualPath, inPackage, name) + + override def sources(inPackage: String): Seq[SourceFileEntry] = Nil + + // we'll ignore packages + override def list(inPackage: String): FlatClassPathEntries = FlatClassPathEntries(Nil, classes(inPackage)) + } + + private case class TestSourcePath(virtualPath: String, sourcesInPackage: EntryNamesInPackage*) extends TestFlatClassPath { + + override def sources(inPackage: String): Seq[SourceFileEntry] = + for { + entriesWrapper <- sourcesInPackage if entriesWrapper.inPackage == inPackage + name <- entriesWrapper.names + } yield sourceFileEntry(virtualPath, inPackage, name) + + override def classes(inPackage: String): Seq[ClassFileEntry] = Nil + + // we'll ignore packages + override def list(inPackage: String): FlatClassPathEntries = FlatClassPathEntries(Nil, sources(inPackage)) + } + + private case class EntryNamesInPackage(inPackage: String)(val names: String*) + + private val dir1 = "./dir1" + private val dir2 = "./dir2" + private val dir3 = "./dir3" + private val dir4 = "" + + private val pkg1 = "pkg1" + private val pkg2 = "pkg2" + private val pkg3 = "pkg1.nested" + private val nonexistingPkg = "nonexisting" + + private def unsupported = throw new UnsupportedOperationException + + private def classFileEntry(pathPrefix: String, inPackage: String, fileName: String) = + ClassFileEntryImpl(classFile(pathPrefix, inPackage, fileName)) + + private def sourceFileEntry(pathPrefix: String, inPackage: String, fileName: String) = + SourceFileEntryImpl(sourceFile(pathPrefix, inPackage, fileName)) + + private def classFile(pathPrefix: String, inPackage: String, fileName: String) = + virtualFile(pathPrefix, inPackage, fileName, ".class") + + private def sourceFile(pathPrefix: String, inPackage: String, fileName: String) = + virtualFile(pathPrefix, inPackage, fileName, ".scala") + + private def virtualFile(pathPrefix: String, inPackage: String, fileName: String, extension: String) = { + val packageDirs = + if (inPackage == FlatClassPath.RootPackage) "" + else inPackage.split('.').mkString("/", "/", "") + new VirtualFile(fileName + extension, s"$pathPrefix$packageDirs/$fileName$extension") + } + + private def createDefaultTestClasspath() = { + val partialClassPaths = Seq(TestSourcePath(dir1, EntryNamesInPackage(pkg1)("F", "A", "G")), + TestClassPath(dir2, EntryNamesInPackage(pkg1)("C", "B", "A"), EntryNamesInPackage(pkg2)("D", "A", "E")), + TestClassPath(dir3, EntryNamesInPackage(pkg1)("A", "D", "F")), + TestSourcePath(dir4, EntryNamesInPackage(pkg2)("A", "H", "I"), EntryNamesInPackage(pkg1)("A")), + TestSourcePath(dir2, EntryNamesInPackage(pkg3)("J", "K", "L")) + ) + + AggregateFlatClassPath(partialClassPaths) + } + + @Test + def testGettingPackages: Unit = { + case class ClassPathWithPackages(packagesInPackage: EntryNamesInPackage*) extends TestFlatClassPath { + override def packages(inPackage: String): Seq[PackageEntry] = + packagesInPackage.find(_.inPackage == inPackage).map(_.names).getOrElse(Nil) map PackageEntryImpl + } + + val partialClassPaths = Seq(ClassPathWithPackages(EntryNamesInPackage(pkg1)("pkg1.a", "pkg1.d", "pkg1.f")), + ClassPathWithPackages(EntryNamesInPackage(pkg1)("pkg1.c", "pkg1.b", "pkg1.a"), + EntryNamesInPackage(pkg2)("pkg2.d", "pkg2.a", "pkg2.e")) + ) + val cp = AggregateFlatClassPath(partialClassPaths) + + val packagesInPkg1 = Seq("pkg1.a", "pkg1.d", "pkg1.f", "pkg1.c", "pkg1.b") + assertEquals(packagesInPkg1, cp.packages(pkg1).map(_.name)) + + val packagesInPkg2 = Seq("pkg2.d", "pkg2.a", "pkg2.e") + assertEquals(packagesInPkg2, cp.packages(pkg2).map(_.name)) + + assertEquals(Seq.empty, cp.packages(nonexistingPkg)) + } + + @Test + def testGettingClasses: Unit = { + val cp = createDefaultTestClasspath() + + val classesInPkg1 = Seq(classFileEntry(dir2, pkg1, "C"), + classFileEntry(dir2, pkg1, "B"), + classFileEntry(dir2, pkg1, "A"), + classFileEntry(dir3, pkg1, "D"), + classFileEntry(dir3, pkg1, "F") + ) + assertEquals(classesInPkg1, cp.classes(pkg1)) + + val classesInPkg2 = Seq(classFileEntry(dir2, pkg2, "D"), + classFileEntry(dir2, pkg2, "A"), + classFileEntry(dir2, pkg2, "E") + ) + assertEquals(classesInPkg2, cp.classes(pkg2)) + + assertEquals(Seq.empty, cp.classes(pkg3)) + assertEquals(Seq.empty, cp.classes(nonexistingPkg)) + } + + @Test + def testGettingSources: Unit = { + val partialClassPaths = Seq(TestClassPath(dir1, EntryNamesInPackage(pkg1)("F", "A", "G")), + TestSourcePath(dir2, EntryNamesInPackage(pkg1)("C", "B", "A"), EntryNamesInPackage(pkg2)("D", "A", "E")), + TestSourcePath(dir3, EntryNamesInPackage(pkg1)("A", "D", "F")), + TestClassPath(dir4, EntryNamesInPackage(pkg2)("A", "H", "I")), + TestClassPath(dir2, EntryNamesInPackage(pkg3)("J", "K", "L")) + ) + val cp = AggregateFlatClassPath(partialClassPaths) + + val sourcesInPkg1 = Seq(sourceFileEntry(dir2, pkg1, "C"), + sourceFileEntry(dir2, pkg1, "B"), + sourceFileEntry(dir2, pkg1, "A"), + sourceFileEntry(dir3, pkg1, "D"), + sourceFileEntry(dir3, pkg1, "F") + ) + assertEquals(sourcesInPkg1, cp.sources(pkg1)) + + val sourcesInPkg2 = Seq(sourceFileEntry(dir2, pkg2, "D"), + sourceFileEntry(dir2, pkg2, "A"), + sourceFileEntry(dir2, pkg2, "E") + ) + assertEquals(sourcesInPkg2, cp.sources(pkg2)) + + assertEquals(Seq.empty, cp.sources(pkg3)) + assertEquals(Seq.empty, cp.sources(nonexistingPkg)) + } + + @Test + def testList: Unit = { + val cp = createDefaultTestClasspath() + + val classesAndSourcesInPkg1 = Seq( + ClassAndSourceFilesEntry(classFile(dir3, pkg1, "F"), sourceFile(dir1, pkg1, "F")), + ClassAndSourceFilesEntry(classFile(dir2, pkg1, "A"), sourceFile(dir1, pkg1, "A")), + sourceFileEntry(dir1, pkg1, "G"), + classFileEntry(dir2, pkg1, "C"), + classFileEntry(dir2, pkg1, "B"), + classFileEntry(dir3, pkg1, "D") + ) + assertEquals(classesAndSourcesInPkg1, cp.list(pkg1).classesAndSources) + + assertEquals(FlatClassPathEntries(Nil, Nil), cp.list(nonexistingPkg)) + } + + @Test + def testFindClass: Unit = { + val cp = createDefaultTestClasspath() + + assertEquals( + Some(ClassAndSourceFilesEntry(classFile(dir2, pkg1, "A"), sourceFile(dir1, pkg1, "A"))), + cp.findClass(s"$pkg1.A") + ) + assertEquals(Some(classFileEntry(dir3, pkg1, "D")), cp.findClass(s"$pkg1.D")) + assertEquals(Some(sourceFileEntry(dir2, pkg3, "L")), cp.findClass(s"$pkg3.L")) + assertEquals(None, cp.findClass("Nonexisting")) + } +} |