From 21f36eece84ae5b61eaf66e75fbe7b02dcb466ed Mon Sep 17 00:00:00 2001 From: "Nadav Sr. Samet" Date: Sat, 17 Jan 2015 18:29:29 -0800 Subject: [PATCH] Added property-based tests for options. Addresses #8. --- proptest/src/test/scala/GraphGen.scala | 16 +++++++++++++- proptest/src/test/scala/Nodes.scala | 21 ++++++++++++++++--- .../src/test/scala/SchemaGenerators.scala | 14 ++++++------- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/proptest/src/test/scala/GraphGen.scala b/proptest/src/test/scala/GraphGen.scala index 08f5687a2..d03e9b95b 100644 --- a/proptest/src/test/scala/GraphGen.scala +++ b/proptest/src/test/scala/GraphGen.scala @@ -1,4 +1,5 @@ import GenUtils._ +import com.trueaccord.scalapb.Scalapb.ScalaPbOptions import org.scalacheck.Gen object GraphGen { @@ -112,6 +113,18 @@ object GraphGen { state.currentFileId), state.closeNamespace) } + def genScalaOptions(state: State): Gen[(Option[ScalaPbOptions], State)] = for { + (scalaPackageName, state) <- GenUtils.listWithStatefulGen(state, minSize = 1, maxSize = 4)(_.generateName) + flatPackage <- Gen.oneOf(true, false) + } yield { + val b = ScalaPbOptions.newBuilder + if (scalaPackageName.nonEmpty) { + b.setPackageName(scalaPackageName.mkString(".")) + } + b.setFlatPackage(flatPackage) + (Some(b.build), state) + } + def genFileNode(state: State): Gen[(FileNode, State)] = sized { s => for { @@ -121,9 +134,10 @@ object GraphGen { javaPackageOption = if (javaPackage.nonEmpty) Some(javaPackage) else None (protoPackage, state) <- Gen.oneOf(state.generateSubspace, Gen.const(("", state))) protoPackageOption = if (protoPackage.nonEmpty) Some(protoPackage) else None + (scalaOptions, state) <- Gen.oneOf[(Option[ScalaPbOptions], State)](genScalaOptions(state), (None, state)) (messages, state) <- listWithStatefulGen(state, maxSize = 4)(genMessageNode(0, None)) (enums, state) <- listWithStatefulGen(state, maxSize = 3)(genEnumNode(None)) - } yield (FileNode(baseName, protoPackageOption, javaPackageOption, messages, enums, fileId), + } yield (FileNode(baseName, protoPackageOption, javaPackageOption, scalaOptions, messages, enums, fileId), if (protoPackage.isEmpty) state else state.closeNamespace) } diff --git a/proptest/src/test/scala/Nodes.scala b/proptest/src/test/scala/Nodes.scala index 4b5cc8986..f1764076d 100644 --- a/proptest/src/test/scala/Nodes.scala +++ b/proptest/src/test/scala/Nodes.scala @@ -1,4 +1,5 @@ +import com.trueaccord.scalapb.Scalapb.ScalaPbOptions import com.trueaccord.scalapb.compiler import com.trueaccord.scalapb.compiler.{FunctionalPrinter, FPrintable} @@ -84,6 +85,7 @@ object Nodes { case class FileNode(baseFileName: String, protoPackage: Option[String], javaPackage: Option[String], + scalaOptions: Option[ScalaPbOptions], messages: Seq[MessageNode], enums: Seq[EnumNode], fileId: Int) extends Node { @@ -108,7 +110,15 @@ object Nodes { val p0 = printer.add(s"// File id $fileId. messages: $minMessageId-$maxMessageId. Enums: $minEnumId-$maxEnumId") val p1 = protoPackage.fold(p0)(pkg => p0.add(s"package $pkg;")) val p2 = javaPackage.fold(p1)(pkg => p1.add(s"""option java_package = "$pkg";""")) - p2.add(fileReferences(rootNode).collect({ + val p3 = scalaOptions.fold(p2)(options => + p2.add("""import "scalapb.proto";""") + .add("option (scalapb.options) = {") + .indent + .when(options.hasPackageName)(_.add(s"""package_name: "${options.getPackageName}"""")) + .add(s"flat_package: ${options.getFlatPackage}") + .outdent + .add("};")) + p3.add(fileReferences(rootNode).collect({ case f if f != baseFileName => s"""import "${f}.proto";""" }).toSeq: _*) .printAll(enums) @@ -118,8 +128,13 @@ object Nodes { def javaOuterClass = (javaPackage.orElse(protoPackage).toSeq :+ snakeCaseToCamelCase(baseFileName, upperInitial = true)) mkString "." def scalaPackage = { - javaPackage.orElse(protoPackage).fold(baseFileName)(_ + "." + baseFileName) - } + val scalaPackageName = scalaOptions.flatMap(options => + if (options.hasPackageName) Some(options.getPackageName) else None) + val requestedPackageName = scalaPackageName.orElse(javaPackage).orElse(protoPackage) + val flatPackage = scalaOptions.exists(_.getFlatPackage) + if (flatPackage) requestedPackageName.getOrElse("") + else requestedPackageName.fold(baseFileName)(_ + "." + baseFileName) + } } case class MessageNode(id: Int, diff --git a/proptest/src/test/scala/SchemaGenerators.scala b/proptest/src/test/scala/SchemaGenerators.scala index 8147de025..d78ba9a08 100644 --- a/proptest/src/test/scala/SchemaGenerators.scala +++ b/proptest/src/test/scala/SchemaGenerators.scala @@ -3,12 +3,9 @@ import java.net.{URL, URLClassLoader} import java.nio.file.Files import javax.tools.ToolProvider -import com.google.protobuf import com.google.protobuf.Message.Builder -import com.google.protobuf.{MessageOrBuilder, TextFormat} import com.trueaccord.scalapb.compiler.FunctionalPrinter -import org.scalacheck.Prop.{forAll, forAllNoShrink} -import org.scalacheck.{Gen, Properties} +import org.scalacheck.Gen import com.trueaccord.scalapb._ import scala.reflect.ClassTag @@ -98,7 +95,7 @@ object SchemaGenerators { file.getAbsolutePath } val args = Seq("--proto_path", - tmpDir.toString, + (tmpDir.toString + ":vendor:protobuf"), "--java_out", tmpDir.toString, "--scala_out", "java_conversions:" + tmpDir.toString) ++ files compiler.Process.runProtoc(args: _*) @@ -113,7 +110,9 @@ object SchemaGenerators { def compileJavaInDir(rootDir: File): Unit = { println("Compiling Java sources.") - val protobufJar = jarForClass[com.google.protobuf.Message].getPath + val protobufJar = Seq( + jarForClass[com.google.protobuf.Message].getPath, + jarForClass[com.trueaccord.scalapb.Scalapb].getPath) val compiler = ToolProvider.getSystemJavaCompiler() getFileTree(rootDir) @@ -122,7 +121,7 @@ object SchemaGenerators { file => if (compiler.run(null, null, null, "-sourcepath", rootDir.toString, - "-cp", protobufJar, + "-cp", protobufJar.mkString(":"), "-d", rootDir.toString, file.getAbsolutePath) != 0) { throw new RuntimeException(s"Compilation of $file failed.") @@ -135,6 +134,7 @@ object SchemaGenerators { val classPath = Seq( jarForClass[annotation.Annotation].getPath, jarForClass[com.trueaccord.scalapb.GeneratedMessage].getPath, + jarForClass[com.trueaccord.scalapb.Scalapb].getPath, jarForClass[com.google.protobuf.Message].getPath, jarForClass[com.trueaccord.lenses.Lens[_, _]].getPath, rootDir