Skip to content

Instantly share code, notes, and snippets.

@jpcaruana
Forked from pascalpratmarty/DummyProject.scala
Created February 14, 2011 15:44
Show Gist options
  • Save jpcaruana/826050 to your computer and use it in GitHub Desktop.
Save jpcaruana/826050 to your computer and use it in GitHub Desktop.
package org.agitude.fileutils
import java.io.File
import org.apache.commons.io.FileUtils
// Utility object for test purpose only
object DummyProject {
private val TMP_DIR = new File("tmp")
val WEB_PACKAGE = Package("org.agitude.web", "module1")
val COMMONS_PACKAGE = Package("org.agitude.commons", "module1")
val OTHER_WEB_PACKAGE = Package("org.agitude.web", "module2")
def clearProject = FileUtils.deleteDirectory(TMP_DIR)
def checker = JavaDirChecker(TMP_DIR)
case class Package(path: String, module: String) {
require(path matches "[\\.a-z]*")
val declaration = "package " + path + ";"
val dir = new File(TMP_DIR + "/" + module, path replace ('.', '/'))
def addFile(filename: String) = new SomeFile(this, filename)
def addClass(className: String) = new JavaClass(this, className)
}
class SomeFile(aPackage: Package, filename: String) {
aPackage.dir mkdirs
val file = new File(aPackage.dir, filename)
val path = file.getAbsolutePath
}
class JavaClass(aPackage: Package, className: String)
extends SomeFile(aPackage, filename = className + ".java") {
FileUtils.writeStringToFile(file, aPackage.declaration)
val fullName: String = aPackage.path + "." + className
}
}
package org.agitude.fileutils
import java.io.File
import io.Source
import collection.Iterator
import scala.annotation.tailrec
case class JavaDirChecker(directory: File) {
require(directory.isDirectory)
val files: List[File] = listJavaFiles(directory)
val conflicts: List[(String, Set[String])] = extract(files, classPath)
val nameCollisions: List[(String, Set[String])] = extract(files, shortName)
@tailrec
private def extract(list: List[File], description: File => String): List[(String, Set[String])] = {
list match {
case Nil => Nil
case x :: ys => {
val (listX, others) = ys partition (file => description(x) == description(file))
if (listX isEmpty) extract(others, description)
else (description(x), toPaths(x +: listX)) :: extract(others, description)
}
}
}
private def listJavaFiles(f: File): List[File] = {
val these = f.listFiles
val (directories, files) = these partition (_.isDirectory)
(files filter (_.getName endsWith ".java")).toList ++ directories.flatMap(listJavaFiles)
}
private def packageName(file: File): String = {
val source: Source = Source.fromFile(file)
val iterator: Iterator[String] = source getLines() filter (_ matches "package .*;")
if (iterator.isEmpty) throw new Exception("There should be a package definition in Java file " + file.getAbsolutePath)
iterator.next.replaceAll("package (.*);", "$1")
}
private def shortName(file: File): String = file.getName takeWhile ('.' !=)
private def classPath(file: File): String = packageName(file) + "." + shortName(file)
private def toPaths(files: List[File]): Set[String] = files map (file => file.getAbsolutePath) toSet
}
class PrintableResult(result: List[(String, Set[String])]) {
def prettyPrint = {
result foreach (pair => {
println(pair._1)
pair._2 foreach (element => println(" " + element))
})
}
}
object JavaDirChecker {
implicit def toPrintable(result: List[(String, Set[String])]): PrintableResult = new PrintableResult(result)
}
package org.agitude.fileutils
import org.scalatest.{BeforeAndAfterEach, FunSuite}
import DummyProject._
import JavaDirChecker._
class JavaDirCheckerTest extends FunSuite with BeforeAndAfterEach {
override def beforeEach() = clearProject
test("JavaDirChecker returns nothing if no Java File") {
WEB_PACKAGE addFile "Toto.txt"
OTHER_WEB_PACKAGE addFile "Toto.txt"
assert(checker.conflicts isEmpty)
}
test("JavaDirChecker returns nothing if Java classNames do not conflict") {
WEB_PACKAGE addClass "Toto"
COMMONS_PACKAGE addClass "Titi"
assert(checker.conflicts isEmpty)
}
test("JavaDirChecker returns nothing if Java packages do not conflict") {
WEB_PACKAGE addClass "Toto"
COMMONS_PACKAGE addClass "Toto"
assert(checker.conflicts isEmpty)
}
test("JavaDirChecker returns a list of conflicting class names") {
val foo = WEB_PACKAGE addClass "Foo"
val foo2 = OTHER_WEB_PACKAGE addClass "Foo"
val foo3 = COMMONS_PACKAGE addClass "Foo"
val bar = WEB_PACKAGE addClass "Bar"
val bar2 = COMMONS_PACKAGE addClass "Bar"
val gee = WEB_PACKAGE addClass "Gee"
assert(checker.conflicts === List((foo.fullName, Set(foo.path, foo2.path))))
assert(checker.nameCollisions === List(("Bar", Set(bar.path, bar2.path)),
("Foo", Set(foo.path, foo2.path, foo3.path))))
// The icing on the cake : Pretty Printing
println("Pretty Printing Demo ")
println("==> Conflicting class definitions:")
checker.conflicts.prettyPrint
println(" ")
println("==> Short Names collisions:")
checker.nameCollisions.prettyPrint
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment