diff --git a/demos/scrooge-maven-demo/src/test/scala/com/twitter/example/DemoSpec.scala b/demos/scrooge-maven-demo/src/test/scala/com/twitter/example/DemoSpec.scala index 2efaab71f..793a821ce 100644 --- a/demos/scrooge-maven-demo/src/test/scala/com/twitter/example/DemoSpec.scala +++ b/demos/scrooge-maven-demo/src/test/scala/com/twitter/example/DemoSpec.scala @@ -9,7 +9,7 @@ import org.scalatest.{MustMatchers, WordSpec} @RunWith(classOf[JUnitRunner]) class DemoSpec extends WordSpec with MustMatchers { - def printUser(user: User) {println("User %s, id %d".format(user.name, user.id))} + def printUser(user: User) { println("User %s, id %d".format(user.name, user.id)) } def await[A](f: Future[A]): A = Await.result(f, 5.seconds) @@ -22,4 +22,3 @@ class DemoSpec extends WordSpec with MustMatchers { } } } - diff --git a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptASMPruner.scala b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptASMPruner.scala index 085f6b9e7..403c79e34 100644 --- a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptASMPruner.scala +++ b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptASMPruner.scala @@ -55,7 +55,7 @@ private[adapt] object AdaptAsmPruner { def isUnusedField(fieldName: String): Boolean = useMap.get(fieldName) match { case Some(used) => !used - case None => false + case None => false } // Get rid of unused field members @@ -139,7 +139,7 @@ private[adapt] object AdaptAsmPruner { insn match { case f: FieldInsnNode => f.owner == "com/twitter/scrooge/adapt/AdaptTProtocol$" && - f.name == "MODULE$" + f.name == "MODULE$" case _ => false } @@ -217,16 +217,20 @@ private[adapt] object AdaptAsmPruner { case Opcodes.ICONST_4 => 4 case Opcodes.ICONST_5 => 5 case Opcodes.ICONST_M1 => -1 - case _ => throw new IllegalStateException( - s"Unexpected opcode ${i.getOpcode} while trying to read fieldId") + case _ => + throw new IllegalStateException( + s"Unexpected opcode ${i.getOpcode} while trying to read fieldId" + ) } case i: IntInsnNode => i.getOpcode match { case Opcodes.BIPUSH => i.operand.toShort case Opcodes.SIPUSH => i.operand.toShort } - case _ => throw new IllegalStateException( - s"Unexpected instruction $insn while trying to read fieldId") + case _ => + throw new IllegalStateException( + s"Unexpected instruction $insn while trying to read fieldId" + ) } /** @@ -277,6 +281,7 @@ private[adapt] object AdaptAsmPruner { ): Unit = { val iter = di.iterator while (iter.hasNext) { + /** * Each field has sections in the template for when it is used or unused. * Based on whether the field is used we keep corresponding section and @@ -287,8 +292,8 @@ private[adapt] object AdaptAsmPruner { case Some(fieldId) => deleteMarkedSection(iter, UsedEnd, !useMap(fieldId)) case _ => - // Note we don't move the iterator forward here to check below - // if this is an unused marker. + // Note we don't move the iterator forward here to check below + // if this is an unused marker. } // Read the marker for unused section readMarker(iter, UnusedStart) match { @@ -349,4 +354,3 @@ private[adapt] object AdaptAsmPruner { classWriter.toByteArray } } - diff --git a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptBinaryThriftStructSerializer.scala b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptBinaryThriftStructSerializer.scala index 49c7349c3..9aa55e2a3 100644 --- a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptBinaryThriftStructSerializer.scala +++ b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptBinaryThriftStructSerializer.scala @@ -1,6 +1,11 @@ package com.twitter.scrooge.adapt -import com.twitter.scrooge.{TArrayByteTransport, ThriftStruct, ThriftStructCodec, ThriftStructSerializer} +import com.twitter.scrooge.{ + TArrayByteTransport, + ThriftStruct, + ThriftStructCodec, + ThriftStructSerializer +} import java.util import org.apache.thrift.protocol.{TBinaryProtocol, TProtocolFactory} @@ -30,6 +35,7 @@ object AdaptBinaryThriftStructSerializer { * Thread local cache protocol for a setting. */ private def cachedProtocol(settings: AdaptSettings): ProtocolAndTransport = { + /** * The protocol is mutable but this is threadsafe because we have a * separate copy for each thread. This way we reuse the underlying @@ -61,9 +67,9 @@ object AdaptBinaryThriftStructSerializer { * @see [[AdaptTProtocol]] */ private[this] class AdaptBinaryThriftStructSerializer[T <: ThriftStruct]( - val codec: ThriftStructCodec[T], - settings: AdaptSettings) - extends ThriftStructSerializer[T] { + val codec: ThriftStructCodec[T], + settings: AdaptSettings + ) extends ThriftStructSerializer[T] { // Since we only support the fast path reading from the TArrayByteTransport // we provide the default if someone hits it to be the TBinaryProtocol @@ -84,5 +90,3 @@ object AdaptBinaryThriftStructSerializer { } } } - - diff --git a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptTrackingDecoder.scala b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptTrackingDecoder.scala index 741c02178..a702e4bb6 100644 --- a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptTrackingDecoder.scala +++ b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptTrackingDecoder.scala @@ -28,17 +28,20 @@ private[adapt] object AdaptTrackingDecoder { * at runtime. */ private[adapt] class AdaptTrackingDecoder[T <: ThriftStruct]( - codec: ThriftStructCodec[T], - fallbackDecoder: Decoder[T], - accessRecordingDecoderBuilder: AccessRecorder => Decoder[T], - settings: AdaptSettings, - classLoader: AdaptClassLoader) - extends AccessRecorder with Decoder[T] { + codec: ThriftStructCodec[T], + fallbackDecoder: Decoder[T], + accessRecordingDecoderBuilder: AccessRecorder => Decoder[T], + settings: AdaptSettings, + classLoader: AdaptClassLoader +) extends AccessRecorder + with Decoder[T] { import AdaptTrackingDecoder._ private[this] val trackedCount = new AtomicInteger() private[this] val fieldAccessCounts: Map[Short, AtomicInteger] = - codec.metaData.fields.map { f => (f.id, new AtomicInteger(0)) }.toMap + codec.metaData.fields.map { f => + (f.id, new AtomicInteger(0)) + }.toMap def fieldAccessed(fieldId: Short): Unit = fieldAccessCounts(fieldId).getAndIncrement() @@ -53,9 +56,10 @@ private[adapt] class AdaptTrackingDecoder[T <: ThriftStruct]( (f, fieldAccessCounts(f.id).get >= settings.useThreshold) }.toMap - val useMapByName = useMapByField.map { case (f, v) => - val normalizedName = CaseConverter.toCamelCase(f.name) - (normalizedName, v) + val useMapByName = useMapByField.map { + case (f, v) => + val normalizedName = CaseConverter.toCamelCase(f.name) + (normalizedName, v) } val useMapById = useMapByField.map { case (f, v) => (f.id, v) } @@ -83,12 +87,10 @@ private[adapt] class AdaptTrackingDecoder[T <: ThriftStruct]( val adaptDecoderClassBytes = AdaptAsmPruner.pruneAdaptDecoder(adaptDecoderFqdn, useMapById) - val decoderClass = classLoader.defineClass( - adaptDecoderFqdn, adaptDecoderClassBytes) + val decoderClass = classLoader.defineClass(adaptDecoderFqdn, adaptDecoderClassBytes) val prunedDecoder = decoderClass.newInstance() - val decodeMethod = decoderClass.getMethod(DecodeMethodName, - classOf[AdaptTProtocol]) + val decodeMethod = decoderClass.getMethod(DecodeMethodName, classOf[AdaptTProtocol]) new Decoder[T] { def apply(prot: AdaptTProtocol): T = { @@ -107,6 +109,7 @@ private[adapt] class AdaptTrackingDecoder[T <: ThriftStruct]( if (adaptiveDecoder != null) { adaptiveDecoder(prot) } else { + /** * Note that we only block one event, one that makes trackedCount * reach settings.trackedReads, to build the decoder. Subsequent @@ -123,4 +126,3 @@ private[adapt] class AdaptTrackingDecoder[T <: ThriftStruct]( } } } - diff --git a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/CaseConverter.scala b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/CaseConverter.scala index abccfa3de..428f84797 100644 --- a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/CaseConverter.scala +++ b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/CaseConverter.scala @@ -6,6 +6,7 @@ import scala.collection.mutable * Taken from scrooge/scrooge-generator/src/main/scala/com/twitter/scrooge/AST/Identifier.scala */ object CaseConverter { + /** * convert string to camel case, with the following fine print: * - leading underscores are preserved @@ -34,13 +35,15 @@ object CaseConverter { .split('_') .filterNot(_.isEmpty) .zipWithIndex - .map { case (part, ind) => - val first = if (ind == 0) part(0).toLower else part(0).toUpper - val isAllUpperCase = part.forall { c => c.isUpper || !c.isLetter } - val rest = if (isAllUpperCase) part.drop(1).toLowerCase else part.drop(1) - new mutable.StringBuilder(part.size).append(first).append(rest) + .map { + case (part, ind) => + val first = if (ind == 0) part(0).toLower else part(0).toUpper + val isAllUpperCase = part.forall { c => + c.isUpper || !c.isLetter + } + val rest = if (isAllUpperCase) part.drop(1).toLowerCase else part.drop(1) + new mutable.StringBuilder(part.size).append(first).append(rest) } .mkString } } - diff --git a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/TAdaptBinaryProtocol.scala b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/TAdaptBinaryProtocol.scala index fde3dd1aa..6db67212c 100644 --- a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/TAdaptBinaryProtocol.scala +++ b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/TAdaptBinaryProtocol.scala @@ -28,9 +28,10 @@ object TAdaptBinaryProtocol { * trait to learn more. */ class TAdaptBinaryProtocol( - transport: TArrayByteTransport, - context: AdaptContext -) extends TLazyBinaryProtocol(transport) with AdaptTProtocol { + transport: TArrayByteTransport, + context: AdaptContext +) extends TLazyBinaryProtocol(transport) + with AdaptTProtocol { import TAdaptBinaryProtocol._ def adaptContext: AdaptContext = context diff --git a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/TrackingAdaptContext.scala b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/TrackingAdaptContext.scala index a24b01f3a..c8b5debfa 100644 --- a/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/TrackingAdaptContext.scala +++ b/scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/TrackingAdaptContext.scala @@ -22,11 +22,11 @@ class TrackingAdaptContext(settings: AdaptSettings) extends AdaptContext { fallbackDecoder, accessRecordingDecoderBuilder, settings, - adaptClassLoader) + adaptClassLoader + ) } def shouldReloadDecoder: Boolean = false def initCopy(): AdaptContext = new TrackingAdaptContext(settings) } - diff --git a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/AdaptiveScroogeTest.scala b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/AdaptiveScroogeTest.scala index 9d162f00e..b8f5e0999 100644 --- a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/AdaptiveScroogeTest.scala +++ b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/AdaptiveScroogeTest.scala @@ -1,7 +1,16 @@ package com.twitter.scrooge.adapt -import com.twitter.scrooge.{BinaryThriftStructSerializer, LazyBinaryThriftStructSerializer, ThriftStruct, ThriftStructCodec, ThriftStructSerializer} -import com.twitter.scrooge.adapt.testutil.{BinaryThriftFieldRemover, ReloadOnceAdaptBinarySerializer} +import com.twitter.scrooge.{ + BinaryThriftStructSerializer, + LazyBinaryThriftStructSerializer, + ThriftStruct, + ThriftStructCodec, + ThriftStructSerializer +} +import com.twitter.scrooge.adapt.testutil.{ + BinaryThriftFieldRemover, + ReloadOnceAdaptBinarySerializer +} import com.twitter.scrooge.adapt.thrift._ import org.apache.thrift.protocol.{TProtocolException, TType} import org.junit.runner.RunWith @@ -32,11 +41,15 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { */ val BlankStructBytes = Array[Byte](TType.STOP) - val NoAccess: Accessor[Any] = Accessor("No access") { _ => () } + val NoAccess: Accessor[Any] = Accessor("No access") { _ => + () + } object TestStructAccessors { val RequiredFieldAccess: Accessor[TestStruct] = - Accessor("Required field") { t => t.boolField } + Accessor("Required field") { t => + t.boolField + } val RequiredFieldsAccess: Accessor[TestStruct] = Accessor("Required fields") { t => @@ -83,7 +96,8 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { OptionalReservedWordFieldAccess, OptionalWithDefaultFieldAccess, NegativeFieldAccess, - UnderscoreFieldsAccess) + UnderscoreFieldsAccess + ) } object TestNestedStructAccessors { @@ -103,16 +117,15 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { RequiredFieldAccess, OptionalFieldAccess, ReservedWordFieldAccess, - OptionalReservedWordFieldAccess) + OptionalReservedWordFieldAccess + ) } - def useAccessPropTestStruct( - use: TestStruct => Any)( + def useAccessPropTestStruct(use: TestStruct => Any)( access: TestStruct => Any ) = useAccessProp(TestStruct, use)(access) - def useAccessPropTestNestedStruct( - use: TestNestedStruct => Any)( + def useAccessPropTestNestedStruct(use: TestNestedStruct => Any)( access: TestNestedStruct => Any ) = useAccessProp(TestNestedStruct, use)(access) @@ -125,9 +138,8 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { // Make sure materialization happens val trackedReads = 1 val useThreshold = 1 - val adaptSer = ReloadOnceAdaptBinarySerializer( - thriftCodec, - AdaptSettings(trackedReads, useThreshold)) + val adaptSer = + ReloadOnceAdaptBinarySerializer(thriftCodec, AdaptSettings(trackedReads, useThreshold)) val bytes = eagerSer.toBytes(orig) for (_ <- 0 until trackedReads) { @@ -200,13 +212,13 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { t: T, codec: ThriftStructCodec[T] ): Seq[String] = - getFieldsWithMethodPrefix(t, codec, AdaptAsmPruner.SetterPrefix) + getFieldsWithMethodPrefix(t, codec, AdaptAsmPruner.SetterPrefix) def getFieldsWithDelegates[T <: ThriftStruct]( t: T, codec: ThriftStructCodec[T] ): Seq[String] = - getFieldsWithMethodPrefix(t, codec, AdaptAsmPruner.DelegatePrefix) + getFieldsWithMethodPrefix(t, codec, AdaptAsmPruner.DelegatePrefix) def encodeDecode[T <: ThriftStruct]( t: T, @@ -232,12 +244,13 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { def adaptSer: ThriftStructSerializer[T] def bytes: Array[Byte] def recorder: T - def adapted : T + def adapted: T } def fixture[T <: ThriftStruct]( t: T, - codec: ThriftStructCodec[T], train: T => Any = NoAccess + codec: ThriftStructCodec[T], + train: T => Any = NoAccess ) = new Fixture[T] { val eagerSer = BinaryThriftStructSerializer(codec) val bytes = eagerSer.toBytes(t) @@ -286,8 +299,10 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property("Parsing required field not set should throw exception even when " + - "required field is unused") { + property( + "Parsing required field not set should throw exception even when " + + "required field is unused" + ) { check { forAll { t: TestRequiredField => val f = fixture(t, TestRequiredField) @@ -298,8 +313,10 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property("Parsing required field not set should throw exception even when " + - "required field is used") { + property( + "Parsing required field not set should throw exception even when " + + "required field is used" + ) { check { forAll { t: TestRequiredField => val f = fixture[TestRequiredField](t, TestRequiredField, _.requiredField) @@ -310,8 +327,10 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property(s"$RemainUnchangedSerDe when trained with optional field used but " + - s"not set in incoming event") { + property( + s"$RemainUnchangedSerDe when trained with optional field used but " + + s"not set in incoming event" + ) { check { forAll { (t: TestStruct) => val f = testStructFixture(t, _.optionalField) @@ -320,8 +339,10 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property("Adapt generated object should be able to write using other " + - "protocols when no field in adapt materialized") { + property( + "Adapt generated object should be able to write using other " + + "protocols when no field in adapt materialized" + ) { check { forAll { t: TestStruct => protocolDecodeTest(t, NoAccess) @@ -329,8 +350,10 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property("Adapt generated object should be able to write using other " + - "protocols when some fields in adapt materialized") { + property( + "Adapt generated object should be able to write using other " + + "protocols when some fields in adapt materialized" + ) { check { forAll { t: TestStruct => protocolDecodeTest(t, TestStructAccessors.RequiredFieldsAccess) @@ -347,8 +370,10 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property("Calling write on the struct should not result in fields being " + - "considered accessed") { + property( + "Calling write on the struct should not result in fields being " + + "considered accessed" + ) { check { forAll { t: TestRequiredField => val f = fixture[TestRequiredField](t, TestRequiredField) @@ -418,8 +443,7 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } } - */ - + */ property("Eager scrooge nested in Adaptive scrooge should encode decode fine") { check { @@ -480,8 +504,10 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property("Adapt serializer should pick up the default value when present " + - "for optional values, when optional field is used") { + property( + "Adapt serializer should pick up the default value when present " + + "for optional values, when optional field is used" + ) { check { forAll { t: TestStruct => val before = t.copy(optionalFieldWithDefaultValue = "test") @@ -498,8 +524,10 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property("Adapt serializer should pick up the default value when present " + - "for optional values, when optional field is not used") { + property( + "Adapt serializer should pick up the default value when present " + + "for optional values, when optional field is not used" + ) { check { forAll { t: TestStruct => val before = t.copy(optionalFieldWithDefaultValue = "test") @@ -514,9 +542,11 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } - property("Adapt serializer should throw TProtocolException when required " + - "field not present, even if default value is specified for it in the " + - "thrift definition") { + property( + "Adapt serializer should throw TProtocolException when required " + + "field not present, even if default value is specified for it in the " + + "thrift definition" + ) { check { forAll { t: TestRequiredDefaultsStruct => val before = t.copy(stringField = "test") @@ -541,4 +571,3 @@ class AdaptiveScroogeTest extends PropSpec with Checkers { } } } - diff --git a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/BinaryThriftFieldRemoverTest.scala b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/BinaryThriftFieldRemoverTest.scala index eee2a7732..2f079b9ac 100644 --- a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/BinaryThriftFieldRemoverTest.scala +++ b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/BinaryThriftFieldRemoverTest.scala @@ -29,7 +29,9 @@ class BinaryThriftFieldRemoverTest extends PropSpec with Checkers { } } - property("Field remove should remove optional field with default value correctly, so it's set to default value") { + property( + "Field remove should remove optional field with default value correctly, so it's set to default value" + ) { check { forAll { t: TestStruct => val before = t.copy(optionalFieldWithDefaultValue = "test") @@ -51,4 +53,3 @@ class BinaryThriftFieldRemoverTest extends PropSpec with Checkers { } } - diff --git a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/Par.scala b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/Par.scala index 4d58875f5..42364db86 100644 --- a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/Par.scala +++ b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/Par.scala @@ -5,6 +5,7 @@ import java.util.concurrent.atomic.AtomicReferenceArray import scala.reflect.ClassTag object Par { + /** * Run f in parallel, on many threads. * All threads are blocked until just before running f and let go diff --git a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/package.scala b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/package.scala index fa8744dc5..853d5b1a2 100644 --- a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/package.scala +++ b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/package.scala @@ -32,7 +32,7 @@ package object adapt { setField <- arbitrary[Set[Boolean]] mapField <- arbitrary[Map[Boolean, Boolean]] annotatedId <- arbitrary[Long] - tpe <- arbitrary[String] + tpe <- arbitrary[String] klass <- arbitrary[Option[String]] optionalField2 <- arbitrary[Option[String]] optionalFieldWithDefaultValue <- arbitrary[String] @@ -61,7 +61,7 @@ package object adapt { negativeField, snakeCase, endOffset - ) + ) } implicit val testNestedStructArbitrary: Arbitrary[TestNestedStruct] = Arbitrary { @@ -97,12 +97,13 @@ package object adapt { } yield TestDefaultsStruct(boolField, shortField, intField) } - implicit val testOptionalFieldNoDefaultArbitrary: Arbitrary[TestOptionalFieldNoDefault] = Arbitrary { - for { - boolField <- arbitrary[Boolean] - intField <- arbitrary[Option[Int]] - } yield TestOptionalFieldNoDefault(boolField, intField) - } + implicit val testOptionalFieldNoDefaultArbitrary: Arbitrary[TestOptionalFieldNoDefault] = + Arbitrary { + for { + boolField <- arbitrary[Boolean] + intField <- arbitrary[Option[Int]] + } yield TestOptionalFieldNoDefault(boolField, intField) + } implicit val testRequiredFieldArbitrary: Arbitrary[TestRequiredField] = Arbitrary { for { @@ -117,12 +118,13 @@ package object adapt { } yield TestPassthroughFields(field) } - implicit val testRequiredDefaultsStructArbitrary: Arbitrary[TestRequiredDefaultsStruct] = Arbitrary { - for { - stringField <- arbitrary[String] - listField <- arbitrary[Seq[String]] - } yield TestRequiredDefaultsStruct(stringField, listField) - } + implicit val testRequiredDefaultsStructArbitrary: Arbitrary[TestRequiredDefaultsStruct] = + Arbitrary { + for { + stringField <- arbitrary[String] + listField <- arbitrary[Seq[String]] + } yield TestRequiredDefaultsStruct(stringField, listField) + } implicit val testStructUnionArbitrary: Arbitrary[TestStructUnion] = Arbitrary { for { @@ -132,4 +134,3 @@ package object adapt { } yield union } } - diff --git a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/BinaryThriftFieldRemover.scala b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/BinaryThriftFieldRemover.scala index 41d8b25e6..296155fed 100644 --- a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/BinaryThriftFieldRemover.scala +++ b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/BinaryThriftFieldRemover.scala @@ -85,7 +85,7 @@ object BinaryThriftFieldRemover { pos + size + I32Bytes } - private[this] def skipValue(tpe: Byte, ba:Array[Byte], pos: Int): Int = + private[this] def skipValue(tpe: Byte, ba: Array[Byte], pos: Int): Int = tpe match { case TType.STRUCT => skipStruct(ba, pos) case TType.I64 => pos + I64Bytes diff --git a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/ReloadOnceAdaptBinarySerializer.scala b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/ReloadOnceAdaptBinarySerializer.scala index 60c745f20..e67da1906 100644 --- a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/ReloadOnceAdaptBinarySerializer.scala +++ b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/ReloadOnceAdaptBinarySerializer.scala @@ -1,10 +1,16 @@ package com.twitter.scrooge.adapt.testutil import com.twitter.scrooge.adapt.{AdaptSettings, TAdaptBinaryProtocol, TrackingAdaptContext} -import com.twitter.scrooge.{TArrayByteTransport, ThriftStruct, ThriftStructCodec, ThriftStructSerializer} +import com.twitter.scrooge.{ + TArrayByteTransport, + ThriftStruct, + ThriftStructCodec, + ThriftStructSerializer +} import org.apache.thrift.protocol.{TBinaryProtocol, TProtocolFactory} object ReloadOnceAdaptBinarySerializer { + /** * Build an Adaptive binary thrift serializer that triggers decoder reload the * first time it's used. @@ -13,17 +19,16 @@ object ReloadOnceAdaptBinarySerializer { */ def apply[T <: ThriftStruct]( codec: ThriftStructCodec[T], - settings: AdaptSettings = AdaptSettings(1,1) + settings: AdaptSettings = AdaptSettings(1, 1) ): ThriftStructSerializer[T] = new ReloadOnceAdaptBinarySerializer[T](codec, settings) private[this] class ReloadOnceAdaptBinarySerializer[T <: ThriftStruct]( - val codec: ThriftStructCodec[T], - settings: AdaptSettings) - extends ThriftStructSerializer[T] { + val codec: ThriftStructCodec[T], + settings: AdaptSettings + ) extends ThriftStructSerializer[T] { - private[this] val adaptContext = new ReloadOnceAdaptContext( - new TrackingAdaptContext(settings)) + private[this] val adaptContext = new ReloadOnceAdaptContext(new TrackingAdaptContext(settings)) val protocolFactory: TProtocolFactory = new TBinaryProtocol.Factory @@ -43,5 +48,3 @@ object ReloadOnceAdaptBinarySerializer { } } } - - diff --git a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/ReloadOnceAdaptContext.scala b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/ReloadOnceAdaptContext.scala index b827ef79b..40c6f35f4 100644 --- a/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/ReloadOnceAdaptContext.scala +++ b/scrooge-adaptive/src/test/scala/com/twitter/scrooge/adapt/testutil/ReloadOnceAdaptContext.scala @@ -4,7 +4,6 @@ import com.twitter.scrooge.adapt.{AccessRecorder, AdaptContext, Decoder} import com.twitter.scrooge.{ThriftStruct, ThriftStructCodec} import java.util.concurrent.atomic.AtomicBoolean - /** * Wraps an adapt context to provide reload once behavior i.e. it when * shouldReloadDecoder is called the first time then and only then true is @@ -18,10 +17,7 @@ class ReloadOnceAdaptContext(underlying: AdaptContext) extends AdaptContext { codec: ThriftStructCodec[T], fallbackDecoder: Decoder[T], accessRecordingDecoderBuilder: AccessRecorder => Decoder[T] - ): Decoder[T] = underlying.buildDecoder( - codec, - fallbackDecoder, - accessRecordingDecoderBuilder) + ): Decoder[T] = underlying.buildDecoder(codec, fallbackDecoder, accessRecordingDecoderBuilder) def shouldReloadDecoder: Boolean = if (reloaded.get()) false diff --git a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/AirlineGenerator.scala b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/AirlineGenerator.scala index d666dab3b..93bc17f52 100644 --- a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/AirlineGenerator.scala +++ b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/AirlineGenerator.scala @@ -21,11 +21,14 @@ object AirlineGenerator { } def buildFlights(rng: Random, num: Int): Set[Flight] = - (0 until num).map{ _ => buildFlight(rng) }.toSet + (0 until num).map { _ => + buildFlight(rng) + }.toSet def buildRoutes(rng: Random, num: Int): Map[Airport, Airport] = - (0 until num).map{ _ => (buildAirport(rng), buildAirport(rng)) }.toMap - + (0 until num).map { _ => + (buildAirport(rng), buildAirport(rng)) + }.toMap def buildAirline(rng: Random): Airline = { val name = rng.nextString(AvgStringSize) @@ -34,17 +37,13 @@ object AirlineGenerator { val airports = buildAirports(rng, NumAirports).toSet val routes = buildRoutes(rng, NumRoutes) val flights = buildFlights(rng, NumFlights) - Airline( - name, - Some(headQuarter), - Some(owner), - Some(airports), - Some(routes), - Some(flights)) + Airline(name, Some(headQuarter), Some(owner), Some(airports), Some(routes), Some(flights)) } private[this] def buildAirlines(rng: Random, num: Int): Array[Airline] = - (0 until num).map{ _ => buildAirline(rng) }.toArray + (0 until num).map { _ => + buildAirline(rng) + }.toArray def buildAirlinesAndBytes( seed: Long, diff --git a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/AirportGenerator.scala b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/AirportGenerator.scala index d3eff0032..9b5426463 100644 --- a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/AirportGenerator.scala +++ b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/AirportGenerator.scala @@ -7,8 +7,8 @@ import thrift.benchmark._ object AirportGenerator { def buildLocation(rng: Random): Location = { - // Next double is only between 0 and 1, so times long will give us something - // across a wide possible range + // Next double is only between 0 and 1, so times long will give us something + // across a wide possible range val lat = rng.nextDouble * rng.nextLong val lon = rng.nextDouble * rng.nextLong @@ -16,7 +16,6 @@ object AirportGenerator { Location(lat, lon, alt) } - def buildAirport(rng: Random): Airport = { val code = rng.nextString(4) val name = rng.nextString(30) @@ -28,7 +27,9 @@ object AirportGenerator { } def buildAirports(rng: Random, num: Int): Array[Airport] = - (0 until num).map{ _ => buildAirport(rng) }.toArray + (0 until num).map { _ => + buildAirport(rng) + }.toArray def buildAirportsAndBytes(seed: Long, num: Int): (Array[Airport], Array[Array[Byte]]) = { val rng = new Random(seed) diff --git a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/Collections.scala b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/Collections.scala index 435e21402..5c12a74e0 100644 --- a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/Collections.scala +++ b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/Collections.scala @@ -4,7 +4,7 @@ import com.twitter.scrooge.ThriftStructCodec import java.io.ByteArrayOutputStream import java.util.concurrent.TimeUnit import java.util.Random -import org.apache.thrift.protocol.{ TProtocol, TBinaryProtocol } +import org.apache.thrift.protocol.{TProtocol, TBinaryProtocol} import org.apache.thrift.transport.TTransport import org.openjdk.jmh.annotations._ import thrift.benchmark._ diff --git a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/LazyTProtocol.scala b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/LazyTProtocol.scala index b55ce1f24..9ed25bd71 100644 --- a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/LazyTProtocol.scala +++ b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/LazyTProtocol.scala @@ -41,7 +41,6 @@ case class ThreadUnsafeLazyBinaryProtocol[T <: ThriftStruct](codec: ThriftStruct } } - object LazyTProtocolBenchmark { // Pass in a seed and fixed number of airports. // Will be initialized with this object so separate from the benchmarks. @@ -87,11 +86,35 @@ object LazyTProtocolBenchmark { @Setup(Level.Trial) def setup(): Unit = { - require(airportBytes.forall { b => binaryThriftStructSerializer.fromBytes(b) == statelessLazySerializer.fromBytes(b) } , "Deserializers do not agree, benchmarks pointless") - require(airports.forall { b => ByteBuffer.wrap(binaryThriftStructSerializer.toBytes(b)) == ByteBuffer.wrap(statelessLazySerializer.toBytes(b)) } , "Stateful vs normal Serializers do not agree, benchmarks pointless") - - require(airportBytes.forall { b => binaryThriftStructSerializer.fromBytes(b) == statefulLazySerializer.fromBytes(b) } , "Stateful Deserializers do not agree, benchmarks pointless") - require(airports.forall { b => ByteBuffer.wrap(binaryThriftStructSerializer.toBytes(b)) == ByteBuffer.wrap(statefulLazySerializer.toBytes(b)) } , "Stateful Serializers do not agree, benchmarks pointless") + require( + airportBytes.forall { b => + binaryThriftStructSerializer.fromBytes(b) == statelessLazySerializer.fromBytes(b) + }, + "Deserializers do not agree, benchmarks pointless" + ) + require( + airports.forall { b => + ByteBuffer.wrap(binaryThriftStructSerializer.toBytes(b)) == ByteBuffer.wrap( + statelessLazySerializer.toBytes(b) + ) + }, + "Stateful vs normal Serializers do not agree, benchmarks pointless" + ) + + require( + airportBytes.forall { b => + binaryThriftStructSerializer.fromBytes(b) == statefulLazySerializer.fromBytes(b) + }, + "Stateful Deserializers do not agree, benchmarks pointless" + ) + require( + airports.forall { b => + ByteBuffer.wrap(binaryThriftStructSerializer.toBytes(b)) == ByteBuffer.wrap( + statefulLazySerializer.toBytes(b) + ) + }, + "Stateful Serializers do not agree, benchmarks pointless" + ) } } @@ -122,13 +145,18 @@ class LazyTProtocolBenchmark { @Benchmark def timeReferenceFromBytesReadAllFields(state: AirportState, bh: Blackhole): Blackhole = { - airportBytes.map(state.binaryThriftStructSerializer.fromBytes).foreach(a => readAllFields(bh, a)) + airportBytes + .map(state.binaryThriftStructSerializer.fromBytes) + .foreach(a => readAllFields(bh, a)) bh } @Benchmark def timeReferenceRTBytes(state: AirportState): Seq[Array[Byte]] = { - airportBytes.map(b => state.binaryThriftStructSerializer.toBytes(state.binaryThriftStructSerializer.fromBytes(b))) + airportBytes.map( + b => + state.binaryThriftStructSerializer.toBytes(state.binaryThriftStructSerializer.fromBytes(b)) + ) } // ========= Stateless benchmarks ========= @@ -137,8 +165,6 @@ class LazyTProtocolBenchmark { def timeStatelessToBytes(state: AirportState): Seq[Array[Byte]] = { airports.map(state.statelessLazySerializer.toBytes) } - - @Benchmark def timeStatelessFromBytes(state: AirportState): Seq[Airport] = { airportBytes.map(state.statelessLazySerializer.fromBytes) @@ -158,7 +184,9 @@ class LazyTProtocolBenchmark { @Benchmark def timeStatelessRTBytes(state: AirportState): Seq[Array[Byte]] = { - airportBytes.map(b => state.statelessLazySerializer.toBytes(state.statelessLazySerializer.fromBytes(b))) + airportBytes.map( + b => state.statelessLazySerializer.toBytes(state.statelessLazySerializer.fromBytes(b)) + ) } // ========= Stateful benchmarks ========= @@ -167,8 +195,6 @@ class LazyTProtocolBenchmark { def timeStatefulToBytes(state: AirportState): Seq[Array[Byte]] = { airports.map(state.statefulLazySerializer.toBytes) } - - @Benchmark def timeStatefulFromBytes(state: AirportState): Seq[Airport] = { airportBytes.map(state.statefulLazySerializer.fromBytes) @@ -180,7 +206,7 @@ class LazyTProtocolBenchmark { bh } - @Benchmark + @Benchmark def timeStatefulFromBytesReadlAllFields(state: AirportState, bh: Blackhole): Blackhole = { airportBytes.map(state.statefulLazySerializer.fromBytes).foreach(a => readAllFields(bh, a)) bh @@ -188,37 +214,62 @@ class LazyTProtocolBenchmark { @Benchmark def timeStatefulRTBytes(state: AirportState): Seq[Array[Byte]] = { - airportBytes.map(b => state.statefulLazySerializer.toBytes(state.statefulLazySerializer.fromBytes(b))) + airportBytes.map( + b => state.statefulLazySerializer.toBytes(state.statefulLazySerializer.fromBytes(b)) + ) } - // ========= Using the thread state, no built in thread safety ========= + // ========= Using the thread state, no built in thread safety ========= @Benchmark - def timeThreadUnsafeToBytes(state: AirportState, threadState: AirportThreadState): Seq[Array[Byte]] = { + def timeThreadUnsafeToBytes( + state: AirportState, + threadState: AirportThreadState + ): Seq[Array[Byte]] = { airports.map(threadState.threadUnsafeLazySerializer.toBytes) } - - @Benchmark - def timeThreadUnsafeFromBytes(state: AirportState, threadState: AirportThreadState): Seq[Airport] = { + def timeThreadUnsafeFromBytes( + state: AirportState, + threadState: AirportThreadState + ): Seq[Airport] = { airportBytes.map(threadState.threadUnsafeLazySerializer.fromBytes) } @Benchmark - def timeThreadUnsafeFromBytesRead3Fields(state: AirportState, threadState: AirportThreadState, bh: Blackhole): Blackhole = { - airportBytes.map(threadState.threadUnsafeLazySerializer.fromBytes).foreach(a => read3Fields(bh, a)) + def timeThreadUnsafeFromBytesRead3Fields( + state: AirportState, + threadState: AirportThreadState, + bh: Blackhole + ): Blackhole = { + airportBytes + .map(threadState.threadUnsafeLazySerializer.fromBytes) + .foreach(a => read3Fields(bh, a)) bh } - @Benchmark - def timeThreadUnsafeFromBytesReadlAllFields(state: AirportState, threadState: AirportThreadState, bh: Blackhole): Blackhole = { - airportBytes.map(threadState.threadUnsafeLazySerializer.fromBytes).foreach(a => readAllFields(bh, a)) + @Benchmark + def timeThreadUnsafeFromBytesReadlAllFields( + state: AirportState, + threadState: AirportThreadState, + bh: Blackhole + ): Blackhole = { + airportBytes + .map(threadState.threadUnsafeLazySerializer.fromBytes) + .foreach(a => readAllFields(bh, a)) bh } @Benchmark - def timeThreadUnsafeRTBytes(state: AirportState, threadState: AirportThreadState): Seq[Array[Byte]] = { - airportBytes.map(b => threadState.threadUnsafeLazySerializer.toBytes(threadState.threadUnsafeLazySerializer.fromBytes(b))) + def timeThreadUnsafeRTBytes( + state: AirportState, + threadState: AirportThreadState + ): Seq[Array[Byte]] = { + airportBytes.map( + b => + threadState.threadUnsafeLazySerializer + .toBytes(threadState.threadUnsafeLazySerializer.fromBytes(b)) + ) } } diff --git a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/TByteArrayOutputStream.scala b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/TByteArrayOutputStream.scala index a91b60cd7..bc748542c 100644 --- a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/TByteArrayOutputStream.scala +++ b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/TByteArrayOutputStream.scala @@ -54,6 +54,9 @@ class TByteArrayOutputStreamBenchmark { run(in.buf, out.stream) @Benchmark - def timeTUnboundedByteArrayOutputStream(in: InputState, out: TUnboundedByteArrayOutputStreamState) = + def timeTUnboundedByteArrayOutputStream( + in: InputState, + out: TUnboundedByteArrayOutputStreamState + ) = run(in.buf, out.stream) } diff --git a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/package.scala b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/package.scala index e4b0f53ef..c8c36ed78 100644 --- a/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/package.scala +++ b/scrooge-benchmark/src/main/scala/com/twitter/scrooge/benchmark/package.scala @@ -11,4 +11,3 @@ package object benchmark { if (rng.nextBoolean) Some(fn(rng)) else None } } - diff --git a/scrooge-core/src/test/scala/com/twitter/scrooge/ThriftUtilSpec.scala b/scrooge-core/src/test/scala/com/twitter/scrooge/ThriftUtilSpec.scala index 6554ec97f..73d9f530d 100644 --- a/scrooge-core/src/test/scala/com/twitter/scrooge/ThriftUtilSpec.scala +++ b/scrooge-core/src/test/scala/com/twitter/scrooge/ThriftUtilSpec.scala @@ -24,7 +24,8 @@ class ThriftUtilSpec extends FunSuite with Checkers { TType.STRUCT, TType.MAP, TType.SET, - TType.LIST) + TType.LIST + ) val unrecognizedTypeCodes = arbitrary[Byte].suchThat(b => !recognizedTypeCodes.contains(b)) @@ -32,7 +33,7 @@ class ThriftUtilSpec extends FunSuite with Checkers { check { val inProt = new TBinaryProtocol(new TMemoryBuffer(8)) val outProt = new TBinaryProtocol(new TMemoryBuffer(8)) - forAll (unrecognizedTypeCodes) { typ => + forAll(unrecognizedTypeCodes) { typ => val e = intercept[TProtocolException] { ThriftUtil.transfer(outProt, inProt, typ) } e.getMessage.contains(typ.toString) } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/ASTSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/ASTSpec.scala index 938f0aee3..ac62036d4 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/ASTSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/ASTSpec.scala @@ -22,8 +22,7 @@ class ASTSpec extends Spec { val rbOatmealNs = Namespace("rb", Identifier("Oatmeal")) val doc = Document(Seq(javaOatmealNs, rbOatmealNs), Nil) val namespaceMap = Map(javaOatmealNs.id.fullName -> javaGranolaNs.id.fullName) - doc.mapNamespaces(namespaceMap) must be( - Document(Seq(javaGranolaNs, rbOatmealNs), Nil)) + doc.mapNamespaces(namespaceMap) must be(Document(Seq(javaGranolaNs, rbOatmealNs), Nil)) } "map namespaces recursively" in { diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/MainSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/MainSpec.scala index 9ba17f0b2..fcb28fe1d 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/MainSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/MainSpec.scala @@ -23,7 +23,7 @@ class MainSpec extends Spec { private def buildPath(segments: String*) = segments.mkString(File.separator) - private def test(inDir:File, outDir: File, manifestDir: File){ + private def test(inDir: File, outDir: File, manifestDir: File) { val input = new File(inDir, "input.thrift") val fw = new FileWriter(input) fw.write(""" @@ -39,17 +39,14 @@ struct Point { """) fw.close() val fileMap = new File(manifestDir, "map.txt") - val args = Array[String]( - "-d", outDir.getPath, - "--gen-file-map", fileMap.getPath, - input.getPath) + val args = Array[String]("-d", outDir.getPath, "--gen-file-map", fileMap.getPath, input.getPath) Main.main(args) val manifestString = Source.fromFile(fileMap).mkString val expected = input.getPath + " -> " + buildPath(outDir.getPath, "MyTest", "Constants.scala") + "\n" + input.getPath + " -> " + buildPath(outDir.getPath, "MyTest", "Direction.scala") + "\n" + - input.getPath + " -> " + buildPath(outDir.getPath, "MyTest", "Point.scala")+ "\n" + input.getPath + " -> " + buildPath(outDir.getPath, "MyTest", "Point.scala") + "\n" manifestString must be(expected) } } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala index 134b3b447..650e8b621 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala @@ -129,18 +129,24 @@ class ThriftStructMetaDataSpec extends Spec { "reports single annotations in Struct.fieldInfos" in { val info = AnnoStruct.fieldInfos(0) info.tfield.name must be("structField") - info.typeAnnotations must be(Map( - "structTypeKey" -> "structTypeValue" - )) - info.fieldAnnotations must be(Map( - "structFieldKey" -> "structFieldValue" - )) + info.typeAnnotations must be( + Map( + "structTypeKey" -> "structTypeValue" + ) + ) + info.fieldAnnotations must be( + Map( + "structFieldKey" -> "structFieldValue" + ) + ) } "reports single struct annotations" in { - AnnoStruct.structAnnotations must be(Map( - "structKey" -> "structValue" - )) + AnnoStruct.structAnnotations must be( + Map( + "structKey" -> "structValue" + ) + ) } // MultiAnnoStruct has two annotations in each position: @@ -148,21 +154,27 @@ class ThriftStructMetaDataSpec extends Spec { "reports multiple annotations in Struct.fieldInfos" in { val info = MultiAnnoStruct.fieldInfos(0) info.tfield.name must be("multiStructField") - info.typeAnnotations must be(Map( - "structTypeKey1" -> "structTypeValue1", - "structTypeKey2" -> "structTypeValue2" - )) - info.fieldAnnotations must be(Map( - "structFieldKey1" -> "structFieldValue1", - "structFieldKey2" -> "structFieldValue2" - )) + info.typeAnnotations must be( + Map( + "structTypeKey1" -> "structTypeValue1", + "structTypeKey2" -> "structTypeValue2" + ) + ) + info.fieldAnnotations must be( + Map( + "structFieldKey1" -> "structFieldValue1", + "structFieldKey2" -> "structFieldValue2" + ) + ) } "reports multiple struct annotations" in { - MultiAnnoStruct.structAnnotations must be(Map( - "structKey1" -> "structValue1", - "structKey2" -> "structValue2" - )) + MultiAnnoStruct.structAnnotations must be( + Map( + "structKey1" -> "structValue1", + "structKey2" -> "structValue2" + ) + ) } "populates metaData for unions" in { @@ -214,9 +226,11 @@ class ThriftStructMetaDataSpec extends Spec { // Announion has one annotation in each position - EXCEPT for type annotations. // For some reason, the thrift code generator doesn't allow that. "reports single union annotations" in { - AnnoUnion.structAnnotations must be(Map( - "unionKey" -> "unionValue" - )) + AnnoUnion.structAnnotations must be( + Map( + "unionKey" -> "unionValue" + ) + ) } "contains union field annotations" in { @@ -225,9 +239,11 @@ class ThriftStructMetaDataSpec extends Spec { info.tfield.name must be("unionField") info.tfield.id must be(1: Short) info.typeAnnotations must be(Map.empty[String, String]) - info.fieldAnnotations must be(Map( - "unionFieldKey" -> "unionFieldValue" - )) + info.fieldAnnotations must be( + Map( + "unionFieldKey" -> "unionFieldValue" + ) + ) info.manifest must be(manifest[AnnoStruct]) info.isOptional must be(false) info.keyManifest must be(None) @@ -237,7 +253,8 @@ class ThriftStructMetaDataSpec extends Spec { "contains union manifest info with field types" { { MatchingFieldAndStruct.MatchingStructFieldFieldManifest must be( - manifest[MatchingFieldAndStruct.MatchingStructField]) + manifest[MatchingFieldAndStruct.MatchingStructField] + ) val info = MatchingFieldAndStruct.MatchingStructField.fieldInfo info.tfield.name must be("matchingStructField") info.tfield.id must be(1: Short) @@ -250,7 +267,8 @@ class ThriftStructMetaDataSpec extends Spec { } { MatchingFieldAndStruct.MatchingStructListFieldManifest must be( - manifest[MatchingFieldAndStruct.MatchingStructList]) + manifest[MatchingFieldAndStruct.MatchingStructList] + ) val info = MatchingFieldAndStruct.MatchingStructList.fieldInfo info.tfield.name must be("matchingStructList") info.tfield.id must be(2: Short) @@ -263,7 +281,8 @@ class ThriftStructMetaDataSpec extends Spec { } { MatchingFieldAndStruct.MatchingStructSetFieldManifest must be( - manifest[MatchingFieldAndStruct.MatchingStructSet]) + manifest[MatchingFieldAndStruct.MatchingStructSet] + ) val info = MatchingFieldAndStruct.MatchingStructSet.fieldInfo info.tfield.name must be("matchingStructSet") info.tfield.id must be(3: Short) @@ -276,7 +295,8 @@ class ThriftStructMetaDataSpec extends Spec { } { MatchingFieldAndStruct.MatchingStructMapFieldManifest must be( - manifest[MatchingFieldAndStruct.MatchingStructMap]) + manifest[MatchingFieldAndStruct.MatchingStructMap] + ) val info = MatchingFieldAndStruct.MatchingStructMap.fieldInfo info.tfield.name must be("matchingStructMap") info.tfield.id must be(4: Short) diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/android_generator/AndroidGeneratorSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/android_generator/AndroidGeneratorSpec.scala index 120823983..eef2b6696 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/android_generator/AndroidGeneratorSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/android_generator/AndroidGeneratorSpec.scala @@ -24,7 +24,12 @@ import scala.collection.concurrent.TrieMap */ class AndroidGeneratorSpec extends Spec { def generateDoc(str: String) = { - val importer = Importer(Seq("src/test/resources/test_thrift", "scrooge-generator-tests/src/test/resources/test_thrift")) + val importer = Importer( + Seq( + "src/test/resources/test_thrift", + "scrooge-generator-tests/src/test/resources/test_thrift" + ) + ) val parser = new ThriftParser(importer, true) val doc = parser.parse(str, parser.document) TypeResolver()(doc).document @@ -33,7 +38,12 @@ class AndroidGeneratorSpec extends Spec { val templateCache = new TrieMap[String, Mustache] def getGenerator(doc: Document, genHashcode: Boolean = true) = { - new AndroidGenerator(ResolvedDocument(doc, new TypeResolver), "thrift", templateCache, genHashcode = genHashcode) + new AndroidGenerator( + ResolvedDocument(doc, new TypeResolver), + "thrift", + templateCache, + genHashcode = genHashcode + ) } def getFileContents(resource: String) = { @@ -57,10 +67,10 @@ class AndroidGeneratorSpec extends Spec { set.add(55) val map = new util.HashMap[Integer, Integer] - map.put(100,100) - map.put(200,200) - map.put(300,300) - map.put(400,400) + map.put(100, 100) + map.put(200, 200) + map.put(300, 300) + map.put(400, 400) (new SimpleWithDefaults.Builder) .set(SimpleWithDefaults.Z, false) @@ -75,304 +85,310 @@ class AndroidGeneratorSpec extends Spec { .set(SimpleWithDefaults.I_MAP, map) .build() - } "Generator" should { System.setProperty("mustache.debug", "true") - "populate default values in structs" in { - val defaultValues = (new SimpleWithDefaults.Builder).build() - - (defaultValues.get(SimpleWithDefaults.Z):Boolean) must be (true) - (defaultValues.get(SimpleWithDefaults.B):Byte) must be (1) - (defaultValues.get(SimpleWithDefaults.S):Short) must be (1) - (defaultValues.get(SimpleWithDefaults.I):Integer) must be (1) - (defaultValues.get(SimpleWithDefaults.J):Long) must be (1) - (defaultValues.get(SimpleWithDefaults.D):Double) must be (1.0) - (defaultValues.get(SimpleWithDefaults.STR):String) must be ("yo") - val l:util.ArrayList[Integer] = defaultValues.get(SimpleWithDefaults.I_LIST) - l.size must be (1) - l.contains(1) must be (true) - - val i_set:util.HashSet[Integer] = defaultValues.get(SimpleWithDefaults.I_SET):util.HashSet[Integer] - i_set.size must be (1) - i_set.contains(1) must be (true) - - val i_map:util.HashMap[Integer, Integer] = defaultValues.get(SimpleWithDefaults.I_MAP) - i_map.size must be (1) - i_map.get(1) must be (1) - } - "handle updated values in structs" in { - val simple = populateTestData - (simple.get(SimpleWithDefaults.Z):Boolean) must be (false) - (simple.get(SimpleWithDefaults.B):Byte) must be (255.toByte) - (simple.get(SimpleWithDefaults.S):Short) must be (12345.toShort) - (simple.get(SimpleWithDefaults.I):Integer) must be (105020401) - (simple.get(SimpleWithDefaults.J):Long) must be (1234000000L) - (simple.get(SimpleWithDefaults.D):Double) must be (9876.54) - (simple.get(SimpleWithDefaults.STR):String) must be ("Changed Value") - val l:util.ArrayList[Integer] = simple.get(SimpleWithDefaults.I_LIST) - l.size must be (3) - l.contains(1) must be (false) - l.contains(10) must be (true) - - val i_set:util.HashSet[Integer] = simple.get(SimpleWithDefaults.I_SET):util.HashSet[Integer] - i_set.size must be (5) - i_set.contains(1) must be (false) - i_set.contains(55) must be (true) - - val i_map:util.HashMap[Integer, Integer] = simple.get(SimpleWithDefaults.I_MAP) - i_map.size must be (4) - i_map.get(1) must be (null) - i_map.get(300) must be (300) - } - "return same hashcode for same values" in { - val data1 = populateTestData - val data2 = populateTestData - data1.hashCode must be (data2.hashCode) - } - "return valid compareTo result" in { - val dataSmall1= (new SimpleWithDefaults.Builder) - .set(SimpleWithDefaults.I, 100) - .build() - val dataSmall2= (new SimpleWithDefaults.Builder) - .set(SimpleWithDefaults.I, 100) - .build() - val dataLarge = (new SimpleWithDefaults.Builder) - .set(SimpleWithDefaults.I, 200) - .build() - - dataSmall1.compareTo(dataSmall2) must be (0) - dataSmall1.compareTo(dataLarge) < 0 must be (true) - } - "handle struct rhs assignment" in { - val const = thrift.complete.android.test1.Constants.ListOfComplexStructs - const.size() must be (3) - val second = const.get(1) - - val structXA = second.get(StructXB.STRUCT_FIELD):StructXA - (second.get(StructXB.SNAKE_CASE_FIELD):Long) must be (71) - (second.get(StructXB.CAMEL_CASE_FIELD):Long) must be (72) - (second.get(StructXB.REQUIRED_FIELD):Long) must be (73) - (structXA.get(StructXA.ID):Long) must be (71) - } - "populate complex collections" in { - val xa1 = (new StructXA.Builder).set(StructXA.ID, 100L).build - val xa2 = (new StructXA.Builder).set(StructXA.ID, 321L).build - val xa3 = (new StructXA.Builder).set(StructXA.ID, 333L).build - val xa4 = (new StructXA.Builder).set(StructXA.ID, 444L).build - val xa5 = (new StructXA.Builder).set(StructXA.ID, 555L).build - val xa6 = (new StructXA.Builder).set(StructXA.ID, 666L).build - - val xb1 = (new StructXB.Builder) - .set(StructXB.SNAKE_CASE_FIELD, 10L) - .set(StructXB.CAMEL_CASE_FIELD, 20L) - .set(StructXB.OPTIONAL_FIELD, "very optional field") - .set(StructXB.REQUIRED_FIELD, 700L) - .set(StructXB.STRUCT_FIELD, xa1) - .set(StructXB.DEFAULT_FIELD, 300L) - .build - - val xb2 = (new StructXB.Builder) - .set(StructXB.SNAKE_CASE_FIELD, 12L) - .set(StructXB.CAMEL_CASE_FIELD, 22L) - .set(StructXB.OPTIONAL_FIELD, "very very optional field") - .set(StructXB.REQUIRED_FIELD, 702L) - .set(StructXB.STRUCT_FIELD, xa2) - .set(StructXB.DEFAULT_FIELD, 302L) - .build - - val xb3 = (new StructXB.Builder) - .set(StructXB.SNAKE_CASE_FIELD, 13L) - .set(StructXB.CAMEL_CASE_FIELD, 23L) - .set(StructXB.OPTIONAL_FIELD, "very very very optional field") - .set(StructXB.REQUIRED_FIELD, 703L) - .set(StructXB.STRUCT_FIELD, xa3) - .set(StructXB.DEFAULT_FIELD, 303L) - .build - - val xb4 = (new StructXB.Builder) - .set(StructXB.SNAKE_CASE_FIELD, 413L) - .set(StructXB.CAMEL_CASE_FIELD, 423L) - .set(StructXB.OPTIONAL_FIELD, "4: optional field") - .set(StructXB.REQUIRED_FIELD, 4703L) - .set(StructXB.STRUCT_FIELD, xa3) - .set(StructXB.DEFAULT_FIELD, 4303L) - .build - - val xb5 = (new StructXB.Builder) - .set(StructXB.SNAKE_CASE_FIELD, 513L) - .set(StructXB.CAMEL_CASE_FIELD, 523L) - .set(StructXB.OPTIONAL_FIELD, "5 very very very optional field") - .set(StructXB.REQUIRED_FIELD, 5703L) - .set(StructXB.STRUCT_FIELD, xa5) - .set(StructXB.DEFAULT_FIELD, 5303L) - .build - - val xb6 = (new StructXB.Builder) - .set(StructXB.SNAKE_CASE_FIELD, 613L) - .set(StructXB.CAMEL_CASE_FIELD, 623L) - .set(StructXB.OPTIONAL_FIELD, "6 very very very optional field") - .set(StructXB.REQUIRED_FIELD, 6703L) - .set(StructXB.STRUCT_FIELD, xa6) - .set(StructXB.DEFAULT_FIELD, 6303L) - .build - - - val xb_key_1 = xb1.deepCopy - val xb_key_2 = xb2.deepCopy - val xb_key_3 = xb3.deepCopy - - val list_in_complex_map1 = new util.ArrayList[String] - list_in_complex_map1.add("first") - list_in_complex_map1.add("second") - list_in_complex_map1.add("third") - - val list_in_complex_map2 = new util.ArrayList[String] - list_in_complex_map2.add("one") - list_in_complex_map2.add("two") - list_in_complex_map2.add("three") - - val map_in_complex_list1 = new util.HashMap[String, Integer] - map_in_complex_list1.put("data_1", 1111) - map_in_complex_list1.put("data_2", 1222) - map_in_complex_list1.put("data_3", 1333) - map_in_complex_list1.put("data_4", 1444) - map_in_complex_list1.put("data_5", 1555) - - val map_in_complex_list2 = new util.HashMap[String, Integer] - map_in_complex_list2.put("data_1", 2111) - map_in_complex_list2.put("data_2", 2222) - map_in_complex_list2.put("data_3", 2333) - map_in_complex_list2.put("data_4", 2444) - map_in_complex_list2.put("data_5", 2555) - - val map_in_complex_list3 = new util.HashMap[String, Integer] - map_in_complex_list3.put("data_1", 2111) - map_in_complex_list3.put("data_2", 2222) - map_in_complex_list3.put("data_3", 2333) - map_in_complex_list3.put("data_4", 2444) - map_in_complex_list3.put("data_5", 2555) - - val list_in_super_complex1 = new util.ArrayList[String] - list_in_super_complex1.add("one") - list_in_super_complex1.add("two") - list_in_super_complex1.add("three") - - val list_in_super_complex2 = new util.ArrayList[String] - list_in_super_complex2.add("second one") - list_in_super_complex2.add("second two") - list_in_super_complex2.add("second three") - - val list_in_super_complex3 = new util.ArrayList[String] - list_in_super_complex3.add("three one") - list_in_super_complex3.add("three two") - list_in_super_complex3.add("three three") - - val map_in_super_complex1 = new util.HashMap[String, util.ArrayList[String]] - map_in_super_complex1.put("key_one_one_empty", new util.ArrayList[String]) - map_in_super_complex1.put("key_one_two", list_in_super_complex1) - map_in_super_complex1.put("key_one_three", list_in_super_complex2) - - val map_in_super_complex2 = new util.HashMap[String, util.ArrayList[String]] - map_in_super_complex2.put("key_two_one_empty", new util.ArrayList[String]) - map_in_super_complex2.put("key_two_two", list_in_super_complex3) - - val map_in_super_complex3 = new util.HashMap[String, util.ArrayList[String]] - map_in_super_complex3.put("key_three_one_empty", list_in_super_complex3) - - val set_in_super_complex1 = new util.HashSet[util.HashMap[String, util.ArrayList[String]]] - set_in_super_complex1.add(map_in_super_complex1) - set_in_super_complex1.add(map_in_super_complex2) - - val set_in_super_complex2 = new util.HashSet[util.HashMap[String, util.ArrayList[String]]] - set_in_super_complex2.add(new util.HashMap[String, util.ArrayList[String]]) - - val set_in_super_complex3 = new util.HashSet[util.HashMap[String, util.ArrayList[String]]] - set_in_super_complex3.add(map_in_super_complex2) - - - val complexColl = (new ComplexCollections.Builder) - .addTo(ComplexCollections.LXB, xb1.deepCopy) - .addTo(ComplexCollections.LXB, xb2.deepCopy) - .addTo(ComplexCollections.LXB, xb2.deepCopy) - .addTo(ComplexCollections.LXB, xb2.deepCopy) - .addTo(ComplexCollections.LXB, xb3.deepCopy) - .addTo(ComplexCollections.SXB, xb4) - .addTo(ComplexCollections.SXB, xb5) - .addTo(ComplexCollections.SXB, xb1.deepCopy) - .addTo(ComplexCollections.SXB, xb2.deepCopy) - .addTo(ComplexCollections.SXB, xb3.deepCopy) - .putTo(ComplexCollections.MXB, xb_key_1, xb3.deepCopy) - .putTo(ComplexCollections.MXB, xb_key_2, xb2.deepCopy) - .putTo(ComplexCollections.MXB, xb_key_3, xb1.deepCopy) - .putTo(ComplexCollections.COMPLEX_MAP, "first_element", list_in_complex_map1) - .putTo(ComplexCollections.COMPLEX_MAP, "second_element", list_in_complex_map2) - .addTo(ComplexCollections.COMPLEX_LIST, map_in_complex_list1) - .addTo(ComplexCollections.COMPLEX_LIST, map_in_complex_list2) - .addTo(ComplexCollections.COMPLEX_LIST, map_in_complex_list3) - .addTo(ComplexCollections.SUPER_COMPLEX_COLLECTION, set_in_super_complex1) - .addTo(ComplexCollections.SUPER_COMPLEX_COLLECTION, new util.HashSet[util.HashMap[String, util.ArrayList[String]]]) - .addTo(ComplexCollections.SUPER_COMPLEX_COLLECTION, set_in_super_complex2) - .build - - val structList:util.ArrayList[StructXB] = complexColl.get(ComplexCollections.LXB) - structList.size must be (5) - val xb1_candidate = structList.get(0) - xb1_candidate.hashCode must be (xb1.hashCode) - (xb1_candidate.get(StructXB.SNAKE_CASE_FIELD):Long) must be (10L) - (xb1_candidate.get(StructXB.CAMEL_CASE_FIELD):Long) must be (20L) - (xb1_candidate.get(StructXB.OPTIONAL_FIELD):String) must be ("very optional field") - (xb1_candidate.get(StructXB.REQUIRED_FIELD):Long) must be (700L) - val xb1_xa1_candidate:StructXA = xb1_candidate.get(StructXB.STRUCT_FIELD) - (xb1_xa1_candidate.get(StructXA.ID):Long) must be (100L) - - val structSet:util.HashSet[StructXB] = complexColl.get(ComplexCollections.SXB) - structSet.size must be (5) - structSet.contains(xb4) must be (true) - structSet.contains(xb5) must be (true) - structSet.contains(xb6) must be (false) - - val structMap:util.HashMap[String, StructXB] = complexColl.get(ComplexCollections.MXB) - structMap.size must be (3) - structMap.containsKey(xb_key_1) must be (true) - structMap.containsKey(xb_key_2) must be (true) - structMap.containsKey(xb_key_3) must be (true) - structMap.containsKey(xb4) must be (false) - val xb2_copied = structMap.get(xb_key_2) - xb2_copied.hashCode must be (xb2.hashCode) - (xb2_copied.get(StructXB.SNAKE_CASE_FIELD):Long) must be (12L) - (xb2_copied.get(StructXB.CAMEL_CASE_FIELD):Long) must be (22L) - (xb2_copied.get(StructXB.OPTIONAL_FIELD):String) must be ("very very optional field") - (xb2_copied.get(StructXB.REQUIRED_FIELD):Long) must be (702L) - val xb2_xa1_candidate:StructXA = xb2_copied.get(StructXB.STRUCT_FIELD) - (xb2_xa1_candidate.get(StructXA.ID):Long) must be (321L) - (xb2_copied.get(StructXB.DEFAULT_FIELD):Long) must be (302L) - - val complex_map_value:util.HashMap[String, util.ArrayList[String]] = complexColl.get(ComplexCollections.COMPLEX_MAP) - complex_map_value.size must be (2) - complex_map_value.get("first_element") must be (list_in_complex_map1) - complex_map_value.get("second_element").hashCode must be (list_in_complex_map2.hashCode) - complex_map_value.get("second_element").hashCode must not be (list_in_complex_map1.hashCode) - - val complex_list_value:util.ArrayList[util.HashMap[String, Integer]] = complexColl.get(ComplexCollections.COMPLEX_LIST) - complex_list_value.size must be (3) - (complex_list_value.get(2):util.HashMap[String, Integer]) must be (map_in_complex_list3) - - val super_complex_list:util.ArrayList[util.HashSet[util.HashMap[String, util.ArrayList[String]]]] = complexColl.get(ComplexCollections.SUPER_COMPLEX_COLLECTION) - super_complex_list.size must be (3) - super_complex_list.contains(set_in_super_complex1) must be (true) - super_complex_list.contains(set_in_super_complex2) must be (true) - super_complex_list.contains(set_in_super_complex3) must be (false) - super_complex_list.get(0) must be (set_in_super_complex1) - super_complex_list.get(0).equals(set_in_super_complex1) must be (true) - - val super_complex_list_set:util.HashSet[util.HashMap[String, util.ArrayList[String]]] = super_complex_list.get(0) - super_complex_list_set.contains(map_in_super_complex1) must be (true) - super_complex_list_set.contains(map_in_super_complex1) must be (true) - super_complex_list_set.contains(map_in_super_complex3) must be (false) - - } + "populate default values in structs" in { + val defaultValues = (new SimpleWithDefaults.Builder).build() + + (defaultValues.get(SimpleWithDefaults.Z): Boolean) must be(true) + (defaultValues.get(SimpleWithDefaults.B): Byte) must be(1) + (defaultValues.get(SimpleWithDefaults.S): Short) must be(1) + (defaultValues.get(SimpleWithDefaults.I): Integer) must be(1) + (defaultValues.get(SimpleWithDefaults.J): Long) must be(1) + (defaultValues.get(SimpleWithDefaults.D): Double) must be(1.0) + (defaultValues.get(SimpleWithDefaults.STR): String) must be("yo") + val l: util.ArrayList[Integer] = defaultValues.get(SimpleWithDefaults.I_LIST) + l.size must be(1) + l.contains(1) must be(true) + + val i_set: util.HashSet[Integer] = + defaultValues.get(SimpleWithDefaults.I_SET): util.HashSet[Integer] + i_set.size must be(1) + i_set.contains(1) must be(true) + + val i_map: util.HashMap[Integer, Integer] = defaultValues.get(SimpleWithDefaults.I_MAP) + i_map.size must be(1) + i_map.get(1) must be(1) + } + "handle updated values in structs" in { + val simple = populateTestData + (simple.get(SimpleWithDefaults.Z): Boolean) must be(false) + (simple.get(SimpleWithDefaults.B): Byte) must be(255.toByte) + (simple.get(SimpleWithDefaults.S): Short) must be(12345.toShort) + (simple.get(SimpleWithDefaults.I): Integer) must be(105020401) + (simple.get(SimpleWithDefaults.J): Long) must be(1234000000L) + (simple.get(SimpleWithDefaults.D): Double) must be(9876.54) + (simple.get(SimpleWithDefaults.STR): String) must be("Changed Value") + val l: util.ArrayList[Integer] = simple.get(SimpleWithDefaults.I_LIST) + l.size must be(3) + l.contains(1) must be(false) + l.contains(10) must be(true) + + val i_set: util.HashSet[Integer] = simple.get(SimpleWithDefaults.I_SET): util.HashSet[Integer] + i_set.size must be(5) + i_set.contains(1) must be(false) + i_set.contains(55) must be(true) + + val i_map: util.HashMap[Integer, Integer] = simple.get(SimpleWithDefaults.I_MAP) + i_map.size must be(4) + i_map.get(1) must be(null) + i_map.get(300) must be(300) + } + "return same hashcode for same values" in { + val data1 = populateTestData + val data2 = populateTestData + data1.hashCode must be(data2.hashCode) + } + "return valid compareTo result" in { + val dataSmall1 = (new SimpleWithDefaults.Builder) + .set(SimpleWithDefaults.I, 100) + .build() + val dataSmall2 = (new SimpleWithDefaults.Builder) + .set(SimpleWithDefaults.I, 100) + .build() + val dataLarge = (new SimpleWithDefaults.Builder) + .set(SimpleWithDefaults.I, 200) + .build() + + dataSmall1.compareTo(dataSmall2) must be(0) + dataSmall1.compareTo(dataLarge) < 0 must be(true) + } + "handle struct rhs assignment" in { + val const = thrift.complete.android.test1.Constants.ListOfComplexStructs + const.size() must be(3) + val second = const.get(1) + + val structXA = second.get(StructXB.STRUCT_FIELD): StructXA + (second.get(StructXB.SNAKE_CASE_FIELD): Long) must be(71) + (second.get(StructXB.CAMEL_CASE_FIELD): Long) must be(72) + (second.get(StructXB.REQUIRED_FIELD): Long) must be(73) + (structXA.get(StructXA.ID): Long) must be(71) + } + "populate complex collections" in { + val xa1 = (new StructXA.Builder).set(StructXA.ID, 100L).build + val xa2 = (new StructXA.Builder).set(StructXA.ID, 321L).build + val xa3 = (new StructXA.Builder).set(StructXA.ID, 333L).build + val xa4 = (new StructXA.Builder).set(StructXA.ID, 444L).build + val xa5 = (new StructXA.Builder).set(StructXA.ID, 555L).build + val xa6 = (new StructXA.Builder).set(StructXA.ID, 666L).build + + val xb1 = (new StructXB.Builder) + .set(StructXB.SNAKE_CASE_FIELD, 10L) + .set(StructXB.CAMEL_CASE_FIELD, 20L) + .set(StructXB.OPTIONAL_FIELD, "very optional field") + .set(StructXB.REQUIRED_FIELD, 700L) + .set(StructXB.STRUCT_FIELD, xa1) + .set(StructXB.DEFAULT_FIELD, 300L) + .build + + val xb2 = (new StructXB.Builder) + .set(StructXB.SNAKE_CASE_FIELD, 12L) + .set(StructXB.CAMEL_CASE_FIELD, 22L) + .set(StructXB.OPTIONAL_FIELD, "very very optional field") + .set(StructXB.REQUIRED_FIELD, 702L) + .set(StructXB.STRUCT_FIELD, xa2) + .set(StructXB.DEFAULT_FIELD, 302L) + .build + + val xb3 = (new StructXB.Builder) + .set(StructXB.SNAKE_CASE_FIELD, 13L) + .set(StructXB.CAMEL_CASE_FIELD, 23L) + .set(StructXB.OPTIONAL_FIELD, "very very very optional field") + .set(StructXB.REQUIRED_FIELD, 703L) + .set(StructXB.STRUCT_FIELD, xa3) + .set(StructXB.DEFAULT_FIELD, 303L) + .build + + val xb4 = (new StructXB.Builder) + .set(StructXB.SNAKE_CASE_FIELD, 413L) + .set(StructXB.CAMEL_CASE_FIELD, 423L) + .set(StructXB.OPTIONAL_FIELD, "4: optional field") + .set(StructXB.REQUIRED_FIELD, 4703L) + .set(StructXB.STRUCT_FIELD, xa3) + .set(StructXB.DEFAULT_FIELD, 4303L) + .build + + val xb5 = (new StructXB.Builder) + .set(StructXB.SNAKE_CASE_FIELD, 513L) + .set(StructXB.CAMEL_CASE_FIELD, 523L) + .set(StructXB.OPTIONAL_FIELD, "5 very very very optional field") + .set(StructXB.REQUIRED_FIELD, 5703L) + .set(StructXB.STRUCT_FIELD, xa5) + .set(StructXB.DEFAULT_FIELD, 5303L) + .build + + val xb6 = (new StructXB.Builder) + .set(StructXB.SNAKE_CASE_FIELD, 613L) + .set(StructXB.CAMEL_CASE_FIELD, 623L) + .set(StructXB.OPTIONAL_FIELD, "6 very very very optional field") + .set(StructXB.REQUIRED_FIELD, 6703L) + .set(StructXB.STRUCT_FIELD, xa6) + .set(StructXB.DEFAULT_FIELD, 6303L) + .build + + val xb_key_1 = xb1.deepCopy + val xb_key_2 = xb2.deepCopy + val xb_key_3 = xb3.deepCopy + + val list_in_complex_map1 = new util.ArrayList[String] + list_in_complex_map1.add("first") + list_in_complex_map1.add("second") + list_in_complex_map1.add("third") + + val list_in_complex_map2 = new util.ArrayList[String] + list_in_complex_map2.add("one") + list_in_complex_map2.add("two") + list_in_complex_map2.add("three") + + val map_in_complex_list1 = new util.HashMap[String, Integer] + map_in_complex_list1.put("data_1", 1111) + map_in_complex_list1.put("data_2", 1222) + map_in_complex_list1.put("data_3", 1333) + map_in_complex_list1.put("data_4", 1444) + map_in_complex_list1.put("data_5", 1555) + + val map_in_complex_list2 = new util.HashMap[String, Integer] + map_in_complex_list2.put("data_1", 2111) + map_in_complex_list2.put("data_2", 2222) + map_in_complex_list2.put("data_3", 2333) + map_in_complex_list2.put("data_4", 2444) + map_in_complex_list2.put("data_5", 2555) + + val map_in_complex_list3 = new util.HashMap[String, Integer] + map_in_complex_list3.put("data_1", 2111) + map_in_complex_list3.put("data_2", 2222) + map_in_complex_list3.put("data_3", 2333) + map_in_complex_list3.put("data_4", 2444) + map_in_complex_list3.put("data_5", 2555) + + val list_in_super_complex1 = new util.ArrayList[String] + list_in_super_complex1.add("one") + list_in_super_complex1.add("two") + list_in_super_complex1.add("three") + + val list_in_super_complex2 = new util.ArrayList[String] + list_in_super_complex2.add("second one") + list_in_super_complex2.add("second two") + list_in_super_complex2.add("second three") + + val list_in_super_complex3 = new util.ArrayList[String] + list_in_super_complex3.add("three one") + list_in_super_complex3.add("three two") + list_in_super_complex3.add("three three") + + val map_in_super_complex1 = new util.HashMap[String, util.ArrayList[String]] + map_in_super_complex1.put("key_one_one_empty", new util.ArrayList[String]) + map_in_super_complex1.put("key_one_two", list_in_super_complex1) + map_in_super_complex1.put("key_one_three", list_in_super_complex2) + + val map_in_super_complex2 = new util.HashMap[String, util.ArrayList[String]] + map_in_super_complex2.put("key_two_one_empty", new util.ArrayList[String]) + map_in_super_complex2.put("key_two_two", list_in_super_complex3) + + val map_in_super_complex3 = new util.HashMap[String, util.ArrayList[String]] + map_in_super_complex3.put("key_three_one_empty", list_in_super_complex3) + + val set_in_super_complex1 = new util.HashSet[util.HashMap[String, util.ArrayList[String]]] + set_in_super_complex1.add(map_in_super_complex1) + set_in_super_complex1.add(map_in_super_complex2) + + val set_in_super_complex2 = new util.HashSet[util.HashMap[String, util.ArrayList[String]]] + set_in_super_complex2.add(new util.HashMap[String, util.ArrayList[String]]) + + val set_in_super_complex3 = new util.HashSet[util.HashMap[String, util.ArrayList[String]]] + set_in_super_complex3.add(map_in_super_complex2) + + val complexColl = (new ComplexCollections.Builder) + .addTo(ComplexCollections.LXB, xb1.deepCopy) + .addTo(ComplexCollections.LXB, xb2.deepCopy) + .addTo(ComplexCollections.LXB, xb2.deepCopy) + .addTo(ComplexCollections.LXB, xb2.deepCopy) + .addTo(ComplexCollections.LXB, xb3.deepCopy) + .addTo(ComplexCollections.SXB, xb4) + .addTo(ComplexCollections.SXB, xb5) + .addTo(ComplexCollections.SXB, xb1.deepCopy) + .addTo(ComplexCollections.SXB, xb2.deepCopy) + .addTo(ComplexCollections.SXB, xb3.deepCopy) + .putTo(ComplexCollections.MXB, xb_key_1, xb3.deepCopy) + .putTo(ComplexCollections.MXB, xb_key_2, xb2.deepCopy) + .putTo(ComplexCollections.MXB, xb_key_3, xb1.deepCopy) + .putTo(ComplexCollections.COMPLEX_MAP, "first_element", list_in_complex_map1) + .putTo(ComplexCollections.COMPLEX_MAP, "second_element", list_in_complex_map2) + .addTo(ComplexCollections.COMPLEX_LIST, map_in_complex_list1) + .addTo(ComplexCollections.COMPLEX_LIST, map_in_complex_list2) + .addTo(ComplexCollections.COMPLEX_LIST, map_in_complex_list3) + .addTo(ComplexCollections.SUPER_COMPLEX_COLLECTION, set_in_super_complex1) + .addTo( + ComplexCollections.SUPER_COMPLEX_COLLECTION, + new util.HashSet[util.HashMap[String, util.ArrayList[String]]] + ) + .addTo(ComplexCollections.SUPER_COMPLEX_COLLECTION, set_in_super_complex2) + .build + + val structList: util.ArrayList[StructXB] = complexColl.get(ComplexCollections.LXB) + structList.size must be(5) + val xb1_candidate = structList.get(0) + xb1_candidate.hashCode must be(xb1.hashCode) + (xb1_candidate.get(StructXB.SNAKE_CASE_FIELD): Long) must be(10L) + (xb1_candidate.get(StructXB.CAMEL_CASE_FIELD): Long) must be(20L) + (xb1_candidate.get(StructXB.OPTIONAL_FIELD): String) must be("very optional field") + (xb1_candidate.get(StructXB.REQUIRED_FIELD): Long) must be(700L) + val xb1_xa1_candidate: StructXA = xb1_candidate.get(StructXB.STRUCT_FIELD) + (xb1_xa1_candidate.get(StructXA.ID): Long) must be(100L) + + val structSet: util.HashSet[StructXB] = complexColl.get(ComplexCollections.SXB) + structSet.size must be(5) + structSet.contains(xb4) must be(true) + structSet.contains(xb5) must be(true) + structSet.contains(xb6) must be(false) + + val structMap: util.HashMap[String, StructXB] = complexColl.get(ComplexCollections.MXB) + structMap.size must be(3) + structMap.containsKey(xb_key_1) must be(true) + structMap.containsKey(xb_key_2) must be(true) + structMap.containsKey(xb_key_3) must be(true) + structMap.containsKey(xb4) must be(false) + val xb2_copied = structMap.get(xb_key_2) + xb2_copied.hashCode must be(xb2.hashCode) + (xb2_copied.get(StructXB.SNAKE_CASE_FIELD): Long) must be(12L) + (xb2_copied.get(StructXB.CAMEL_CASE_FIELD): Long) must be(22L) + (xb2_copied.get(StructXB.OPTIONAL_FIELD): String) must be("very very optional field") + (xb2_copied.get(StructXB.REQUIRED_FIELD): Long) must be(702L) + val xb2_xa1_candidate: StructXA = xb2_copied.get(StructXB.STRUCT_FIELD) + (xb2_xa1_candidate.get(StructXA.ID): Long) must be(321L) + (xb2_copied.get(StructXB.DEFAULT_FIELD): Long) must be(302L) + + val complex_map_value: util.HashMap[String, util.ArrayList[String]] = + complexColl.get(ComplexCollections.COMPLEX_MAP) + complex_map_value.size must be(2) + complex_map_value.get("first_element") must be(list_in_complex_map1) + complex_map_value.get("second_element").hashCode must be(list_in_complex_map2.hashCode) + complex_map_value.get("second_element").hashCode must not be (list_in_complex_map1.hashCode) + + val complex_list_value: util.ArrayList[util.HashMap[String, Integer]] = + complexColl.get(ComplexCollections.COMPLEX_LIST) + complex_list_value.size must be(3) + (complex_list_value.get(2): util.HashMap[String, Integer]) must be(map_in_complex_list3) + + val super_complex_list + : util.ArrayList[util.HashSet[util.HashMap[String, util.ArrayList[String]]]] = + complexColl.get(ComplexCollections.SUPER_COMPLEX_COLLECTION) + super_complex_list.size must be(3) + super_complex_list.contains(set_in_super_complex1) must be(true) + super_complex_list.contains(set_in_super_complex2) must be(true) + super_complex_list.contains(set_in_super_complex3) must be(false) + super_complex_list.get(0) must be(set_in_super_complex1) + super_complex_list.get(0).equals(set_in_super_complex1) must be(true) + + val super_complex_list_set: util.HashSet[util.HashMap[String, util.ArrayList[String]]] = + super_complex_list.get(0) + super_complex_list_set.contains(map_in_super_complex1) must be(true) + super_complex_list_set.contains(map_in_super_complex1) must be(true) + super_complex_list_set.contains(map_in_super_complex3) must be(false) + + } "populate enum controller" in { val doc = generateDoc(getFileContents("test_thrift/enum.thrift")) @@ -387,19 +403,22 @@ class AndroidGeneratorSpec extends Spec { "generate enum code" in { val controller = mock[EnumController] when(controller.name) thenReturn "test" - when(controller.constants) thenReturn Seq(new EnumConstant("foo", 1, false), new EnumConstant("bar", 2, true)) + when(controller.constants) thenReturn Seq( + new EnumConstant("foo", 1, false), + new EnumConstant("bar", 2, true) + ) when(controller.namespace) thenReturn "com.twitter.thrift" when(controller.has_namespace) thenReturn true val sw = renderMustache("enum.mustache", controller) verify(sw, getFileContents("android_output/enum.txt")) } - "populate consts" in { - val doc = generateDoc(getFileContents("test_thrift/consts.thrift")) - val controller = new ConstController(doc.consts, getGenerator(doc), doc.namespace("android")) - val sw = renderMustache("consts.mustache", controller) - verify(sw, getFileContents("android_output/consts.txt")) - } + "populate consts" in { + val doc = generateDoc(getFileContents("test_thrift/consts.thrift")) + val controller = new ConstController(doc.consts, getGenerator(doc), doc.namespace("android")) + val sw = renderMustache("consts.mustache", controller) + verify(sw, getFileContents("android_output/consts.txt")) + } "populate const map" in { val doc = generateDoc(getFileContents("test_thrift/constant_map.thrift")) @@ -412,14 +431,16 @@ class AndroidGeneratorSpec extends Spec { "generate struct with hashcode" in { val doc = generateDoc(getFileContents("test_thrift/struct.thrift")) val generator = getGenerator(doc) - val controller = new StructController(doc.structs(1), false, generator, doc.namespace("android")) + val controller = + new StructController(doc.structs(1), false, generator, doc.namespace("android")) val sw = renderMustache("struct.mustache", controller) verify(sw, getFileContents("android_output/struct_with_hashcode.txt")) } "generate empty struct" in { val doc = generateDoc(getFileContents("test_thrift/empty_struct.thrift")) - val controller = new StructController(doc.structs(0), false, getGenerator(doc), doc.namespace("android")) + val controller = + new StructController(doc.structs(0), false, getGenerator(doc), doc.namespace("android")) val sw = renderMustache("struct.mustache", controller) verify(sw, getFileContents("android_output/empty_struct.txt"), false) } @@ -427,7 +448,8 @@ class AndroidGeneratorSpec extends Spec { "generate union with hashcode" in { val doc = generateDoc(getFileContents("test_thrift/union.thrift")) val generator = getGenerator(doc) - val controller = new StructController(doc.structs(0), false, generator, doc.namespace("android")) + val controller = + new StructController(doc.structs(0), false, generator, doc.namespace("android")) val sw = renderMustache("struct.mustache", controller) verify(sw, getFileContents("android_output/union_with_hashcode.txt")) } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ApacheJavaMetadataSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ApacheJavaMetadataSpec.scala index f0f2cf8e3..3321716e1 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ApacheJavaMetadataSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ApacheJavaMetadataSpec.scala @@ -6,20 +6,19 @@ import org.apache.thrift.protocol.TType import org.apache.thrift.meta_data._ import scala.collection.JavaConverters._ - class ApacheJavaMetadataSpec extends Spec { "ApacheJavaMetadata" should { "generate struct metadata" should { - val metadata = + val metadata = FieldMetaData .getStructMetaDataMap(classOf[ExceptionsAreStructs]) .asScala - .map { case(id, value) => (id.getFieldName, value) } + .map { case (id, value) => (id.getFieldName, value) } "for exception field" in { val fieldValueMetaData = metadata("exceptionField").valueMetaData - + fieldValueMetaData.`type` must be(TType.STRUCT) fieldValueMetaData mustBe a[StructMetaData] fieldValueMetaData.asInstanceOf[StructMetaData].structClass must be(classOf[MyException]) @@ -27,7 +26,7 @@ class ApacheJavaMetadataSpec extends Spec { "for struct field" in { val fieldValueMetaData = metadata("structField").valueMetaData - + fieldValueMetaData.`type` must be(TType.STRUCT) fieldValueMetaData mustBe a[StructMetaData] fieldValueMetaData.asInstanceOf[StructMetaData].structClass must be(classOf[MyStruct]) @@ -35,44 +34,50 @@ class ApacheJavaMetadataSpec extends Spec { "for list of exceptions field" in { val fieldValueMetaData = metadata("exceptionListField").valueMetaData - + fieldValueMetaData.`type` must be(TType.LIST) fieldValueMetaData mustBe a[ListMetaData] val listMetaData = fieldValueMetaData.asInstanceOf[ListMetaData] listMetaData.elemMetaData.`type` must be(TType.STRUCT) listMetaData.elemMetaData mustBe a[StructMetaData] - listMetaData.elemMetaData.asInstanceOf[StructMetaData].structClass must be(classOf[MyException]) + listMetaData.elemMetaData.asInstanceOf[StructMetaData].structClass must be( + classOf[MyException] + ) } "for set of exceptions field" in { val fieldValueMetaData = metadata("exceptionSetField").valueMetaData - + fieldValueMetaData.`type` must be(TType.SET) fieldValueMetaData mustBe a[SetMetaData] val setMetaData = fieldValueMetaData.asInstanceOf[SetMetaData] setMetaData.elemMetaData.`type` must be(TType.STRUCT) setMetaData.elemMetaData mustBe a[StructMetaData] - setMetaData.elemMetaData.asInstanceOf[StructMetaData].structClass must be(classOf[MyException]) + setMetaData.elemMetaData.asInstanceOf[StructMetaData].structClass must be( + classOf[MyException] + ) } "for map exception to string field" in { val fieldValueMetaData = metadata("exceptionToStringMapField").valueMetaData - + fieldValueMetaData.`type` must be(TType.MAP) fieldValueMetaData mustBe a[MapMetaData] val mapMetaData = fieldValueMetaData.asInstanceOf[MapMetaData] mapMetaData.keyMetaData.`type` must be(TType.STRUCT) mapMetaData.keyMetaData mustBe a[StructMetaData] - mapMetaData.keyMetaData.asInstanceOf[StructMetaData].structClass must be(classOf[MyException]) + mapMetaData.keyMetaData.asInstanceOf[StructMetaData].structClass must be( + classOf[MyException] + ) mapMetaData.valueMetaData.`type` must be(TType.STRING) } "for map string to exceptions field" in { val fieldValueMetaData = metadata("stringToExceptionMapField").valueMetaData - + fieldValueMetaData.`type` must be(TType.MAP) fieldValueMetaData mustBe a[MapMetaData] @@ -80,7 +85,9 @@ class ApacheJavaMetadataSpec extends Spec { mapMetaData.keyMetaData.`type` must be(TType.STRING) mapMetaData.valueMetaData.`type` must be(TType.STRUCT) mapMetaData.valueMetaData mustBe a[StructMetaData] - mapMetaData.valueMetaData.asInstanceOf[StructMetaData].structClass must be(classOf[MyException]) + mapMetaData.valueMetaData.asInstanceOf[StructMetaData].structClass must be( + classOf[MyException] + ) } } } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/GeneratorFactorySpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/GeneratorFactorySpec.scala index f666e200e..a968a94d7 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/GeneratorFactorySpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/GeneratorFactorySpec.scala @@ -26,7 +26,8 @@ class GeneratorFactorySpec extends Spec { "test", ResolvedDocument(new Document(Seq(), Seq()), TypeResolver()), "", - Seq.empty[String]) + Seq.empty[String] + ) generator.isInstanceOf[ScalaGenerator] must be(true) } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ImmutableStructSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ImmutableStructSpec.scala index 97294f718..7661da6b4 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ImmutableStructSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ImmutableStructSpec.scala @@ -29,7 +29,9 @@ class ImmutableStructSpec extends Spec { xtruct, 321 ) - val nested = NestedXtruct(xtruct, xtruct2, + val nested = NestedXtruct( + xtruct, + xtruct2, Xtruct3( "string_thing", 456, @@ -50,8 +52,8 @@ class ImmutableStructSpec extends Spec { ) ) copied.x1 must be(nested.x1) - copied.x2.structThing must not be(nested.x2.structThing) //swapped - copied.x2 must not be(nested.x2) + copied.x2.structThing must not be (nested.x2.structThing) //swapped + copied.x2 must not be (nested.x2) copied.x3 must be(nested.x3) } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala index 47704450e..cadba7142 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala @@ -16,7 +16,7 @@ class NonFinagleSpec extends Spec { Seq(chicago, nyc) .filter { airport => inRegion(airport.loc, nw, se) - } + } } def hasWifi(a: Airport) = Try { @@ -30,9 +30,9 @@ class NonFinagleSpec extends Spec { private[this] def inRegion(loc: Location, nw: Location, se: Location) = loc.latitude < nw.latitude && - loc.latitude > se.latitude && - loc.longitude > nw.longitude && - loc.longitude < se.longitude + loc.latitude > se.latitude && + loc.longitude > nw.longitude && + loc.longitude < se.longitude } service.hasWifi(chicago).get() must be(true) service.hasWifi(nyc).get() must be(false) @@ -40,7 +40,7 @@ class NonFinagleSpec extends Spec { intercept[AirportException] { service.hasWifi(sfo).get() } - service.fetchAirportsInBounds(Location(500,0), Location(0, 500))() must be(Seq(chicago)) + service.fetchAirportsInBounds(Location(500, 0), Location(0, 500))() must be(Seq(chicago)) } } } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala index dac468175..b4acf2a1d 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala @@ -39,12 +39,16 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { includes.b.thriftscala.Constants.name1.last must be("l1") includes.b.thriftscala.Constants.name1.address.street must be("some street") includes.b.thriftscala.Constants.name1.address.city match { - case includes.a.thriftscala.City.CityState(includes.a.thriftscala.CityState(city, state)) => { + case includes.a.thriftscala.City + .CityState(includes.a.thriftscala.CityState(city, state)) => { city must be("San Francisco") state must be("CA") } - case _ => fail("City not specified as city_state " + - includes.b.thriftscala.Constants.name1.address.city) + case _ => + fail( + "City not specified as city_state " + + includes.b.thriftscala.Constants.name1.address.city + ) } } @@ -255,7 +259,8 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { val eStruct = EnumCollections( aMap = Map(NumberID.One -> NumberID.Two), aList = List(NumberID.One), - aSet = Set(NumberID.One)) + aSet = Set(NumberID.One) + ) EnumCollections.encode(eStruct, prot) EnumCollections.decode(prot) must be(eStruct) @@ -298,10 +303,12 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { thrift.test.Constants.emptyList must be(List()) thrift.test.Constants.someMap must be(Map("foo" -> "bar")) thrift.test.Constants.someSimpleSet must be(Set("foo", "bar")) - thrift.test.Constants.someSet must be(Set( - List("piggy"), - List("kitty") - )) + thrift.test.Constants.someSet must be( + Set( + List("piggy"), + List("kitty") + ) + ) thrift.test.Constants.long_key_long_value_map(2147483648L) must be(2147483648L) thrift.test.Constants.long_set.contains(2147483648L) must be(true) thrift.test.Constants.long_list.contains(2147483648L) must be(true) @@ -312,9 +319,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { "basic structs" should { "ints" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("baby", TType.I16, 1)) one(protocol).readI16(); will(returnValue((16: Short))) nextRead(e, protocol, new TField("mama", TType.I32, 2)) @@ -329,9 +338,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("baby", TType.I16, 1)) one(protocol).writeI16(`with`(Expectations.equal(16: Short))) nextWrite(e, protocol, new TField("mama", TType.I32, 2)) @@ -348,9 +359,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "bytes" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("x", TType.BYTE, 1)) one(protocol).readByte(); will(returnValue(3.toByte)) nextRead(e, protocol, new TField("y", TType.STRING, 2)) @@ -365,9 +378,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("x", TType.BYTE, 1)) one(protocol).writeByte(`with`(Expectations.equal(16.toByte))) nextWrite(e, protocol, new TField("y", TType.STRING, 2)) @@ -382,9 +397,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "bool, double, string" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("alive", TType.BOOL, 1)) one(protocol).readBool(); will(returnValue(true)) nextRead(e, protocol, new TField("pi", TType.DOUBLE, 2)) @@ -399,9 +416,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("alive", TType.BOOL, 1)) one(protocol).writeBool(`with`(Expectations.equal(false))) nextWrite(e, protocol, new TField("pi", TType.DOUBLE, 2)) @@ -422,11 +441,14 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { intlist = List(10, 20), intset = Set(44, 55), namemap = Map("wendy" -> 500), - nested = List(Set(9))) + nested = List(Set(9)) + ) - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("intlist", TType.LIST, 1)) one(protocol).readListBegin(); will(returnValue(new TList(TType.I32, 2))) one(protocol).readI32(); will(returnValue(10)) @@ -456,9 +478,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("intlist", TType.LIST, 1)) one(protocol).writeListBegin(`with`(listEqual(new TList(TType.I32, 2)))) one(protocol).writeI32(`with`(Expectations.equal(10))) @@ -492,9 +516,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { "complicated structs" should { "with required fields" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("string", TType.STRING, 1)) one(protocol).readString(); will(returnValue("yo")) endRead(e, protocol) @@ -506,7 +532,8 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "missing required value throws exception during deserialization" should { - "with no default value" in { cycle => import cycle._ + "with no default value" in { cycle => + import cycle._ val protocol = mock[TProtocol] expecting { e => emptyRead(e, protocol) @@ -519,7 +546,8 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "with default value" in { cycle => import cycle._ + "with default value" in { cycle => + import cycle._ val protocol = mock[TProtocol] expecting { e => emptyRead(e, protocol) @@ -534,7 +562,8 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "null required value throws exception during serialization" should { - "with no default value" in { cycle => import cycle._ + "with no default value" in { cycle => + import cycle._ val protocol = mock[TProtocol] whenExecuting { @@ -544,7 +573,8 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "with default value" in { cycle => import cycle._ + "with default value" in { cycle => + import cycle._ val protocol = mock[TProtocol] whenExecuting { @@ -578,9 +608,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "with optional fields" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("name", TType.STRING, 1)) one(protocol).readString(); will(returnValue("Commie")) nextRead(e, protocol, new TField("age", TType.I32, 2)) @@ -593,9 +625,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "read with missing field" in { cycle => import cycle._ + "read with missing field" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("name", TType.STRING, 1)) one(protocol).readString(); will(returnValue("Commie")) endRead(e, protocol) @@ -606,9 +640,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("name", TType.STRING, 1)) one(protocol).writeString(`with`(Expectations.equal("Commie"))) nextWrite(e, protocol, new TField("age", TType.I32, 2)) @@ -621,9 +657,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write with missing field" in { cycle => import cycle._ + "write with missing field" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("name", TType.STRING, 1)) one(protocol).writeString(`with`(Expectations.equal("Commie"))) endWrite(e, protocol) @@ -636,9 +674,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "with default values" should { - "read with value missing, using default" in { cycle => import cycle._ + "read with value missing, using default" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ one(protocol).readStructBegin() one(protocol).readFieldBegin(); will(returnValue(new TField("stop", TType.STOP, 10))) one(protocol).readStructEnd() @@ -649,9 +689,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "read with value present" in { cycle => import cycle._ + "read with value present" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ one(protocol).readStructBegin() nextRead(e, protocol, new TField("name", TType.STRING, 1)) one(protocol).readString(); will(returnValue("delilah")) @@ -666,9 +708,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "nested" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("name", TType.STRING, 1)) one(protocol).readString(); will(returnValue("United States of America")) nextRead(e, protocol, new TField("provinces", TType.LIST, 2)) @@ -684,22 +728,27 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { nextRead(e, protocol, new TField("age", TType.I32, 2)) one(protocol).readI32(); will(returnValue(42)) endRead(e, protocol) - /** End of Emperor struct **/ + /** End of Emperor struct **/ endRead(e, protocol) } whenExecuting { - Empire.decode(protocol) must be(Empire( - "United States of America", - List("connecticut", "california"), - Emperor("Bush", 42))) + Empire.decode(protocol) must be( + Empire( + "United States of America", + List("connecticut", "california"), + Emperor("Bush", 42) + ) + ) } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("name", TType.STRING, 1)) one(protocol).writeString(`with`(Expectations.equal("Canada"))) nextWrite(e, protocol, new TField("provinces", TType.LIST, 2)) @@ -761,7 +810,7 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "hashCode is different for two different objects" in { _ => - Biggie(num10 = -5).hashCode must not be(Biggie().hashCode) + Biggie(num10 = -5).hashCode must not be (Biggie().hashCode) } "toString" in { _ => @@ -799,7 +848,8 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "zero fields" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] expecting { e => emptyRead(e, protocol) @@ -812,7 +862,8 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] whenExecuting { intercept[TProtocolException] { @@ -823,9 +874,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "one field" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("hummingbird", TType.STRING, 2)) one(protocol).readString(); will(returnValue("Ruby-Throated")) endRead(e, protocol) @@ -836,9 +889,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("owlet_nightjar", TType.STRING, 3)) one(protocol).writeString(`with`(Expectations.equal("foo"))) endWrite(e, protocol) @@ -851,9 +906,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "more than one field" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("hummingbird", TType.STRING, 2)) one(protocol).readString(); will(returnValue("Anna's Hummingbird")) nextRead(e, protocol, new TField("owlet_nightjar", TType.STRING, 3)) @@ -872,9 +929,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "nested struct" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("raptor", TType.STRUCT, 1)) startRead(e, protocol, new TField("isOwl", TType.BOOL, 1)) one(protocol).readBool(); will(returnValue(false)) @@ -889,9 +948,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("raptor", TType.STRUCT, 1)) startWrite(e, protocol, new TField("isOwl", TType.BOOL, 1)) one(protocol).writeBool(`with`(Expectations.equal(true))) @@ -908,9 +969,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "collection" should { - "read" in { cycle => import cycle._ + "read" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("flock", TType.LIST, 4)) one(protocol).readListBegin(); will(returnValue(new TList(TType.STRING, 3))) one(protocol).readString(); will(returnValue("starling")) @@ -925,9 +988,11 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } } - "write" in { cycle => import cycle._ + "write" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("flock", TType.LIST, 4)) one(protocol).writeListBegin(`with`(listEqual(new TList(TType.STRING, 3)))) one(protocol).writeString(`with`(Expectations.equal("starling"))) @@ -1087,7 +1152,7 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { checkInside(PassThrough6.withoutPassthroughFields(pt6)) must be(true) } - "be able to add more" in { _ => + "be able to add more" in { _ => val pt1 = PassThrough(1) val pt2 = PassThrough2(1, PassThroughStruct(), null) val f2 = pt2.getFieldBlob(PassThrough2.F2Field.id).get @@ -1102,7 +1167,7 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { pt2roundTripped must be(pt2) } - "be proxy-able" in { _ => + "be proxy-able" in { _ => val pt2 = PassThrough2(1, PassThroughStruct(), PassThroughStruct()) val pt1 = { @@ -1153,7 +1218,9 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { } "generate with special scala namespace syntax" in { _ => - scrooge.test.thriftscala.Thingymabob().isInstanceOf[scrooge.test.thriftscala.Thingymabob] must be(true) + scrooge.test.thriftscala + .Thingymabob() + .isInstanceOf[scrooge.test.thriftscala.Thingymabob] must be(true) } "generate productElement correctly" in { _ => @@ -1187,8 +1254,9 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { def apply(args: Bbb.GetInt.Args) = Future.value(5) }, getBox = new Service[Aaa.GetBox.Args, Aaa.GetBox.SuccessType] { - def apply(args: Aaa.GetBox.Args) = Future.value(Box(4,6)) - }) + def apply(args: Aaa.GetBox.Args) = Future.value(Box(4, 6)) + } + ) Await.result(dddService.getInt(Bbb.GetInt.Args()), 5.seconds) must be(5) } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala index 03dfd71e2..6727d7eb6 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala @@ -4,7 +4,15 @@ import com.twitter.conversions.time._ import com.twitter.finagle import com.twitter.finagle.param.Stats import com.twitter.finagle.service.{ResponseClass, ResponseClassifier, ReqRep} -import com.twitter.finagle.{Address, ListeningServer, Name, Thrift, Service, SimpleFilter, SourcedException} +import com.twitter.finagle.{ + Address, + ListeningServer, + Name, + Thrift, + Service, + SimpleFilter, + SourcedException +} import com.twitter.finagle.stats.InMemoryStatsReceiver import com.twitter.finagle.thrift.ThriftClientRequest import com.twitter.scrooge.ThriftException @@ -55,10 +63,12 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { Await.result(result) must be(-1) } - "generate structs for args and return value" in { cycle => import cycle._ + "generate structs for args and return value" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("where", TType.STRING, 1)) one(protocol).readString(); will(returnValue("boston")) endRead(e, protocol) @@ -68,7 +78,8 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { SimpleService.Deliver.Args.decode(protocol).where must be("boston") } - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("where", TType.STRING, 1)) one(protocol).writeString("atlanta") endWrite(e, protocol) @@ -78,7 +89,8 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { SimpleService.Deliver.Args("atlanta").write(protocol) must be(()) } - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("success", TType.I32, 0)) one(protocol).readI32(); will(returnValue(13)) endRead(e, protocol) @@ -88,7 +100,8 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { SimpleService.Deliver.Result.decode(protocol).success must be(Some(13)) } - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("success", TType.I32, 0)) one(protocol).writeI32(24) endWrite(e, protocol) @@ -99,10 +112,12 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { } } - "generate unions for args and return value" in { cycle => import cycle._ + "generate unions for args and return value" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("arg0", TType.STRUCT, 1)) startRead(e, protocol, new TField("bools", TType.STRUCT, 2)) startRead(e, protocol, new TField("im_true", TType.BOOL, 1)) @@ -116,10 +131,12 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { whenExecuting { ThriftTest.TestUnions.Args.decode(protocol).arg0 must be( - MorePerfectUnion.Bools(Bools(true, false))) + MorePerfectUnion.Bools(Bools(true, false)) + ) } - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("arg0", TType.STRUCT, 1)) startWrite(e, protocol, new TField("bonk", TType.STRUCT, 1)) startWrite(e, protocol, new TField("message", TType.STRING, 1)) @@ -132,12 +149,15 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { } whenExecuting { - ThriftTest.TestUnions.Args( - MorePerfectUnion.Bonk(Bonk("hello world", 42)) - ).write(protocol) must be(()) + ThriftTest.TestUnions + .Args( + MorePerfectUnion.Bonk(Bonk("hello world", 42)) + ) + .write(protocol) must be(()) } - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("success", TType.STRUCT, 0)) startRead(e, protocol, new TField("bools", TType.STRUCT, 2)) startRead(e, protocol, new TField("im_true", TType.BOOL, 1)) @@ -151,10 +171,12 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { whenExecuting { ThriftTest.TestUnions.Result.decode(protocol).success must be( - Some(MorePerfectUnion.Bools(Bools(true, false)))) + Some(MorePerfectUnion.Bools(Bools(true, false))) + ) } - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("success", TType.STRUCT, 0)) startWrite(e, protocol, new TField("bonk", TType.STRUCT, 1)) startWrite(e, protocol, new TField("message", TType.STRING, 1)) @@ -167,16 +189,20 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { } whenExecuting { - ThriftTest.TestUnions.Result( - Some(MorePerfectUnion.Bonk(Bonk("hello world", 42))) - ).write(protocol) must be(()) + ThriftTest.TestUnions + .Result( + Some(MorePerfectUnion.Bonk(Bonk("hello world", 42))) + ) + .write(protocol) must be(()) } } - "generate exception return values" in { cycle => import cycle._ + "generate exception return values" in { cycle => + import cycle._ val protocol = mock[TProtocol] - expecting { e => import e._ + expecting { e => + import e._ startRead(e, protocol, new TField("ex", TType.STRUCT, 1)) startRead(e, protocol, new TField("errorCode", TType.I32, 1)) one(protocol).readI32(); will(returnValue(1)) @@ -193,7 +219,8 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { res.ex2 must be(None) } - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("success", TType.I32, 0)) one(protocol).writeI32(24) endWrite(e, protocol) @@ -203,7 +230,8 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { ExceptionalService.Deliver.Result(Some(24)).write(protocol) must be(()) } - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("ex", TType.STRUCT, 1)) startWrite(e, protocol, new TField("errorCode", TType.I32, 1)) one(protocol).writeI32(`with`(Expectations.equal(1))) @@ -214,10 +242,13 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { } whenExecuting { - ExceptionalService.Deliver.Result(None, Some(Xception(1, "silly"))).write(protocol) must be(()) + ExceptionalService.Deliver.Result(None, Some(Xception(1, "silly"))).write(protocol) must be( + () + ) } - expecting { e => import e._ + expecting { e => + import e._ startWrite(e, protocol, new TField("ex3", TType.STRUCT, 3)) one(protocol).writeStructBegin(`with`(any(classOf[TStruct]))) one(protocol).writeFieldStop() @@ -226,7 +257,9 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { } whenExecuting { - ExceptionalService.Deliver.Result(None, None, None, Some(EmptyXception())).write(protocol) must be(()) + ExceptionalService.Deliver + .Result(None, None, None, Some(EmptyXception())) + .write(protocol) must be(()) } } @@ -240,7 +273,8 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "success" in { _ => val request = encodeRequest("deliver", ExceptionalService.Deliver.Args("Boston")).message - val response = encodeResponse("deliver", ExceptionalService.Deliver.Result(success = Some(42))) + val response = + encodeResponse("deliver", ExceptionalService.Deliver.Result(success = Some(42))) context.checking(new Expectations { one(impl).deliver("Boston"); will(returnValue(Future.value(42))) @@ -272,7 +306,8 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val clientService = new finagle.Service[ThriftClientRequest, Array[Byte]] { def apply(req: ThriftClientRequest) = service(req.message) } - val client = new ExceptionalService$FinagleClient(clientService, serviceName="ExceptionalService") + val client = + new ExceptionalService$FinagleClient(clientService, serviceName = "ExceptionalService") "set service name" in { _ => client.serviceName must be("ExceptionalService") @@ -376,7 +411,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val service = new Capsly$FinagleService(null, null) { def getFunction2(name: String) = functionMap(name) } - service.getFunction2("Bad_Name") must not be(None) + service.getFunction2("Bad_Name") must not be (None) } "generate a finagle Service per method" should { @@ -387,11 +422,14 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { new InetSocketAddress(InetAddress.getLoopbackAddress, 0), new SimpleService[Future] { def deliver(where: String) = Future.value(3) - }) + } + ) val simpleService: SimpleService.ServiceIface = Thrift.client.newServiceIface[SimpleService.ServiceIface]( - Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), "simple") + Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), + "simple" + ) Await.result(simpleService.deliver(Deliver.Args("Boston")), 5.seconds) must be(3) Await.result(server.close(), 2.seconds) @@ -414,14 +452,24 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { ) val readOnlyClientService = Thrift.client.newServiceIface[ReadOnlyService.ServiceIface]( - Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), "read-only") - Await.result(readOnlyClientService.getName(GetName.Args()), 5.seconds) must be ("Initial name") + Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), + "read-only" + ) + Await.result(readOnlyClientService.getName(GetName.Args()), 5.seconds) must be( + "Initial name" + ) val readWriteClientService = Thrift.client.newServiceIface[ReadWriteService.ServiceIface]( - Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), "read-write") - Await.result(readWriteClientService.getName(GetName.Args()), 5.seconds) must be ("Initial name") + Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), + "read-write" + ) + Await.result(readWriteClientService.getName(GetName.Args()), 5.seconds) must be( + "Initial name" + ) - Await.result(readWriteClientService.setName(SetName.Args("New name")), 5.seconds) must be(()) + Await.result(readWriteClientService.setName(SetName.Args("New name")), 5.seconds) must be( + () + ) Await.result(readOnlyClientService.getName(GetName.Args()), 5.seconds) must be("New name") @@ -451,7 +499,9 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val server = serveExceptionalService() val clientService = Thrift.client.newServiceIface[ExceptionalService.ServiceIface]( - Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), "client") + Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), + "client" + ) intercept[EmptyXception] { Await.result(clientService.deliver(Deliver.Args("")), 5.seconds) @@ -466,18 +516,22 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { new InetSocketAddress(InetAddress.getLoopbackAddress, 0), new SimpleService[Future] { def deliver(input: String) = Future.value(input.length) - }) + } + ) val simpleServiceIface: SimpleService.ServiceIface = Thrift.client.newServiceIface[SimpleService.ServiceIface]( - Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), "simple") + Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), + "simple" + ) val doubleFilter = new SimpleFilter[Deliver.Args, Deliver.SuccessType] { def apply(args: Deliver.Args, service: Service[Deliver.Args, Deliver.SuccessType]) = service(args.copy(where = args.where + args.where)) } - val filteredServiceIface = simpleServiceIface.copy(deliver = doubleFilter andThen simpleServiceIface.deliver) + val filteredServiceIface = + simpleServiceIface.copy(deliver = doubleFilter andThen simpleServiceIface.deliver) val methodIface = Thrift.client.newMethodIface(filteredServiceIface) Await.result(methodIface.deliver("123")) must be(6) @@ -490,7 +544,9 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val service = serveExceptionalService() val clientService = Thrift.client.newServiceIface[ExceptionalService.ServiceIface]( - Name.bound(Address(service.boundAddress.asInstanceOf[InetSocketAddress])), "client") + Name.bound(Address(service.boundAddress.asInstanceOf[InetSocketAddress])), + "client" + ) val retryPolicy = RetryPolicy.tries[Try[Int]](3, { @@ -501,7 +557,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val retriedDeliveryService = new RetryExceptionsFilter(retryPolicy, new JavaTimer(true)) andThen clientService.deliver - Await.result(retriedDeliveryService(Deliver.Args("there"))) must be (123) + Await.result(retriedDeliveryService(Deliver.Args("there"))) must be(123) Await.result(service.close(), 2.seconds) } @@ -509,7 +565,9 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "work with a newMethodIface" in { _ => val service = serveExceptionalService() val clientService = Thrift.client.newServiceIface[ExceptionalService.ServiceIface]( - Name.bound(Address(service.boundAddress.asInstanceOf[InetSocketAddress])), "client") + Name.bound(Address(service.boundAddress.asInstanceOf[InetSocketAddress])), + "client" + ) val futureIface = Thrift.client.newMethodIface(clientService) @@ -533,7 +591,9 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { ) val client = Thrift.client.newServiceIface[CamelCaseSnakeCaseService.ServiceIface]( - Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), "client") + Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), + "client" + ) val richClient = Thrift.client.newMethodIface(client) Await.result(richClient.fooBar("foo")) mustBe "foo" @@ -545,10 +605,12 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "have correct stats" in { _ => val service = serveExceptionalService() val statsReceiver = new InMemoryStatsReceiver - val clientService = Thrift.client. - configured(Stats(statsReceiver)). - newServiceIface[ExceptionalService.ServiceIface]( - Name.bound(Address(service.boundAddress.asInstanceOf[InetSocketAddress])), "customServiceName") + val clientService = Thrift.client + .configured(Stats(statsReceiver)) + .newServiceIface[ExceptionalService.ServiceIface]( + Name.bound(Address(service.boundAddress.asInstanceOf[InetSocketAddress])), + "customServiceName" + ) val futureIface = Thrift.client.newMethodIface(clientService) @@ -556,9 +618,27 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { Await.result(futureIface.deliver(where = "abc")) } - eventually { statsReceiver.counters(Seq("customServiceName", "ExceptionalService", "deliver", "requests")) must be (1) } - eventually { statsReceiver.counters(Seq("customServiceName", "ExceptionalService", "deliver", "failures")) must be (1) } - eventually { statsReceiver.counters(Seq("customServiceName", "ExceptionalService", "deliver", "failures", "thrift.test.Xception")) must be (1) } + eventually { + statsReceiver.counters( + Seq("customServiceName", "ExceptionalService", "deliver", "requests") + ) must be(1) + } + eventually { + statsReceiver.counters( + Seq("customServiceName", "ExceptionalService", "deliver", "failures") + ) must be(1) + } + eventually { + statsReceiver.counters( + Seq( + "customServiceName", + "ExceptionalService", + "deliver", + "failures", + "thrift.test.Xception" + ) + ) must be(1) + } intercept[Xception] { Await.result(futureIface.deliver(where = "abc")) @@ -567,10 +647,32 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { // The 3rd request succeeds Await.result(futureIface.deliver(where = "abc")) - eventually { statsReceiver.counters(Seq("customServiceName", "ExceptionalService", "deliver", "requests")) must be (3) } - eventually { statsReceiver.counters(Seq("customServiceName", "ExceptionalService", "deliver", "success")) must be (1) } - eventually { statsReceiver.counters(Seq("customServiceName", "ExceptionalService", "deliver", "failures")) must be (2) } - eventually { statsReceiver.counters(Seq("customServiceName", "ExceptionalService", "deliver", "failures", "thrift.test.Xception")) must be (2) } + eventually { + statsReceiver.counters( + Seq("customServiceName", "ExceptionalService", "deliver", "requests") + ) must be(3) + } + eventually { + statsReceiver.counters( + Seq("customServiceName", "ExceptionalService", "deliver", "success") + ) must be(1) + } + eventually { + statsReceiver.counters( + Seq("customServiceName", "ExceptionalService", "deliver", "failures") + ) must be(2) + } + eventually { + statsReceiver.counters( + Seq( + "customServiceName", + "ExceptionalService", + "deliver", + "failures", + "thrift.test.Xception" + ) + ) must be(2) + } Await.result(service.close(), 2.seconds) } @@ -591,7 +693,10 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val clientService = Thrift.client .withStatsReceiver(stats) .withResponseClassifier(bigNumsAreFailures) - .newService(Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), "client") + .newService( + Name.bound(Address(server.boundAddress.asInstanceOf[InetSocketAddress])), + "client" + ) val svc = new SimpleService.FinagledClient( clientService, @@ -619,10 +724,12 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "have stats with serviceName not set" in { _ => val service = serveExceptionalService() val statsReceiver = new InMemoryStatsReceiver - val clientService = Thrift.client. - configured(Stats(statsReceiver)). - newServiceIface[ExceptionalService.ServiceIface]( - Name.bound(Address(service.boundAddress.asInstanceOf[InetSocketAddress])), "client") + val clientService = Thrift.client + .configured(Stats(statsReceiver)) + .newServiceIface[ExceptionalService.ServiceIface]( + Name.bound(Address(service.boundAddress.asInstanceOf[InetSocketAddress])), + "client" + ) val futureIface = Thrift.client.newMethodIface(clientService) @@ -630,7 +737,11 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { Await.result(futureIface.deliver(where = "abc")) } - eventually { statsReceiver.counters(Seq("client", "ExceptionalService", "deliver", "requests")) must be (1) } + eventually { + statsReceiver.counters(Seq("client", "ExceptionalService", "deliver", "requests")) must be( + 1 + ) + } Await.result(service.close(), 2.seconds) } @@ -644,7 +755,6 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val service = new thrift.test.Service$FinagleService(impl, new TBinaryProtocol.Factory) "allow generation and calls to eponymous FinagledService" in { _ => - context.checking(new Expectations { one(impl).test(); will(returnValue(Future.value(()))) }) @@ -658,7 +768,6 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { } "allow generation and calls to eponymous FinagledClient" in { _ => - val clientService = new finagle.Service[ThriftClientRequest, Array[Byte]] { def apply(req: ThriftClientRequest) = service(req.message) } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/cocoa_generator/CocoaGeneratorSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/cocoa_generator/CocoaGeneratorSpec.scala index c11ed8702..49af8a197 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/cocoa_generator/CocoaGeneratorSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/cocoa_generator/CocoaGeneratorSpec.scala @@ -7,26 +7,27 @@ import com.google.common.io.CharStreams import com.twitter.scrooge.testutil.{Spec, TempDirectory} import com.twitter.scrooge.testutil.Utils.verify - class CocoaGeneratorSpec extends Spec { - val templateFiles = List("cocoa_output/TFNTwitterThriftScribeAnotherTestStruct.h", - "cocoa_output/TFNTwitterThriftScribeAnotherTestStruct.m", - "cocoa_output/TFNTwitterThriftScribeTestEnum.h", - "cocoa_output/TFNTwitterThriftScribeTestStruct.h", - "cocoa_output/TFNTwitterThriftScribeTestStruct.m").map{new File(_)} + val templateFiles = List( + "cocoa_output/TFNTwitterThriftScribeAnotherTestStruct.h", + "cocoa_output/TFNTwitterThriftScribeAnotherTestStruct.m", + "cocoa_output/TFNTwitterThriftScribeTestEnum.h", + "cocoa_output/TFNTwitterThriftScribeTestStruct.h", + "cocoa_output/TFNTwitterThriftScribeTestStruct.m" + ).map { new File(_) } def getFileContents(resource: String): String = { val ccl = Thread.currentThread().getContextClassLoader val is = ccl.getResourceAsStream(resource) match { - case null => new FileInputStream(resource) - case input: InputStream => input + case null => new FileInputStream(resource) + case input: InputStream => input } val br = new BufferedReader(new InputStreamReader(is, Charsets.UTF_8)) CharStreams.toString(br) } - def getListOfFiles(d: File):List[File] = { + def getListOfFiles(d: File): List[File] = { if (d.exists && d.isDirectory) { d.listFiles.filter(_.isFile).toList } else { @@ -40,17 +41,17 @@ class CocoaGeneratorSpec extends Spec { val ccl = Thread.currentThread().getContextClassLoader val inputThrift = ccl.getResource("test_thrift/cocoa.thrift").getPath() - val args = Array[String]( - "-l", "cocoa", - "-d", tempDir.getPath, - inputThrift) + val args = Array[String]("-l", "cocoa", "-d", tempDir.getPath, inputThrift) Main.main(args) val generated_flist = getListOfFiles(tempDir) "generate some .m .h files" in { - assert(templateFiles.size == generated_flist.size, "missing file, generated files are:" - + generated_flist.toString()) + assert( + templateFiles.size == generated_flist.size, + "missing file, generated files are:" + + generated_flist.toString() + ) } "generate proper content inside files" in { diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/ImporterSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/ImporterSpec.scala index 9a449b9ec..d70850fa0 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/ImporterSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/ImporterSpec.scala @@ -71,7 +71,9 @@ class ImporterSpec extends Spec { val importer = Importer(Seq(folder1.getAbsolutePath, folder2.getAbsolutePath)) - importer.getResolvedPath("a.thrift") must be(Some(new File(testFolder, "f2/a.thrift").getCanonicalPath)) + importer.getResolvedPath("a.thrift") must be( + Some(new File(testFolder, "f2/a.thrift").getCanonicalPath) + ) importer.getResolvedPath("b.thrift") must be(None) importer.getResolvedPath("f2/a.thrift") must be(None) } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/ThriftParserSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/ThriftParserSpec.scala index 51b612c99..c927a1a24 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/ThriftParserSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/ThriftParserSpec.scala @@ -26,7 +26,7 @@ class ThriftParserSpec extends Spec { } "comments with Windows-style carriage return" in { - commentTestSources.map(_.replace("\n","\r\n")).foreach(verifyCommentParsing) + commentTestSources.map(_.replace("\n", "\r\n")).foreach(verifyCommentParsing) } "comments with parens" in { @@ -35,8 +35,8 @@ class ThriftParserSpec extends Spec { struct MyStruct {} """ parser.parse(source, parser.document) match { - case Document(List(),List(Struct(SimpleID("MyStruct", None), "MyStruct", List(), - None, m))) if m.isEmpty => + case Document(List(), List(Struct(SimpleID("MyStruct", None), "MyStruct", List(), None, m))) + if m.isEmpty => case x => fail(s"Failed to match $x") } } @@ -44,7 +44,9 @@ struct MyStruct {} "double-quoted strings" in { parser.parse(""" "hello!" """, parser.rhs) must be(StringLiteral("hello!")) parser.parse(""" "hello\nthere!" """, parser.rhs) must be(StringLiteral("""hello\nthere!""")) - parser.parse(""" "hello\\nthere!" """, parser.rhs) must be(StringLiteral("""hello\\nthere!""")) + parser.parse(""" "hello\\nthere!" """, parser.rhs) must be( + StringLiteral("""hello\\nthere!""") + ) parser.parse(""" "hello//there!" """, parser.rhs) must be(StringLiteral("""hello//there!""")) parser.parse(""" "hello'there!" """, parser.rhs) must be(StringLiteral("""hello'there!""")) parser.parse(""" "hello\'there!" """, parser.rhs) must be(StringLiteral("""hello\'there!""")) @@ -55,7 +57,9 @@ struct MyStruct {} "single-quoted strings" in { parser.parse(""" 'hello!' """, parser.rhs) must be(StringLiteral("hello!")) parser.parse(""" 'hello\nthere!' """, parser.rhs) must be(StringLiteral("""hello\nthere!""")) - parser.parse(""" 'hello\\nthere!' """, parser.rhs) must be(StringLiteral("""hello\\nthere!""")) + parser.parse(""" 'hello\\nthere!' """, parser.rhs) must be( + StringLiteral("""hello\\nthere!""") + ) parser.parse(""" 'hello//there!' """, parser.rhs) must be(StringLiteral("""hello//there!""")) parser.parse(""" 'hello"there!' """, parser.rhs) must be(StringLiteral("""hello"there!""")) parser.parse(""" 'hello\"there!' """, parser.rhs) must be(StringLiteral("""hello\"there!""")) @@ -69,9 +73,14 @@ struct MyStruct {} val list = parser.parse("[ 4, 5, ]", parser.rhs) list.isInstanceOf[ListRHS] must be(true) list.asInstanceOf[ListRHS].elems.toList must be(List(IntLiteral(4), IntLiteral(5))) - parser.parse("{ 'name': 'Commie', 'home': 'San Francisco', }", - parser.rhs) must be(MapRHS(Seq(StringLiteral("name") -> StringLiteral - ("Commie"), StringLiteral("home") -> StringLiteral("San Francisco")))) + parser.parse("{ 'name': 'Commie', 'home': 'San Francisco', }", parser.rhs) must be( + MapRHS( + Seq( + StringLiteral("name") -> StringLiteral("Commie"), + StringLiteral("home") -> StringLiteral("San Francisco") + ) + ) + ) } "base types" in { @@ -87,30 +96,61 @@ struct MyStruct {} "compound types" in { parser.parse("list", parser.fieldType) must be(ListType(TI64, None)) - parser.parse("list>", parser.fieldType) must be(ListType(ListType(TString, - None), None)) - parser.parse("map>", parser.fieldType) must be(MapType(TString, - ListType(TBool, None), None)) - parser.parse("set", parser.fieldType) must be(SetType(ReferenceType(Identifier("Monster")), - None)) + parser.parse("list>", parser.fieldType) must be( + ListType(ListType(TString, None), None) + ) + parser.parse("map>", parser.fieldType) must be( + MapType(TString, ListType(TBool, None), None) + ) + parser.parse("set", parser.fieldType) must be( + SetType(ReferenceType(Identifier("Monster")), None) + ) parser.parse("Monster", parser.fieldType) must be(ReferenceType(Identifier("Monster"))) } "functions" in { parser.parse("/**doc!*/ void go()", parser.function) must be( - Function(SimpleID("go"), "go", Void, Seq(), Seq(), Some("/**doc!*/"))) + Function(SimpleID("go"), "go", Void, Seq(), Seq(), Some("/**doc!*/")) + ) parser.parse( "list get_tables(optional i32 id, /**DOC*/3: required string name='cat') throws (1: Exception ex);", - parser.function) must be( - Function(SimpleID("get_tables"), "get_tables", ListType(TString, None), Seq( - Field(-1, SimpleID("id"), "id", TI32, None, Requiredness.Optional), - Field(3, SimpleID("name"), "name", TString, Some(StringLiteral("cat")), Requiredness.Required, docstring = Some("/**DOC*/")) - ), Seq(Field(1, SimpleID("ex"), "ex", ReferenceType(Identifier("Exception")), None, Requiredness.Default)), None)) + parser.function + ) must be( + Function( + SimpleID("get_tables"), + "get_tables", + ListType(TString, None), + Seq( + Field(-1, SimpleID("id"), "id", TI32, None, Requiredness.Optional), + Field( + 3, + SimpleID("name"), + "name", + TString, + Some(StringLiteral("cat")), + Requiredness.Required, + docstring = Some("/**DOC*/") + ) + ), + Seq( + Field( + 1, + SimpleID("ex"), + "ex", + ReferenceType(Identifier("Exception")), + None, + Requiredness.Default + ) + ), + None + ) + ) } "const" in { - parser.parse("/** COMMENT */ const string name = \"Columbo\"", parser.definition) must be(ConstDefinition(SimpleID("name"), - TString, StringLiteral("Columbo"), Some("/** COMMENT */"))) + parser.parse("/** COMMENT */ const string name = \"Columbo\"", parser.definition) must be( + ConstDefinition(SimpleID("name"), TString, StringLiteral("Columbo"), Some("/** COMMENT */")) + ) } "more than one docstring" in { @@ -119,8 +159,14 @@ struct MyStruct {} /** and another */ const string tyrion = "lannister" """ - parser.parse(code, parser.definition) must be(ConstDefinition(SimpleID("tyrion"), - TString, StringLiteral("lannister"), Some("/** comment */\n/** and another */"))) + parser.parse(code, parser.definition) must be( + ConstDefinition( + SimpleID("tyrion"), + TString, + StringLiteral("lannister"), + Some("/** comment */\n/** and another */") + ) + ) } "comment before docstring" in { @@ -129,8 +175,14 @@ const string tyrion = "lannister" /** docstring */ const string tyrion = "lannister" """ - parser.parse(code, parser.definition) must be(ConstDefinition(SimpleID("tyrion"), - TString, StringLiteral("lannister"), Some("/** docstring */"))) + parser.parse(code, parser.definition) must be( + ConstDefinition( + SimpleID("tyrion"), + TString, + StringLiteral("lannister"), + Some("/** docstring */") + ) + ) } "typedef" in { @@ -142,7 +194,8 @@ const string tyrion = "lannister" SimpleID("Ladder"), ListType(TI32, None), Map("information" -> "important", "more" -> "better") - )) + ) + ) } "enum" in { @@ -151,14 +204,20 @@ const string tyrion = "lannister" NORTH, SOUTH, EAST=90, WEST, UP, DOWN=5 } """ - parser.parse(code, parser.definition) must be(Enum(SimpleID("Direction"), Seq( - EnumField(SimpleID("NORTH"), 0, None), - EnumField(SimpleID("SOUTH"), 1, None), - EnumField(SimpleID("EAST"), 90, None), - EnumField(SimpleID("WEST"), 91, None), - EnumField(SimpleID("UP"), 92, None), - EnumField(SimpleID("DOWN"), 5, None) - ), None)) + parser.parse(code, parser.definition) must be( + Enum( + SimpleID("Direction"), + Seq( + EnumField(SimpleID("NORTH"), 0, None), + EnumField(SimpleID("SOUTH"), 1, None), + EnumField(SimpleID("EAST"), 90, None), + EnumField(SimpleID("WEST"), 91, None), + EnumField(SimpleID("UP"), 92, None), + EnumField(SimpleID("DOWN"), 5, None) + ), + None + ) + ) val withComment = """ /** @@ -172,19 +231,23 @@ enum Foo // I am a comment. Y = 2 }""" - parser.parse(withComment, parser.enum) must be(Enum(SimpleID("Foo"), - Seq( - EnumField(SimpleID("X"), 1, Some("/** I am a doc. */")), - EnumField(SimpleID("Y"), 2, None)), - Some("/**\n * Docstring!\n */") - )) + parser.parse(withComment, parser.enum) must be( + Enum( + SimpleID("Foo"), + Seq( + EnumField(SimpleID("X"), 1, Some("/** I am a doc. */")), + EnumField(SimpleID("Y"), 2, None) + ), + Some("/**\n * Docstring!\n */") + ) + ) } - "senum" in { // wtf is senum?! parser.parse("senum Cities { 'Milpitas', 'Mayfield' }", parser.definition) must be( - Senum(SimpleID("Cities"), Seq("Milpitas", "Mayfield"))) + Senum(SimpleID("Cities"), Seq("Milpitas", "Mayfield")) + ) } "struct" in { @@ -200,11 +263,34 @@ enum Foo multiline="also supported", ) """ - parser.parse(code, parser.definition) must be(Struct(SimpleID("Point"), "Point", Seq( - Field(1, SimpleID("x"), "x", TDouble, None, Requiredness.Default), - Field(2, SimpleID("y"), "y", TDouble, None, Requiredness.Default, docstring = Some("/** comments*/")), - Field(3, SimpleID("color"), "color", ReferenceType(Identifier("Color")), Some(IdRHS(SimpleID("BLUE"))), Requiredness.Default) - ), Some("/** docs up here */"), Map("annotation" -> "supported", "multiline" -> "also supported"))) + parser.parse(code, parser.definition) must be( + Struct( + SimpleID("Point"), + "Point", + Seq( + Field(1, SimpleID("x"), "x", TDouble, None, Requiredness.Default), + Field( + 2, + SimpleID("y"), + "y", + TDouble, + None, + Requiredness.Default, + docstring = Some("/** comments*/") + ), + Field( + 3, + SimpleID("color"), + "color", + ReferenceType(Identifier("Color")), + Some(IdRHS(SimpleID("BLUE"))), + Requiredness.Default + ) + ), + Some("/** docs up here */"), + Map("annotation" -> "supported", "multiline" -> "also supported") + ) + ) } "union" should { @@ -219,12 +305,49 @@ enum Foo 4: LighterThanAir lta } (maxTypes="4") """ - parser.parse(code, parser.definition) must be(Union(SimpleID("Aircraft"), "Aircraft", Seq( - Field(1, SimpleID("a"), "a", ReferenceType(Identifier("Airplane")), None, Requiredness.Default), - Field(2, SimpleID("r"), "r", ReferenceType(Identifier("Rotorcraft")), None, Requiredness.Default, docstring = Some("/** comments*/")), - Field(3, SimpleID("g"), "g", ReferenceType(Identifier("Glider")), None, Requiredness.Default), - Field(4, SimpleID("lta"), "lta", ReferenceType(Identifier("LighterThanAir")), None, Requiredness.Default) - ), Some("/** docs up here */"), Map("maxTypes" -> "4"))) + parser.parse(code, parser.definition) must be( + Union( + SimpleID("Aircraft"), + "Aircraft", + Seq( + Field( + 1, + SimpleID("a"), + "a", + ReferenceType(Identifier("Airplane")), + None, + Requiredness.Default + ), + Field( + 2, + SimpleID("r"), + "r", + ReferenceType(Identifier("Rotorcraft")), + None, + Requiredness.Default, + docstring = Some("/** comments*/") + ), + Field( + 3, + SimpleID("g"), + "g", + ReferenceType(Identifier("Glider")), + None, + Requiredness.Default + ), + Field( + 4, + SimpleID("lta"), + "lta", + ReferenceType(Identifier("LighterThanAir")), + None, + Requiredness.Default + ) + ), + Some("/** docs up here */"), + Map("maxTypes" -> "4") + ) + ) } "requiredness" in { @@ -244,44 +367,103 @@ enum Foo } """ - laxParser.parse(code, laxParser.definition) must be(Union(SimpleID("Aircraft"), "Aircraft", Seq( - Field(1, SimpleID("a"), "a", ReferenceType(Identifier("Airplane")), None, Requiredness.Default), - Field(2, SimpleID("r"), "r", ReferenceType(Identifier("Rotorcraft")), None, Requiredness.Default), - Field(3, SimpleID("g"), "g", ReferenceType(Identifier("Glider")), None, Requiredness.Default) - ), None, Map.empty)) + laxParser.parse(code, laxParser.definition) must be( + Union( + SimpleID("Aircraft"), + "Aircraft", + Seq( + Field( + 1, + SimpleID("a"), + "a", + ReferenceType(Identifier("Airplane")), + None, + Requiredness.Default + ), + Field( + 2, + SimpleID("r"), + "r", + ReferenceType(Identifier("Rotorcraft")), + None, + Requiredness.Default + ), + Field( + 3, + SimpleID("g"), + "g", + ReferenceType(Identifier("Glider")), + None, + Requiredness.Default + ) + ), + None, + Map.empty + ) + ) } "invalid field name" in { intercept[UnionFieldInvalidNameException] { - parser.parse(""" + parser.parse( + """ union Fruit { 1: Apple apple 2: Banana banana 3: UnknownFruit unknown_union_field } - """, parser.definition) + """, + parser.definition + ) } } } "exception" in { parser.parse("exception BadError { 1: string message }", parser.definition) must be( - Exception_(SimpleID("BadError"), "BadError", - Seq(Field(1, SimpleID("message"), "message", TString, None, Requiredness.Default)), None)) + Exception_( + SimpleID("BadError"), + "BadError", + Seq(Field(1, SimpleID("message"), "message", TString, None, Requiredness.Default)), + None + ) + ) parser.parse("exception E { string message, string reason }", parser.definition) must be( - Exception_(SimpleID("E"), "E", Seq( - Field(-1, SimpleID("message"), "message", TString, None, Requiredness.Default), - Field(-2, SimpleID("reason"), "reason", TString, None, Requiredness.Default) - ), None)) + Exception_( + SimpleID("E"), + "E", + Seq( + Field(-1, SimpleID("message"), "message", TString, None, Requiredness.Default), + Field(-2, SimpleID("reason"), "reason", TString, None, Requiredness.Default) + ), + None + ) + ) parser.parse("exception NoParams { }", parser.definition) must be( - Exception_(SimpleID("NoParams"), "NoParams", Seq(), None)) + Exception_(SimpleID("NoParams"), "NoParams", Seq(), None) + ) parser.parse("/** doc rivers */ exception wellDocumentedException { }", parser.definition) must be( - Exception_(SimpleID("wellDocumentedException"), "wellDocumentedException", Seq(), Some("/** doc rivers */"))) + Exception_( + SimpleID("wellDocumentedException"), + "wellDocumentedException", + Seq(), + Some("/** doc rivers */") + ) + ) val annotations = Map("persisted" -> "true") - parser.parse("exception BadError { 1: string message } (persisted = \"true\")", parser.definition) must be( - Exception_(SimpleID("BadError"), "BadError", - Seq(Field(1, SimpleID("message"), "message", TString, None, Requiredness.Default)), None, annotations)) + parser.parse( + "exception BadError { 1: string message } (persisted = \"true\")", + parser.definition + ) must be( + Exception_( + SimpleID("BadError"), + "BadError", + Seq(Field(1, SimpleID("message"), "message", TString, None, Requiredness.Default)), + None, + annotations + ) + ) } "service" in { @@ -292,22 +474,49 @@ enum Foo binary get(1: string name) throws (1: NotFoundException ex); } """ - parser.parse(code, parser.definition) must be(Service(SimpleID("Cache"), None, Seq( - Function(SimpleID("put"), "put", Void, Seq( - Field(1, SimpleID("name"), "name", TString, None, Requiredness.Default), - Field(2, SimpleID("value"), "value", TBinary, None, Requiredness.Default) - ), Seq(), None), - Function(SimpleID("get"), "get", TBinary, Seq( - Field(1, SimpleID("name"), "name", TString, None, Requiredness.Default) - ), Seq(Field(1, SimpleID("ex"), "ex", ReferenceType(Identifier("NotFoundException")), None, Requiredness.Default)), None) - ), Some("/** cold hard cache */"))) + parser.parse(code, parser.definition) must be( + Service( + SimpleID("Cache"), + None, + Seq( + Function( + SimpleID("put"), + "put", + Void, + Seq( + Field(1, SimpleID("name"), "name", TString, None, Requiredness.Default), + Field(2, SimpleID("value"), "value", TBinary, None, Requiredness.Default) + ), + Seq(), + None + ), + Function( + SimpleID("get"), + "get", + TBinary, + Seq( + Field(1, SimpleID("name"), "name", TString, None, Requiredness.Default) + ), + Seq( + Field( + 1, + SimpleID("ex"), + "ex", + ReferenceType(Identifier("NotFoundException")), + None, + Requiredness.Default + ) + ), + None + ) + ), + Some("/** cold hard cache */") + ) + ) parser.parse("service LeechCache extends Cache {}", parser.definition) must be( - Service( - SimpleID("LeechCache"), - Some(ServiceParent(SimpleID("Cache"), None)), - Seq(), - None)) + Service(SimpleID("LeechCache"), Some(ServiceParent(SimpleID("Cache"), None)), Seq(), None) + ) } "document" in { @@ -321,12 +530,21 @@ enum Foo void doNothing(); } """ - parser.parse(code, parser.document) must be(Document( - Seq(Namespace("java", Identifier("com.example")), Namespace("*", Identifier("example"))), - Seq(Service(SimpleID("NullService"), None, Seq( - Function(SimpleID("doNothing"), "doNothing", Void, Seq(), Seq(), Some("/** DoC */")) - ), Some("/** what up doc */"))) - )) + parser.parse(code, parser.document) must be( + Document( + Seq(Namespace("java", Identifier("com.example")), Namespace("*", Identifier("example"))), + Seq( + Service( + SimpleID("NullService"), + None, + Seq( + Function(SimpleID("doNothing"), "doNothing", Void, Seq(), Seq(), Some("/** DoC */")) + ), + Some("/** what up doc */") + ) + ) + ) + ) } // reject syntax @@ -383,7 +601,8 @@ enum Foo SimpleID("AirportCode"), TString, Map("dbtype" -> "fixedchar(4)", "nullable" -> "false") - )) + ) + ) val idTypeAnnotations = Map("autoincrement" -> "true") val idFieldAnnotations = Map("initialValue" -> "0") @@ -409,13 +628,41 @@ enum Foo SimpleID("Airport"), "Airport", Seq( - Field(1, SimpleID("id"), "id", TI64, Some(IntLiteral(0)), Requiredness.Default, idTypeAnnotations, idFieldAnnotations), - Field(2, SimpleID("code"), "code", TString, None, Requiredness.Optional, codeTypeAnnotations, Map.empty), - Field(3, SimpleID("name"), "name", TString, None, Requiredness.Optional, Map.empty, nameFieldAnnotations) + Field( + 1, + SimpleID("id"), + "id", + TI64, + Some(IntLiteral(0)), + Requiredness.Default, + idTypeAnnotations, + idFieldAnnotations + ), + Field( + 2, + SimpleID("code"), + "code", + TString, + None, + Requiredness.Optional, + codeTypeAnnotations, + Map.empty + ), + Field( + 3, + SimpleID("name"), + "name", + TString, + None, + Requiredness.Optional, + Map.empty, + nameFieldAnnotations + ) ), None, structAnnotations - )) + ) + ) } "handle illegal filenames" in { @@ -453,57 +700,91 @@ enum Foo "boolean default values" in { var field = parser.parse("bool x = 0", parser.field) - field.default must be (Some(BoolLiteral(false))) + field.default must be(Some(BoolLiteral(false))) field = parser.parse("bool x = 1", parser.field) - field.default must be (Some(BoolLiteral(true))) + field.default must be(Some(BoolLiteral(true))) intercept[TypeMismatchException] { parser.parse("bool x = 2", parser.field) } field = parser.parse("bool x = false", parser.field) - field.default must be (Some(BoolLiteral(false))) + field.default must be(Some(BoolLiteral(false))) field = parser.parse("bool x = true", parser.field) - field.default must be (Some(BoolLiteral(true))) + field.default must be(Some(BoolLiteral(true))) field = parser.parse("bool x = False", parser.field) - field.default must be (Some(BoolLiteral(false))) + field.default must be(Some(BoolLiteral(false))) field = parser.parse("bool x = True", parser.field) - field.default must be (Some(BoolLiteral(true))) + field.default must be(Some(BoolLiteral(true))) intercept[TypeMismatchException] { parser.parse("bool x = WhatIsThis", parser.field) } - parser.parse("const bool z = false", parser.const) must be ( - ConstDefinition(SimpleID("z", None), TBool, BoolLiteral(false), None)) + parser.parse("const bool z = false", parser.const) must be( + ConstDefinition(SimpleID("z", None), TBool, BoolLiteral(false), None) + ) - parser.parse("const bool z = True", parser.const) must be ( - ConstDefinition(SimpleID("z", None), TBool, BoolLiteral(true), None)) + parser.parse("const bool z = True", parser.const) must be( + ConstDefinition(SimpleID("z", None), TBool, BoolLiteral(true), None) + ) intercept[TypeMismatchException] { parser.parse("const bool z = IDontEven", parser.const) } intercept[TypeMismatchException] { - parser.parse("service theService { i32 getValue(1: bool arg = SomethingElse) }", - parser.service) + parser.parse( + "service theService { i32 getValue(1: bool arg = SomethingElse) }", + parser.service + ) } - parser.parse("struct asdf { bool x = false }", parser.struct) must be ( - Struct(SimpleID("asdf", None), "asdf", - List(Field(-1, SimpleID("x", None), "x", TBool, Some(BoolLiteral(false)), - Requiredness.Default, Map(), Map())), - None,Map())) + parser.parse("struct asdf { bool x = false }", parser.struct) must be( + Struct( + SimpleID("asdf", None), + "asdf", + List( + Field( + -1, + SimpleID("x", None), + "x", + TBool, + Some(BoolLiteral(false)), + Requiredness.Default, + Map(), + Map() + ) + ), + None, + Map() + ) + ) - parser.parse("struct asdf { bool x = 1 }", parser.struct) must be ( - Struct(SimpleID("asdf", None), "asdf", - List(Field(-1, SimpleID("x", None), "x", TBool, Some(BoolLiteral(true)), - Requiredness.Default, Map(), Map())), - None,Map())) + parser.parse("struct asdf { bool x = 1 }", parser.struct) must be( + Struct( + SimpleID("asdf", None), + "asdf", + List( + Field( + -1, + SimpleID("x", None), + "x", + TBool, + Some(BoolLiteral(true)), + Requiredness.Default, + Map(), + Map() + ) + ), + None, + Map() + ) + ) intercept[TypeMismatchException] { parser.parse("struct S { 1: bool B = 15 }", parser.struct) @@ -513,12 +794,27 @@ enum Foo "Apache-compatible annotations" in { // see http://svn.apache.org/viewvc/thrift/trunk/test/AnnotationTest.thrift?view=markup&pathrev=1386848 - parser.parse("""typedef list ( cpp.template = "std::list" ) int_linked_list""", parser.typedef) must be( - Typedef(SimpleID("int_linked_list", None), ListType(TI32, None), Map("cpp.template" -> "std::list")) + parser.parse( + """typedef list ( cpp.template = "std::list" ) int_linked_list""", + parser.typedef + ) must be( + Typedef( + SimpleID("int_linked_list", None), + ListType(TI32, None), + Map("cpp.template" -> "std::list") + ) ) - parser.parse("""typedef string ( unicode.encoding = "UTF-16" ) non_latin_string (foo="bar")""", parser.typedef) must be( - Typedef(SimpleID("non_latin_string", None), TString, Map("unicode.encoding" -> "UTF-16"), Map("foo" -> "bar")) + parser.parse( + """typedef string ( unicode.encoding = "UTF-16" ) non_latin_string (foo="bar")""", + parser.typedef + ) must be( + Typedef( + SimpleID("non_latin_string", None), + TString, + Map("unicode.encoding" -> "UTF-16"), + Map("foo" -> "bar") + ) ) // TODO(CSL-4127): support annotations on nested types @@ -536,30 +832,87 @@ enum Foo | python.type = "DenseFoo", | java.final = "", |) - """.stripMargin, parser.struct) must be( - Struct(SimpleID("foo", None), "foo", Seq( - Field(1, SimpleID("bar", None), "bar", TI32, None, Default, Map(), Map("presence" -> "required"), None), - Field(2, SimpleID("baz", None), "baz", TI32, None, Default, Map(), Map("presence" -> "manual", "cpp.use_pointer" -> ""), None), - Field(3, SimpleID("qux", None), "qux", TI32, None, Default, Map(), Map(), None), - Field(4, SimpleID("bop", None), "bop", TI32, None, Default, Map(), Map(), None)), None, Map("cpp.type" -> "DenseFoo", "python.type" -> "DenseFoo", "java.final" -> "")) + """.stripMargin, + parser.struct + ) must be( + Struct( + SimpleID("foo", None), + "foo", + Seq( + Field( + 1, + SimpleID("bar", None), + "bar", + TI32, + None, + Default, + Map(), + Map("presence" -> "required"), + None + ), + Field( + 2, + SimpleID("baz", None), + "baz", + TI32, + None, + Default, + Map(), + Map("presence" -> "manual", "cpp.use_pointer" -> ""), + None + ), + Field(3, SimpleID("qux", None), "qux", TI32, None, Default, Map(), Map(), None), + Field(4, SimpleID("bop", None), "bop", TI32, None, Default, Map(), Map(), None) + ), + None, + Map("cpp.type" -> "DenseFoo", "python.type" -> "DenseFoo", "java.final" -> "") + ) ) parser.parse( - """ + """ |exception foo_error { | 1: i32 error_code ( foo="bar" ) | 2: string error_msg |} (foo = "bar") | - """.stripMargin, parser.exception) must be( - Exception_(SimpleID("foo_error", None), "foo_error", Seq( - Field(1, SimpleID("error_code", None), "error_code", TI32, None, Default, Map(), Map("foo" -> "bar"), None), - Field(2, SimpleID("error_msg", None), "error_msg", TString, None, Default, Map(), Map(), None)), - None, Map("foo" -> "bar")) + """.stripMargin, + parser.exception + ) must be( + Exception_( + SimpleID("foo_error", None), + "foo_error", + Seq( + Field( + 1, + SimpleID("error_code", None), + "error_code", + TI32, + None, + Default, + Map(), + Map("foo" -> "bar"), + None + ), + Field( + 2, + SimpleID("error_msg", None), + "error_msg", + TString, + None, + Default, + Map(), + Map(), + None + ) + ), + None, + Map("foo" -> "bar") + ) ) parser.parse( - """ + """ |enum weekdays { | SUNDAY ( weekend = "yes" ), | MONDAY, @@ -570,8 +923,12 @@ enum Foo | SATURDAY ( weekend = "yes" ) |} (foo.bar="baz") | - """.stripMargin, parser.enum) must be ( - Enum(SimpleID("weekdays", None), Seq( + """.stripMargin, + parser.enum + ) must be( + Enum( + SimpleID("weekdays", None), + Seq( EnumField(SimpleID("SUNDAY", None), 0, None, Map("weekend" -> "yes")), EnumField(SimpleID("MONDAY", None), 1, None, Map()), EnumField(SimpleID("TUESDAY", None), 2, None, Map()), @@ -579,12 +936,15 @@ enum Foo EnumField(SimpleID("THURSDAY", None), 4, None, Map()), EnumField(SimpleID("FRIDAY", None), 5, None, Map()), EnumField(SimpleID("SATURDAY", None), 6, None, Map("weekend" -> "yes")) - ), None, Map("foo.bar" -> "baz")) + ), + None, + Map("foo.bar" -> "baz") + ) ) // Annotations on senum values are not supported parser.parse( - """ + """ |senum seasons { | "Spring", | "Summer", @@ -592,37 +952,43 @@ enum Foo | "Winter" |} ( foo = "bar" ) | - """.stripMargin, parser.senum) must be ( + """.stripMargin, + parser.senum + ) must be( Senum( SimpleID("seasons", None), - Seq("Spring", "Summer", "Fall", "Winter"), - Map("foo" -> "bar")) + Seq("Spring", "Summer", "Fall", "Winter"), + Map("foo" -> "bar") + ) ) - parser.parse( - """ + parser.parse(""" |service foo_service { | void foo() ( foo = "bar" ) |} (a.b="c") | - """.stripMargin, parser.service) must be ( - Service(SimpleID("foo_service", None), None, Seq( - Function(SimpleID("foo", None), "foo", Void, Seq(), Seq(), None, Map("foo" -> "bar")) - ), - None, - Map("a.b" -> "c")) + """.stripMargin, parser.service) must be( + Service( + SimpleID("foo_service", None), + None, + Seq( + Function(SimpleID("foo", None), "foo", Void, Seq(), Seq(), None, Map("foo" -> "bar")) + ), + None, + Map("a.b" -> "c") + ) ) } } - private def getParserForFilenameTest(thriftFilename: String): ThriftParser = { val importer = new Importer { override def apply(v1: String): scala.Option[FileContents] = scala.Some(FileContents(NullImporter, "", scala.Some(thriftFilename))) override private[scrooge] def canonicalPaths: Seq[String] = Nil override def lastModified(filename: String): scala.Option[Long] = None - override private[scrooge] def getResolvedPath(filename: String): scala.Option[String] = Some(filename) + override private[scrooge] def getResolvedPath(filename: String): scala.Option[String] = + Some(filename) } new ThriftParser(importer, true) } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/TypeResolverSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/TypeResolverSpec.scala index 6d2d27245..ce1346387 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/TypeResolverSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/frontend/TypeResolverSpec.scala @@ -10,15 +10,22 @@ class TypeResolverSpec extends Spec { val enum = Enum(SimpleID("SomeEnum"), Seq(foo, bar), None) val enumType = new EnumType(enum) val enumRef = ReferenceType(enum.sid) - val struct = Struct(SimpleID("BlahBlah"), "BlahBlah", Seq( - Field(1, SimpleID("baby"), "baby", TI16), - Field(2, SimpleID("mama"), "mama", TI32), - Field(3, SimpleID("papa"), "papa", TI64), - Field(4, SimpleID("pupu"), "pupu", enumRef) - ), None, Map.empty) + val struct = Struct( + SimpleID("BlahBlah"), + "BlahBlah", + Seq( + Field(1, SimpleID("baby"), "baby", TI16), + Field(2, SimpleID("mama"), "mama", TI32), + Field(3, SimpleID("papa"), "papa", TI64), + Field(4, SimpleID("pupu"), "pupu", enumRef) + ), + None, + Map.empty + ) val structType = new StructType(struct) val structRef = ReferenceType(struct.sid) - val ex = Exception_(SimpleID("Boom"), "Boom", Seq(Field(1, SimpleID("msg"), "msg", enumRef)), None) + val ex = + Exception_(SimpleID("Boom"), "Boom", Seq(Field(1, SimpleID("msg"), "msg", enumRef)), None) val exType = new StructType(ex) val resolver = TypeResolver() .withType(enum.sid.name, enumType) @@ -27,7 +34,13 @@ class TypeResolverSpec extends Spec { def createStruct(structName: String, fieldType: FieldType) = { val fieldName: String = structName + "_field" - Struct(SimpleID(structName), structName, Seq(Field(1, SimpleID(fieldName), fieldName, fieldType)), None, Map.empty) + Struct( + SimpleID(structName), + structName, + Seq(Field(1, SimpleID(fieldName), fieldName, fieldType)), + None, + Map.empty + ) } "throw exception on unknown type" in { @@ -46,7 +59,7 @@ class TypeResolverSpec extends Spec { resolver2(struct, None) match { case ResolvedDefinition(struct2: Struct, _) => struct2.fields(3).fieldType must be(enumType) - // pass + // pass case _ => fail() } @@ -89,7 +102,7 @@ class TypeResolverSpec extends Spec { "transform MapType" in { resolver(MapType(enumRef, structRef, None)) match { case MapType(enumType, structType, None) => - // pass + // pass case _ => fail() } @@ -98,7 +111,7 @@ class TypeResolverSpec extends Spec { "transform SetType" in { resolver(SetType(structRef, None)) match { case SetType(structType, None) => - // pass + // pass case _ => fail() } @@ -107,7 +120,7 @@ class TypeResolverSpec extends Spec { "transform ListType" in { resolver(ListType(structRef, None)) match { case ListType(structType, None) => - // pass + // pass case _ => fail() } @@ -123,9 +136,11 @@ class TypeResolverSpec extends Spec { } "transform a Field with enum constant default" in { - val field = Field(1, SimpleID("field"), "field", enumRef, Some(IdRHS(Identifier("SomeEnum.FOO")))) + val field = + Field(1, SimpleID("field"), "field", enumRef, Some(IdRHS(Identifier("SomeEnum.FOO")))) resolver(field) must be( - Field(1, SimpleID("field"), "field", enumType, Some(EnumRHS(enum, foo)))) + Field(1, SimpleID("field"), "field", enumType, Some(EnumRHS(enum, foo))) + ) } "transform a Function" in { @@ -133,17 +148,26 @@ class TypeResolverSpec extends Spec { val ex = Field(2, SimpleID("ex"), "ex", structRef) val fun = Function(SimpleID("foo"), "foo", structRef, Seq(field), Seq(ex), None) resolver(fun) must be( - Function(SimpleID("foo"), "foo", resolver(fun.funcType), Seq(resolver(field)), Seq(resolver(ex)), None)) + Function( + SimpleID("foo"), + "foo", + resolver(fun.funcType), + Seq(resolver(field)), + Seq(resolver(ex)), + None + ) + ) } "transform a TypeDef" in { val typedef = Typedef(SimpleID("foo"), enumRef, Map("some" -> "annotation")) - resolver(typedef, None).definition must be( - typedef.copy(fieldType = enumType)) + resolver(typedef, None).definition must be(typedef.copy(fieldType = enumType)) } "transform a Struct" in { - resolver(struct, None).definition must be(struct.copy(fields = struct.fields.map(resolver.apply))) + resolver(struct, None).definition must be( + struct.copy(fields = struct.fields.map(resolver.apply)) + ) } "fail to transform when a Typedef has same identifier as a Struct" in { @@ -162,7 +186,9 @@ class TypeResolverSpec extends Spec { "transform a Const" in { val const = ConstDefinition(SimpleID("foo"), enumRef, IdRHS(Identifier("SomeEnum.FOO")), None) - resolver(const, None).definition must be(ConstDefinition(SimpleID("foo"), enumType, EnumRHS(enum, foo), None)) + resolver(const, None).definition must be( + ConstDefinition(SimpleID("foo"), enumType, EnumRHS(enum, foo), None) + ) } "const definition transitivity" in { @@ -173,7 +199,8 @@ class TypeResolverSpec extends Spec { val newResolver = resolver(line, None).resolver val copy = ConstDefinition(SimpleID("copy"), TString, IdRHS(SimpleID("line")), None) newResolver(copy, None).definition must be( - ConstDefinition(SimpleID("copy"), TString, StringLiteral("hi"), None)) + ConstDefinition(SimpleID("copy"), TString, StringLiteral("hi"), None) + ) // this code has type mismatch // const string line = "hi" @@ -187,7 +214,8 @@ class TypeResolverSpec extends Spec { // this code has undefined symbol // const string line = "hi" // const string copy = noSuchConst - val copyWrongId = ConstDefinition(SimpleID("copy"), TString, IdRHS(SimpleID("noSuchConst")), None) + val copyWrongId = + ConstDefinition(SimpleID("copy"), TString, IdRHS(SimpleID("noSuchConst")), None) intercept[UndefinedConstantException] { newResolver(copyWrongId, None) } @@ -205,7 +233,9 @@ class TypeResolverSpec extends Spec { val test1Field = testStruct1.fields(0) val test2Field = testStruct2.fields(0) - val structElems = Map(test2Field -> StructRHS(sid = structType1.sid, elems = Map(test1Field -> IntLiteral(3)))) + val structElems = Map( + test2Field -> StructRHS(sid = structType1.sid, elems = Map(test1Field -> IntLiteral(3))) + ) value must be(StructRHS(sid = structType2.sid, elems = structElems)) } @@ -219,30 +249,34 @@ class TypeResolverSpec extends Spec { } "transform a Service" in { - val fun = Function(SimpleID("foo"), "foo", structRef, - Seq(Field(1, SimpleID("foo"), "foo", structRef)), Nil, None) + val fun = Function( + SimpleID("foo"), + "foo", + structRef, + Seq(Field(1, SimpleID("foo"), "foo", structRef)), + Nil, + None + ) val service = Service(SimpleID("Glurb"), None, Seq(fun), None) resolver(service, None).definition must be(service.copy(functions = Seq(resolver(fun)))) } "resolve a service parent from same scope" in { val service1 = Service(SimpleID("Super"), None, Nil, None) - val service2 = Service( - SimpleID("Sub"), - Some(ServiceParent(SimpleID("Super"), None)), - Nil, - None) + val service2 = + Service(SimpleID("Sub"), Some(ServiceParent(SimpleID("Super"), None)), Nil, None) val resolver = TypeResolver().withService(service1) resolver(service2, None).definition must be( - service2.copy( - parent = Some(ServiceParent(service1.sid, None)))) + service2.copy(parent = Some(ServiceParent(service1.sid, None))) + ) } "resolve a parameter from an included scope" in { val oneInt = Struct(SimpleID("TestRequest"), "TestRequest", Seq(), None, Map.empty) val doc = Document(Nil, Seq(oneInt)) val resolver = TypeResolver().withInclude(Include("other.thrift", doc)) - val resolveFieldType: FieldType = resolver.resolveFieldType(QualifiedID(Seq("other", "TestRequest"))) + val resolveFieldType: FieldType = + resolver.resolveFieldType(QualifiedID(Seq("other", "TestRequest"))) resolveFieldType.asInstanceOf[StructType].scopePrefix must be(Some(SimpleID("other"))) } @@ -255,33 +289,84 @@ class TypeResolverSpec extends Spec { SimpleID("Sub"), Some(ServiceParent(SimpleID("Super"), Some(SimpleID("other")))), Nil, - None) + None + ) resolver(subSvc, None).definition must be( - subSvc.copy(parent = Some(ServiceParent( - SimpleID("Super"), - Some(SimpleID("other")))))) + subSvc.copy(parent = Some(ServiceParent(SimpleID("Super"), Some(SimpleID("other"))))) + ) } "resolve a typedef from an included scope" in { - val oneInt = Struct(SimpleID("OneInt"), "OneInt", Seq(Field(1, SimpleID("id"), "id", TI32, None, Requiredness.Default)), None, Map.empty) - val typedefInt = Typedef(SimpleID("ManyInts"), ListType(ReferenceType(Identifier("OneInt")), None), Map.empty) + val oneInt = Struct( + SimpleID("OneInt"), + "OneInt", + Seq(Field(1, SimpleID("id"), "id", TI32, None, Requiredness.Default)), + None, + Map.empty + ) + val typedefInt = Typedef( + SimpleID("ManyInts"), + ListType(ReferenceType(Identifier("OneInt")), None), + Map.empty + ) val doc1 = Document(Nil, Seq(oneInt, typedefInt)) - val collectionStruct = Struct(SimpleID("IntCollection"), "IntCollection", Seq( - Field(1, SimpleID("scores1"), "scores1", ReferenceType(Identifier("typedef1.ManyInts")), None, Requiredness.Default), - Field(2, SimpleID("scores2"), "scores2", SetType(ReferenceType(Identifier("typedef1.OneInt")), None), None, Requiredness.Default) - ), None, Map("foo" -> "bar")) - val doc2 = Document(Seq(Include("src/test/thrift/typedef1.thrift", doc1)), Seq(collectionStruct)) + val collectionStruct = Struct( + SimpleID("IntCollection"), + "IntCollection", + Seq( + Field( + 1, + SimpleID("scores1"), + "scores1", + ReferenceType(Identifier("typedef1.ManyInts")), + None, + Requiredness.Default + ), + Field( + 2, + SimpleID("scores2"), + "scores2", + SetType(ReferenceType(Identifier("typedef1.OneInt")), None), + None, + Requiredness.Default + ) + ), + None, + Map("foo" -> "bar") + ) + val doc2 = + Document(Seq(Include("src/test/thrift/typedef1.thrift", doc1)), Seq(collectionStruct)) val resolvedDoc = TypeResolver()(doc2).document resolvedDoc.defs(0) match { case Struct(_, _, fields, _, annotations) => { fields(0) match { - case Field(1, _, _, ListType(StructType(_, Some(SimpleID("typedef1", _))), None), _, _, _, _, _) => // pass + case Field( + 1, + _, + _, + ListType(StructType(_, Some(SimpleID("typedef1", _))), None), + _, + _, + _, + _, + _ + ) => // pass case _ => fail() } fields(1) match { - case Field(2, _, _, SetType(StructType(_, Some(SimpleID("typedef1", _))), None), _, _, _, _, _) => // pass + case Field( + 2, + _, + _, + SetType(StructType(_, Some(SimpleID("typedef1", _))), None), + _, + _, + _, + _, + _ + ) => // pass case _ => fail() } annotations must be(Map("foo" -> "bar")) @@ -363,7 +448,7 @@ class TypeResolverSpec extends Spec { "UndefinedSymbolException" in { val input = "const i32 NotAService = 4\n" + - "service S extends NotAService {}" + "service S extends NotAService {}" val parser = new ThriftParser(Importer("."), strict = true) diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/integration/AndroidIntegrationSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/integration/AndroidIntegrationSpec.scala index 38382c3bb..c897da1ad 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/integration/AndroidIntegrationSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/integration/AndroidIntegrationSpec.scala @@ -12,7 +12,8 @@ class AndroidIntegrationSpec extends Spec { "transfer struct to Scrooge" in { val protocol = new TBinaryProtocol(new TMemoryBuffer(10000)) val builder = new androidGen.Bonk_struct.Builder - val androidStruct = builder.set(Bonk_struct.INT_THING, 123) + val androidStruct = builder + .set(Bonk_struct.INT_THING, 123) .set(Bonk_struct.MESSAGE, "howdy world") .build() androidStruct.write(protocol) @@ -22,32 +23,32 @@ class AndroidIntegrationSpec extends Spec { scroogeStruct.message must be("howdy world") scroogeStruct.intThing must be(123) // test transferred names - scroogeGen.BonkStruct.MessageField.name must be( - androidStruct.fieldForId(1).getFieldName) // == "message" - scroogeGen.BonkStruct.IntThingField.name must be( - androidStruct.fieldForId(2).getFieldName) // == "int_thing" + scroogeGen.BonkStruct.MessageField.name must be(androidStruct.fieldForId(1).getFieldName) // == "message" + scroogeGen.BonkStruct.IntThingField.name must be(androidStruct.fieldForId(2).getFieldName) // == "int_thing" } "transfer union to Scrooge" in { val protocol = new TBinaryProtocol(new TMemoryBuffer(10000)) val builder = new androidGen.Bonk_struct.Builder - val androidStruct = builder.set(Bonk_struct.INT_THING, 123) + val androidStruct = builder + .set(Bonk_struct.INT_THING, 123) .set(Bonk_struct.MESSAGE, "howdy world") .build() - val androidUnion = new androidGen.bonk_or_bool_union(androidGen.bonk_or_bool_union.BONK, androidStruct) + val androidUnion = + new androidGen.bonk_or_bool_union(androidGen.bonk_or_bool_union.BONK, androidStruct) androidUnion.write(protocol) val scroogeUnion = scroogeGen.BonkOrBoolUnion.decode(protocol) // test transferred values val scroogeStruct = scroogeUnion.asInstanceOf[scroogeGen.BonkOrBoolUnion.Bonk] - scroogeStruct.bonk must not be(null) + scroogeStruct.bonk must not be (null) scroogeStruct.bonk.message must be("howdy world") scroogeStruct.bonk.intThing must be(123) // test transferred names scroogeGen.BonkOrBoolUnion.Union.name must be("bonk_or_bool_union") - scroogeGen.BonkOrBoolUnion.BonkField.name must be( - androidUnion.fieldForId(1).getFieldName) // == "bonk" + scroogeGen.BonkOrBoolUnion.BonkField.name must be(androidUnion.fieldForId(1).getFieldName) // == "bonk" scroogeGen.BonkOrBoolUnion.BoolThingField.name must be( - androidUnion.fieldForId(2).getFieldName) // == "bool_thing" + androidUnion.fieldForId(2).getFieldName + ) // == "bool_thing" } } @@ -58,9 +59,9 @@ class AndroidIntegrationSpec extends Spec { scroogeGen.BonkStruct.encode(scroogeStruct, protocol) val androidStruct = new androidGen.Bonk_struct() androidStruct.read(protocol) - val int_thing:Integer = androidStruct.get(androidGen.Bonk_struct.INT_THING) + val int_thing: Integer = androidStruct.get(androidGen.Bonk_struct.INT_THING) int_thing must be(123) - val message:String= androidStruct.get(androidGen.Bonk_struct.MESSAGE) + val message: String = androidStruct.get(androidGen.Bonk_struct.MESSAGE) message must be("howdy world") } @@ -75,12 +76,12 @@ class AndroidIntegrationSpec extends Spec { val setField = androidUnion.getSetField() val value = androidUnion.getFieldValue(setField) - androidUnion.getFieldValue(setField).isInstanceOf[androidGen.Bonk_struct] must be (true) + androidUnion.getFieldValue(setField).isInstanceOf[androidGen.Bonk_struct] must be(true) val value2 = value.asInstanceOf[androidGen.Bonk_struct] - val int_thing:Integer = value2.get(androidGen.Bonk_struct.INT_THING) + val int_thing: Integer = value2.get(androidGen.Bonk_struct.INT_THING) int_thing must be(123) - val message:String= value2.get(androidGen.Bonk_struct.MESSAGE) + val message: String = value2.get(androidGen.Bonk_struct.MESSAGE) message must be("howdy world") } } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/integration/ScalaIntegrationSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/integration/ScalaIntegrationSpec.scala index 04c68d5c4..24f7376c0 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/integration/ScalaIntegrationSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/integration/ScalaIntegrationSpec.scala @@ -21,10 +21,8 @@ class ScalaIntegrationSpec extends Spec { scroogeStruct.message must be("howdy world") scroogeStruct.intThing must be(123) // test transferred names - scroogeGen.BonkStruct.MessageField.name must be( - apacheStruct.fieldForId(1).getFieldName) // == "message" - scroogeGen.BonkStruct.IntThingField.name must be( - apacheStruct.fieldForId(2).getFieldName) // == "int_thing" + scroogeGen.BonkStruct.MessageField.name must be(apacheStruct.fieldForId(1).getFieldName) // == "message" + scroogeGen.BonkStruct.IntThingField.name must be(apacheStruct.fieldForId(2).getFieldName) // == "int_thing" } "transfer union to Scrooge" in { @@ -36,15 +34,13 @@ class ScalaIntegrationSpec extends Spec { // test transferred values val scroogeStruct = scroogeUnion.asInstanceOf[scroogeGen.BonkOrBoolUnion.Bonk] - scroogeStruct.bonk must not be(null) + scroogeStruct.bonk must not be (null) scroogeStruct.bonk.message must be("howdy world") scroogeStruct.bonk.intThing must be(123) // test transferred names scroogeGen.BonkOrBoolUnion.Union.name must be("bonk_or_bool_union") - scroogeGen.BonkOrBoolUnion.BonkField.name must be( - apacheUnion.fieldForId(1).getFieldName) // == "bonk" - scroogeGen.BonkOrBoolUnion.BoolThingField.name must be( - apacheUnion.fieldForId(2).getFieldName) // == "bool_thing" + scroogeGen.BonkOrBoolUnion.BonkField.name must be(apacheUnion.fieldForId(1).getFieldName) // == "bonk" + scroogeGen.BonkOrBoolUnion.BoolThingField.name must be(apacheUnion.fieldForId(2).getFieldName) // == "bool_thing" } } @@ -60,10 +56,12 @@ class ScalaIntegrationSpec extends Spec { apacheStruct.getInt_thing must be(123) apacheStruct.getMessage must be("howdy world") // test transferred names - apacheStruct.fieldForId(1).getFieldName must be( - scroogeGen.BonkStruct.MessageField.name) // == "message" - apacheStruct.fieldForId(2).getFieldName must be( - scroogeGen.BonkStruct.IntThingField.name) // == "int_thing" + apacheStruct + .fieldForId(1) + .getFieldName must be(scroogeGen.BonkStruct.MessageField.name) // == "message" + apacheStruct + .fieldForId(2) + .getFieldName must be(scroogeGen.BonkStruct.IntThingField.name) // == "int_thing" } "transfer union to Apache" in { @@ -81,10 +79,12 @@ class ScalaIntegrationSpec extends Spec { apacheUnion.getBool_thing } // test transferred names - apacheUnion.fieldForId(1).getFieldName must be( - scroogeGen.BonkOrBoolUnion.BonkField.name) // == "bonk" - apacheUnion.fieldForId(2).getFieldName must be( - scroogeGen.BonkOrBoolUnion.BoolThingField.name) // == "bonk" + apacheUnion + .fieldForId(1) + .getFieldName must be(scroogeGen.BonkOrBoolUnion.BonkField.name) // == "bonk" + apacheUnion + .fieldForId(2) + .getFieldName must be(scroogeGen.BonkOrBoolUnion.BoolThingField.name) // == "bonk" } "can encode with lazy TBinaryProtocol and decode with TBinaryProtocol" in { @@ -96,7 +96,7 @@ class ScalaIntegrationSpec extends Spec { val tbinary = new TBinaryProtocol(TArrayByteTransport(byteArray)) - scroogeGen.BonkStruct.decode(tbinary) must be (scroogeStruct) + scroogeGen.BonkStruct.decode(tbinary) must be(scroogeStruct) } "can decode with lazy TBinaryProtocol and compare with original" in { @@ -111,8 +111,7 @@ class ScalaIntegrationSpec extends Spec { val lazyReaderTransport = TArrayByteTransport(byteArray) val lazyReaderProtocol = new TLazyBinaryProtocol(lazyReaderTransport) - scroogeGen.BonkStruct.decode(lazyReaderProtocol) must be (scroogeStruct) + scroogeGen.BonkStruct.decode(lazyReaderProtocol) must be(scroogeStruct) } } } - diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/java_generator/ApacheJavaGeneratorSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/java_generator/ApacheJavaGeneratorSpec.scala index d471ff339..b7449c1d9 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/java_generator/ApacheJavaGeneratorSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/java_generator/ApacheJavaGeneratorSpec.scala @@ -74,7 +74,10 @@ class ApacheJavaGeneratorSpec extends Spec { "generate enum code" in { val controller = mock[EnumController] when(controller.name) thenReturn "test" - when(controller.constants) thenReturn Seq(new EnumConstant("foo", 1, false), new EnumConstant("bar", 2, true)) + when(controller.constants) thenReturn Seq( + new EnumConstant("foo", 1, false), + new EnumConstant("bar", 2, true) + ) when(controller.namespace) thenReturn "com.twitter.thrift" when(controller.has_namespace) thenReturn true val sw = renderMustache("enum.mustache", controller) @@ -121,7 +124,8 @@ class ApacheJavaGeneratorSpec extends Spec { "generate struct" in { val doc = generateDoc(getFileContents("test_thrift/struct.thrift")) - val controller = new StructController(doc.structs(1), false, getGenerator(doc), doc.namespace("java")) + val controller = + new StructController(doc.structs(1), false, getGenerator(doc), doc.namespace("java")) val sw = renderMustache("struct.mustache", controller) verify(sw, getFileContents("apache_output/struct.txt")) } @@ -136,21 +140,24 @@ class ApacheJavaGeneratorSpec extends Spec { "generate empty struct" in { val doc = generateDoc(getFileContents("test_thrift/empty_struct.thrift")) - val controller = new StructController(doc.structs(0), false, getGenerator(doc), doc.namespace("java")) + val controller = + new StructController(doc.structs(0), false, getGenerator(doc), doc.namespace("java")) val sw = renderMustache("struct.mustache", controller) verify(sw, getFileContents("apache_output/empty_struct.txt"), false) } "generate exception" in { val doc = generateDoc(getFileContents("test_thrift/service.thrift")) - val controller = new StructController(doc.structs(1), false, getGenerator(doc), doc.namespace("java")) + val controller = + new StructController(doc.structs(1), false, getGenerator(doc), doc.namespace("java")) val sw = renderMustache("struct.mustache", controller) verify(sw, getFileContents("apache_output/test_exception.txt")) } "generate union" in { val doc = generateDoc(getFileContents("test_thrift/union.thrift")) - val controller = new StructController(doc.structs(0), false, getGenerator(doc), doc.namespace("java")) + val controller = + new StructController(doc.structs(0), false, getGenerator(doc), doc.namespace("java")) val sw = renderMustache("struct.mustache", controller) verify(sw, getFileContents("apache_output/union.txt")) } @@ -165,28 +172,34 @@ class ApacheJavaGeneratorSpec extends Spec { "generate service that extends parent" in { val doc = generateDoc(getFileContents("test_thrift/service.thrift")) - val controller = new ServiceController(doc.services(1), getGenerator(doc), doc.namespace("java")) + val controller = + new ServiceController(doc.services(1), getGenerator(doc), doc.namespace("java")) val sw = renderMustache("service.mustache", controller) verify(sw, getFileContents("apache_output/test_service.txt")) } "generate service that does not extend parent" in { val doc = generateDoc(getFileContents("test_thrift/service_without_parent.thrift")) - val controller = new ServiceController(doc.services(0), getGenerator(doc), doc.namespace("java")) + val controller = + new ServiceController(doc.services(0), getGenerator(doc), doc.namespace("java")) val sw = renderMustache("service.mustache", controller) verify(sw, getFileContents("apache_output/test_service_without_parent.txt")) } "generate service with a parent from a different namespace" in { - val doc = generateDoc(getFileContents("test_thrift/service_with_parent_different_namespace.thrift")) + val doc = + generateDoc(getFileContents("test_thrift/service_with_parent_different_namespace.thrift")) val baseDoc = mock[Document] val parentDoc = mock[ResolvedDocument] when(baseDoc.namespace("java")) thenReturn Some(QualifiedID(Seq("com", "twitter", "thrift"))) when(parentDoc.document) thenReturn baseDoc val generator = new ApacheJavaGenerator( - ResolvedDocument(Document(Seq.empty, Seq.empty), TypeResolver( - includeMap = Map("service" -> parentDoc) - )), + ResolvedDocument( + Document(Seq.empty, Seq.empty), + TypeResolver( + includeMap = Map("service" -> parentDoc) + ) + ), "thrift", templateCache, false diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/mustache/HandlebarSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/mustache/HandlebarSpec.scala index 19cef13d9..5adae969d 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/mustache/HandlebarSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/mustache/HandlebarSpec.scala @@ -34,7 +34,8 @@ class HandlebarSpec extends Spec { "simple interpolation" in { val template = "Hello {{name}}!\nYou're looking {{how}} today." Handlebar.generate(template, Dictionary("name" -> v("Mary"), "how" -> v("sad"))) must be( - "Hello Mary!\nYou're looking sad today.") + "Hello Mary!\nYou're looking sad today." + ) } "optional blocks" in { @@ -55,13 +56,15 @@ class HandlebarSpec extends Spec { "normally" in { val template = "The cats are named: {{#cats}}'{{name}}' {{/cats}}." Handlebar.generate(template, Dictionary("cats" -> v(cats))) must be( - "The cats are named: 'Commie' 'Lola' 'Lexi' .") + "The cats are named: 'Commie' 'Lola' 'Lexi' ." + ) } "with a joiner" in { val template = "The cats are named: {{#cats}}{{name}}{{/cats|, }}." Handlebar.generate(template, Dictionary("cats" -> v(cats))) must be( - "The cats are named: Commie, Lola, Lexi.") + "The cats are named: Commie, Lola, Lexi." + ) } } @@ -76,24 +79,29 @@ class HandlebarSpec extends Spec { "works" in { val template = "We have these cities:\n{{#cities}}\n{{>description}}\n{{/cities}}\n" Handlebar.generate(template, dictionary) must be( - "We have these cities:\nNew York,\nNY\nAtlanta,\nGA\n") + "We have these cities:\nNew York,\nNY\nAtlanta,\nGA\n" + ) } "indents" in { val template = "We have these cities:\n{{#cities}}\n {{>description}}\n{{/cities}}\n" Handlebar.generate(template, dictionary) must be( - "We have these cities:\n New York,\n NY\n Atlanta,\n GA\n") + "We have these cities:\n New York,\n NY\n Atlanta,\n GA\n" + ) } "indents nestedly" in { val template = "We have these cities:\n {{>header}}\n" - val headerTemplate = new Handlebar("Header:\n{{#cities}}\n {{>description}}\n{{/cities}}\n") + val headerTemplate = + new Handlebar("Header:\n{{#cities}}\n {{>description}}\n{{/cities}}\n") val dictionary = Dictionary( "cities" -> v(cities), "header" -> v(headerTemplate), - "description" -> v(cityTemplate)) + "description" -> v(cityTemplate) + ) Handlebar.generate(template, dictionary) must be( - "We have these cities:\n Header:\n New York,\n NY\n Atlanta,\n GA\n") + "We have these cities:\n Header:\n New York,\n NY\n Atlanta,\n GA\n" + ) } } @@ -102,18 +110,28 @@ class HandlebarSpec extends Spec { Dictionary( "cats" -> v( Dictionary( - "info" -> v(Seq( - Dictionary("city" -> v("Anchorage")), - Dictionary("city" -> v("Seattle")), - Dictionary("city" -> v("Lihu'a")))))), - "name" -> v("Taro")), // NOTE: "name" must be AFTER "cats->info" to exhibit nesting bug + "info" -> v( + Seq( + Dictionary("city" -> v("Anchorage")), + Dictionary("city" -> v("Seattle")), + Dictionary("city" -> v("Lihu'a")) + ) + ) + ) + ), + "name" -> v("Taro") + ), // NOTE: "name" must be AFTER "cats->info" to exhibit nesting bug Dictionary( "cats" -> v( Dictionary( - "info" -> v(Seq( - Dictionary("city" -> v("Chicago")), - Dictionary("city" -> v("Knoxville")))))), - "name" -> v("Mira"))) + "info" -> v( + Seq(Dictionary("city" -> v("Chicago")), Dictionary("city" -> v("Knoxville"))) + ) + ) + ), + "name" -> v("Mira") + ) + ) // this also (accidentally) tests whitespace cleanup. val template = """My book report: {{#students}} diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/mustache/ParserSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/mustache/ParserSpec.scala index 72258f2a2..5cb380675 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/mustache/ParserSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/mustache/ParserSpec.scala @@ -28,22 +28,30 @@ class ParserSpec extends Spec { "interpolates" in { val text = "say hello to {{friend}}, {{name}}" - MustacheParser(text) must be(Template(Seq( - Data("say hello to "), - Interpolation("friend"), - Data(", "), - Interpolation("name") - ))) + MustacheParser(text) must be( + Template( + Seq( + Data("say hello to "), + Interpolation("friend"), + Data(", "), + Interpolation("name") + ) + ) + ) } "doesn't get confused by other {" in { val text = "say { to {{friend}}, {{name}}" - MustacheParser(text) must be(Template(Seq( - Data("say { to "), - Interpolation("friend"), - Data(", "), - Interpolation("name") - ))) + MustacheParser(text) must be( + Template( + Seq( + Data("say { to "), + Interpolation("friend"), + Data(", "), + Interpolation("name") + ) + ) + ) } "errors on impossible ids" in { @@ -55,28 +63,54 @@ class ParserSpec extends Spec { "section" in { val text = "Classmates: {{#students}}Name: {{name}}{{/students}}" - MustacheParser(text) must be(Template(Seq( - Data("Classmates: "), - Section("students", Template(Seq( - Data("Name: "), - Interpolation("name") - )), false) - ))) + MustacheParser(text) must be( + Template( + Seq( + Data("Classmates: "), + Section( + "students", + Template( + Seq( + Data("Name: "), + Interpolation("name") + ) + ), + false + ) + ) + ) + ) } "nested section" in { val text = "Planets: {{#planets}}{{name}} Moons: {{#moons}}{{name}}{{/moons}} :) {{/planets}}" - MustacheParser(text) must be(Template(Seq( - Data("Planets: "), - Section("planets", Template(Seq( - Interpolation("name"), - Data(" Moons: "), - Section("moons", Template(Seq( - Interpolation("name") - )), false), - Data(" :) ") - )), false) - ))) + MustacheParser(text) must be( + Template( + Seq( + Data("Planets: "), + Section( + "planets", + Template( + Seq( + Interpolation("name"), + Data(" Moons: "), + Section( + "moons", + Template( + Seq( + Interpolation("name") + ) + ), + false + ), + Data(" :) ") + ) + ), + false + ) + ) + ) + ) } "complains about mismatched section headers" in { @@ -88,48 +122,87 @@ class ParserSpec extends Spec { "inverted section" in { val text = "{{^space}}no space{{/space}}" - MustacheParser(text) must be(Template(Seq( - Section("space", Template(Seq( - Data("no space") - )), true) - ))) + MustacheParser(text) must be( + Template( + Seq( + Section( + "space", + Template( + Seq( + Data("no space") + ) + ), + true + ) + ) + ) + ) } "comments" in { val text = "remember {{! these comments look stupid, like xml}} nothing." - MustacheParser(text) must be(Template(Seq( - Data("remember "), - Data(" nothing.") - ))) + MustacheParser(text) must be( + Template( + Seq( + Data("remember "), + Data(" nothing.") + ) + ) + ) } "partial" in { val text = "{{#foo}}ok {{>other}}{{/foo}}" - MustacheParser(text) must be(Template(Seq( - Section("foo", Template(Seq( - Data("ok "), - Partial("other") - )), false) - ))) + MustacheParser(text) must be( + Template( + Seq( + Section( + "foo", + Template( + Seq( + Data("ok "), + Partial("other") + ) + ), + false + ) + ) + ) + ) } "triple braces is fine" in { val text = "Hello, {{{foo}}}." - MustacheParser(text) must be(Template(Seq( - Data("Hello, {"), - Interpolation("foo"), - Data("}.") - ))) + MustacheParser(text) must be( + Template( + Seq( + Data("Hello, {"), + Interpolation("foo"), + Data("}.") + ) + ) + ) } "section with joiner" in { val text = "Students: {{#students}}{{name}}{{/students|, }}" - MustacheParser(text) must be(Template(Seq( - Data("Students: "), - Section("students", Template(Seq( - Interpolation("name") - )), false, Some(", ")) - ))) + MustacheParser(text) must be( + Template( + Seq( + Data("Students: "), + Section( + "students", + Template( + Seq( + Interpolation("name") + ) + ), + false, + Some(", ") + ) + ) + ) + ) } } } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/testutil/EvalHelper.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/testutil/EvalHelper.scala index 510079d86..3105004ec 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/testutil/EvalHelper.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/testutil/EvalHelper.scala @@ -127,4 +127,3 @@ trait EvalHelper { Arrays.copyOfRange(buf.getArray, 0, buf.length) } } - diff --git a/scrooge-linter/src/main/scala/com/twitter/scrooge/linter/Linter.scala b/scrooge-linter/src/main/scala/com/twitter/scrooge/linter/Linter.scala index ab8e01fd9..161863e86 100644 --- a/scrooge-linter/src/main/scala/com/twitter/scrooge/linter/Linter.scala +++ b/scrooge-linter/src/main/scala/com/twitter/scrooge/linter/Linter.scala @@ -41,7 +41,9 @@ object LintRule { def all(rules: Seq[LintRule]): LintRule = new LintRule { def apply(doc: Document): Seq[LintMessage] = - rules flatMap { r => r(doc) } + rules flatMap { r => + r(doc) + } } val DefaultRules = Seq( @@ -54,7 +56,7 @@ object LintRule { TransitivePersistence, FieldIndexGreaterThanZeroRule, MalformedDocstring - ) + ) val Rules = DefaultRules ++ Seq( // Add any optional rules here. @@ -86,23 +88,30 @@ object LintRule { def findUnpersistedStructsFromFields(fieldTypes: Seq[FieldType]): Seq[String] = { fieldTypes.flatMap { - case StructType(s, scopePrefix) => findUnpersistedStructs(s, scopePrefix) // includes Unions + case StructType(s, scopePrefix) => + findUnpersistedStructs(s, scopePrefix) // includes Unions case EnumType(enum: Enum, _) => Seq.empty // enums don't have annotations - case MapType(keyType, valueType, _) => findUnpersistedStructsFromFields(Seq(keyType, valueType)) + case MapType(keyType, valueType, _) => + findUnpersistedStructsFromFields(Seq(keyType, valueType)) case SetType(eltType, _) => findUnpersistedStructsFromFields(Seq(eltType)) case ListType(eltType, _) => findUnpersistedStructsFromFields(Seq(eltType)) - case _:BaseType => Seq.empty // primitive types - case _:ReferenceType => // ReferenceTypes have been resolved, this can not happen - throw new UnsupportedOperationException("There should be no ReferenceType anymore after type resolution") + case _: BaseType => Seq.empty // primitive types + case _: ReferenceType => // ReferenceTypes have been resolved, this can not happen + throw new UnsupportedOperationException( + "There should be no ReferenceType anymore after type resolution" + ) } } for { - struct <- doc.structs if isPersisted(struct) // structs contains all StructLikes including Structs and Unions + struct <- doc.structs + if isPersisted(struct) // structs contains all StructLikes including Structs and Unions structChild <- findUnpersistedStructs(struct) - } yield LintMessage( + } yield + LintMessage( s"struct ${struct.originalName} with persisted annotation refers to struct ${structChild} that is not annotated persisted.", - Error) + Error + ) } } @@ -115,10 +124,16 @@ object LintRule { val fieldsErrors = for { s <- persistedStructs field <- s.fields if field.docstring.isEmpty - } yield LintMessage(s"Missing documentation on field ${field.originalName} in struct ${s.originalName} annotated (persisted = 'true').") + } yield + LintMessage( + s"Missing documentation on field ${field.originalName} in struct ${s.originalName} annotated (persisted = 'true')." + ) val structErrors = for { s <- persistedStructs if s.docstring.isEmpty - } yield LintMessage(s"Missing documentation on struct ${s.originalName} annotated (persisted = 'true').") + } yield + LintMessage( + s"Missing documentation on struct ${s.originalName} annotated (persisted = 'true')." + ) structErrors ++ fieldsErrors } } @@ -175,7 +190,7 @@ object LintRule { // service function fields are generated as a function val serviceFnParams = doc.defs.collect { - case service@Service(id, _, _, _, _) => + case service @ Service(id, _, _, _, _) => service.functions.collect { case Function(fnId, _, _, args, _, _, _) if args.length >= optimalLimit => lintMessage("thrift service method parameters", s"${id.name}.${fnId.name} function") @@ -185,7 +200,7 @@ object LintRule { // service function exceptions fields generate thrift response struct // constructors and an unapply function val serviceFnExceptions = doc.defs.collect { - case service@Service(id, _, _, _, _) => + case service @ Service(id, _, _, _, _) => service.functions.collect { case Function(fnId, _, _, _, throws, _, _) if throws.length >= optimalLimit => lintMessage("thrift service method exceptions", s"${id.name}.${fnId.name} function") @@ -194,7 +209,7 @@ object LintRule { // service functions are generated as constructor parameters for the service val serviceFns = doc.defs.collect { - case service@Service(id, _, fns, _, _) if fns.length >= optimalLimit => + case service @ Service(id, _, fns, _, _) if fns.length >= optimalLimit => lintMessage("thrift service methods", s"${id.name} struct") } @@ -211,14 +226,18 @@ object LintRule { case struct: StructLike => if (!isTitleCase(struct.originalName)) { val correctName = Identifier.toTitleCase(struct.originalName) - messages += LintMessage(s"Struct name ${struct.originalName} is not UpperCamelCase. " + - s"Should be: ${correctName}. \n${struct.pos.longString}") + messages += LintMessage( + s"Struct name ${struct.originalName} is not UpperCamelCase. " + + s"Should be: ${correctName}. \n${struct.pos.longString}" + ) } struct.fields.foreach { f => if (!isCamelCase(f.originalName)) { - messages += LintMessage(s"Field name ${f.originalName} is not lowerCamelCase. " + - s"Should be: ${Identifier.toCamelCase(f.originalName)}. \n${f.pos.longString}") + messages += LintMessage( + s"Field name ${f.originalName} is not lowerCamelCase. " + + s"Should be: ${Identifier.toCamelCase(f.originalName)}. \n${f.pos.longString}" + ) } } case _ => @@ -241,8 +260,10 @@ object LintRule { case struct: StructLike => struct.fields.collect { case f if f.requiredness == Requiredness.Required && f.default.nonEmpty => - LintMessage(s"Required field ${f.originalName} has a default value. " + - s"Make it optional or remove the default.\n${f.pos.longString}") + LintMessage( + s"Required field ${f.originalName} has a default value. " + + s"Make it optional or remove the default.\n${f.pos.longString}" + ) } }.flatten } @@ -254,68 +275,277 @@ object LintRule { val messages = new ArrayBuffer[LintMessage] val identifiers = doc.defs.collect { case struct: StructLike => - languageKeywords.foreach { case (lang, keywords) => - if (keywords.contains(struct.originalName)) { - messages += LintMessage( - s"Struct name ${struct.originalName}} is a $lang keyword. Avoid using keywords as identifiers.\n" + - s"${struct.pos.longString}") + languageKeywords.foreach { + case (lang, keywords) => + if (keywords.contains(struct.originalName)) { + messages += LintMessage( + s"Struct name ${struct.originalName}} is a $lang keyword. Avoid using keywords as identifiers.\n" + + s"${struct.pos.longString}" + ) } } val fieldNames = struct.fields.map(_.originalName).toSet for { (lang, keywords) <- languageKeywords - fields = struct.fields.filter { f => keywords.contains(f.originalName) } if fields.nonEmpty + fields = struct.fields.filter { f => + keywords.contains(f.originalName) + } if fields.nonEmpty fieldNames = fields.map(_.originalName) - } messages += LintMessage(s"Found field names that are $lang keywords: ${fieldNames.mkString(", ")}. " + - s"Avoid using keywords as identifiers.\n${fields.head.pos.longString}") + } messages += LintMessage( + s"Found field names that are $lang keywords: ${fieldNames.mkString(", ")}. " + + s"Avoid using keywords as identifiers.\n${fields.head.pos.longString}" + ) } messages } private[this] val languageKeywords: Map[String, Set[String]] = Map( - "scala" -> Set("abstract", "case", "catch", "class", "def", "do", "else", - "extends", "false", "final", "finally", "for", "forSome", "if", - "implicit", "import", "lazy", "match", "new", "null", "object", - "override", "package", "private", "protected", "return", "sealed", - "super", "this", "throw", "trait", "try", "true", - "type", "val", "var", "while", "with", "yield"), - - "java" -> Set("abstract", - "assert", "boolean", "break", "byte", "case", "catch", "char", "class", - "const", "continue", "default", "do", "double", "else", "enum", "extends", - "final", "finally", "float", "for", "goto", "if", "implements", "import", - "instanceof", "int", "interface", "long", "native", "new", "package", - "private", "protected", "public", "return", "short", "static", "strictfp", - "super", "switch", "synchronized", "this", "throw", "throws", "transient", - "try", "void", "volatile", "while"), - - "ruby" -> Set("BEGIN", "END", "__ENCODING__", "__END__", "__FILE__", "__LINE__", - "alias", "and", "begin", "break", "case", "class", "def", "defined?", - "do", "else", "elsif", "end", "ensure", "false", "for", "if", - "in", "module", "next", "nil", "not", "or", "redo", "rescue", "retry", - "return", "self", "super", "then", "true", "undef", "unless", "until", - "when", "while", "yield"), - - "php" -> Set("__halt_compiler", "abstract", "and", "array", "as", "break", "callable", - "case", "catch", "class", "clone", "const", "continue", "declare", "default", - "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", - "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", - "final", "finally", "for", "foreach", "function", "global", "goto", "if", - "implements", "include", "include_once", "instanceof", "insteadof", "interface", - "isset", "list", "namespace", "new", "or", "print", "private", "protected", - "public", "require", "require_once", "return", "static", "switch", "throw", - "trait", "try", "unset", "use", "var", "while", "xor", "yield"), - - "python" -> Set("and", "as", "assert", "break", "class", "continue", "def", - "del", "elif", "else", "except", "exec", "finally", "for", "from", "global", - "if", "import", "in", "is", "lambda", "not", "or", "pass", - "print", "raise", "return", "try", "while", "with", "yield") + "scala" -> Set( + "abstract", + "case", + "catch", + "class", + "def", + "do", + "else", + "extends", + "false", + "final", + "finally", + "for", + "forSome", + "if", + "implicit", + "import", + "lazy", + "match", + "new", + "null", + "object", + "override", + "package", + "private", + "protected", + "return", + "sealed", + "super", + "this", + "throw", + "trait", + "try", + "true", + "type", + "val", + "var", + "while", + "with", + "yield" + ), + "java" -> Set( + "abstract", + "assert", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "const", + "continue", + "default", + "do", + "double", + "else", + "enum", + "extends", + "final", + "finally", + "float", + "for", + "goto", + "if", + "implements", + "import", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "strictfp", + "super", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "try", + "void", + "volatile", + "while" + ), + "ruby" -> Set( + "BEGIN", + "END", + "__ENCODING__", + "__END__", + "__FILE__", + "__LINE__", + "alias", + "and", + "begin", + "break", + "case", + "class", + "def", + "defined?", + "do", + "else", + "elsif", + "end", + "ensure", + "false", + "for", + "if", + "in", + "module", + "next", + "nil", + "not", + "or", + "redo", + "rescue", + "retry", + "return", + "self", + "super", + "then", + "true", + "undef", + "unless", + "until", + "when", + "while", + "yield" + ), + "php" -> Set( + "__halt_compiler", + "abstract", + "and", + "array", + "as", + "break", + "callable", + "case", + "catch", + "class", + "clone", + "const", + "continue", + "declare", + "default", + "die", + "do", + "echo", + "else", + "elseif", + "empty", + "enddeclare", + "endfor", + "endforeach", + "endif", + "endswitch", + "endwhile", + "eval", + "exit", + "extends", + "final", + "finally", + "for", + "foreach", + "function", + "global", + "goto", + "if", + "implements", + "include", + "include_once", + "instanceof", + "insteadof", + "interface", + "isset", + "list", + "namespace", + "new", + "or", + "print", + "private", + "protected", + "public", + "require", + "require_once", + "return", + "static", + "switch", + "throw", + "trait", + "try", + "unset", + "use", + "var", + "while", + "xor", + "yield" + ), + "python" -> Set( + "and", + "as", + "assert", + "break", + "class", + "continue", + "def", + "del", + "elif", + "else", + "except", + "exec", + "finally", + "for", + "from", + "global", + "if", + "import", + "in", + "is", + "lambda", + "not", + "or", + "pass", + "print", + "raise", + "return", + "try", + "while", + "with", + "yield" + ) ) // Returns a list of languages in which id is a keyword. private[this] def checkKeyword(id: String): Iterable[String] = { - languageKeywords.collect { case (lang, keywords) if keywords.contains(id) => - lang + languageKeywords.collect { + case (lang, keywords) if keywords.contains(id) => + lang } } } @@ -325,12 +555,15 @@ object LintRule { */ object FieldIndexGreaterThanZeroRule extends LintRule { def apply(doc: Document) = { - doc.defs.collect { + doc.defs.collect { case struct: StructLike => struct.fields.collect { case f if f.index <= 0 => - LintMessage(s"Non positive field id of ${f.originalName}. Field id should be supplied and must be " + - s" greater than zero in struct \n${struct.originalName}", Warning) + LintMessage( + s"Non positive field id of ${f.originalName}. Field id should be supplied and must be " + + s" greater than zero in struct \n${struct.originalName}", + Warning + ) } }.flatten } @@ -340,23 +573,21 @@ object LintRule { // Thrift docstring is invalid def apply(doc: Document): Seq[LintMessage] = { val docStrings: Seq[String] = - doc.defs - .flatMap { - case enumField: EnumField => - Seq(enumField.docstring) - case enum: Enum => - Seq(enum.docstring) - case const: ConstDefinition => - Seq(const.docstring) - case struct: StructLike => - Seq(struct.docstring) ++ - struct.fields.map(_.docstring) - case service: Service => - Seq(service.docstring) ++ - service.functions.map(_.docstring) - case _ => Seq.empty - } - .flatten + doc.defs.flatMap { + case enumField: EnumField => + Seq(enumField.docstring) + case enum: Enum => + Seq(enum.docstring) + case const: ConstDefinition => + Seq(const.docstring) + case struct: StructLike => + Seq(struct.docstring) ++ + struct.fields.map(_.docstring) + case service: Service => + Seq(service.docstring) ++ + service.functions.map(_.docstring) + case _ => Seq.empty + }.flatten verifyDocstring(docStrings) } @@ -415,7 +646,7 @@ class Linter(cfg: Config) { val errorCount = messages.count(_.level == Error) val warnCount = messages.count(_.level == Warning) - if (errorCount + warnCount > 0 ) { + if (errorCount + warnCount > 0) { warning("%d warnings and %d errors found".format(messages.size - errorCount, errorCount)) } errorCount @@ -425,7 +656,12 @@ class Linter(cfg: Config) { def lint(): Int = { val requiresIncludes = rules.exists { _.requiresIncludes } val importer = Importer(new File(".")) +: Importer(cfg.includePaths) - val parser = new ThriftParser(importer, cfg.strict, defaultOptional = false, skipIncludes = !requiresIncludes) + val parser = new ThriftParser( + importer, + cfg.strict, + defaultOptional = false, + skipIncludes = !requiresIncludes + ) val errorCounts = cfg.files.map { inputFile => if (cfg.verbose) diff --git a/scrooge-linter/src/main/scala/com/twitter/scrooge/linter/Main.scala b/scrooge-linter/src/main/scala/com/twitter/scrooge/linter/Main.scala index 09a5fab84..3cf6eee1b 100644 --- a/scrooge-linter/src/main/scala/com/twitter/scrooge/linter/Main.scala +++ b/scrooge-linter/src/main/scala/com/twitter/scrooge/linter/Main.scala @@ -31,7 +31,6 @@ case class Config( verbose: Boolean = false ) - object Main { def main(args: Array[String]) { val cfg = parseOptions(args) @@ -61,48 +60,59 @@ object Main { opt[Unit]('v', "verbose") action { (_, c) => c.copy(verbose = true) - } text("log verbose messages about progress") + } text ("log verbose messages about progress") - opt[Unit]('i', "ignore-errors") text ("return 0 if linter errors are found. If not set, linter returns 1.") action { (_, c) => - c.copy(ignoreErrors = true) + opt[Unit]('i', "ignore-errors") text ("return 0 if linter errors are found. If not set, linter returns 1.") action { + (_, c) => + c.copy(ignoreErrors = true) } - opt[String]('n', "include-path") unbounded() valueName("") action { (path, c) => + opt[String]('n', "include-path") unbounded () valueName ("") action { (path, c) => c.copy(includePaths = c.includePaths ++ path.split(File.pathSeparator)) - } text("path(s) to search for included thrift files (may be used multiple times)") - - def findRule(ruleName: String) = LintRule.Rules.find((r) => r.name == ruleName).getOrElse({ - println(s"Unknown rule ${ruleName}. Available: ${LintRule.Rules.map(_.name).mkString(", ")}") + } text ("path(s) to search for included thrift files (may be used multiple times)") + + def findRule(ruleName: String) = + LintRule.Rules + .find((r) => r.name == ruleName) + .getOrElse({ + println( + s"Unknown rule ${ruleName}. Available: ${LintRule.Rules.map(_.name).mkString(", ")}" + ) sys.exit(1) }) def ruleList(rules: Seq[LintRule]) = rules.map(_.name).mkString(", ") - opt[String]('e', "enable-rule") unbounded() valueName("") action { (ruleName, c) => { - val rule = findRule(ruleName); - if (c.enabledRules.contains(rule)) c else c.copy(enabledRules = c.enabledRules :+ rule) - } - } text(s"rules to be enabled.\n Available: ${ruleList(LintRule.Rules)}\n Default: ${ruleList(LintRule.DefaultRules)}") - - opt[String]('d', "disable-rule") unbounded() valueName("") action { (ruleName, c) => { - c.copy(enabledRules = c.enabledRules.filter(_ != findRule(ruleName))) - } - } text("rules to be disabled.") - - - opt[Unit]('p', "ignore-parse-errors") text ("continue if parsing errors are found.") action { (_, c) => - c.copy(ignoreParseErrors = true) + opt[String]('e', "enable-rule") unbounded () valueName ("") action { + (ruleName, c) => + { + val rule = findRule(ruleName); + if (c.enabledRules.contains(rule)) c else c.copy(enabledRules = c.enabledRules :+ rule) + } + } text (s"rules to be enabled.\n Available: ${ruleList(LintRule.Rules)}\n Default: ${ruleList(LintRule.DefaultRules)}") + + opt[String]('d', "disable-rule") unbounded () valueName ("") action { + (ruleName, c) => + { + c.copy(enabledRules = c.enabledRules.filter(_ != findRule(ruleName))) + } + } text ("rules to be disabled.") + + opt[Unit]('p', "ignore-parse-errors") text ("continue if parsing errors are found.") action { + (_, c) => + c.copy(ignoreParseErrors = true) } opt[Unit]('w', "warnings") text ("show linter warnings (default = False)") action { (_, c) => c.copy(showWarnings = true) } - opt[Unit]("disable-strict") text ("issue warnings on non-severe parse errors instead of aborting") action { (_, c) => - c.copy(strict = false) + opt[Unit]("disable-strict") text ("issue warnings on non-severe parse errors instead of aborting") action { + (_, c) => + c.copy(strict = false) } - arg[String]("") unbounded() text ("thrift files to compile") action { (input, c) => + arg[String]("") unbounded () text ("thrift files to compile") action { (input, c) => c.copy(files = c.files :+ input) } } diff --git a/scrooge-linter/src/test/scala/com/twitter/scrooge/linter/LinterSpec.scala b/scrooge-linter/src/test/scala/com/twitter/scrooge/linter/LinterSpec.scala index 654bc5574..0beaedb05 100644 --- a/scrooge-linter/src/test/scala/com/twitter/scrooge/linter/LinterSpec.scala +++ b/scrooge-linter/src/test/scala/com/twitter/scrooge/linter/LinterSpec.scala @@ -20,8 +20,6 @@ import com.twitter.scrooge.ast._ import org.junit.runner.RunWith import org.scalatest.{MustMatchers, WordSpec} import org.scalatest.junit.JUnitRunner - - @RunWith(classOf[JUnitRunner]) class LinterSpec extends WordSpec with MustMatchers { @@ -35,21 +33,28 @@ class LinterSpec extends WordSpec with MustMatchers { s"val$i", TString, default = Some(StringLiteral(s"val-$i")), - requiredness = Requiredness.Required) + requiredness = Requiredness.Required + ) } "Linter" should { "pass Namespaces" in { mustPass( - LintRule.Namespaces(Document(Seq( - Namespace("java", Identifier("com.twitter.oatmeal")), - Namespace("scala", Identifier("com.twitter.oatmeal")) - ), Nil)) + LintRule.Namespaces( + Document( + Seq( + Namespace("java", Identifier("com.twitter.oatmeal")), + Namespace("scala", Identifier("com.twitter.oatmeal")) + ), + Nil + ) + ) ) } "fail Namespaces" in { - val errors = LintRule.Namespaces(Document(Seq(Namespace("java", SimpleID("asdf"))), Nil)).toSeq + val errors = + LintRule.Namespaces(Document(Seq(Namespace("java", SimpleID("asdf"))), Nil)).toSeq errors.length must be(1) assert(errors(0).msg contains ("Missing namespace")) } @@ -60,52 +65,68 @@ class LinterSpec extends WordSpec with MustMatchers { Document( Seq( Namespace("java", SimpleID("asdf")), - Include("com.twitter.oatmeal", Document(Seq(), Seq()))), - Nil)) + Include("com.twitter.oatmeal", Document(Seq(), Seq())) + ), + Nil + ) + ) ) } "fail RelativeIncludes" in { - val errors = LintRule.RelativeIncludes(Document( - Seq( - Namespace("java", SimpleID("asdf")), - Include("./dir1/../dir1/include1.thrift", Document(Seq(), Seq()))), - Nil)).toSeq + val errors = LintRule + .RelativeIncludes( + Document( + Seq( + Namespace("java", SimpleID("asdf")), + Include("./dir1/../dir1/include1.thrift", Document(Seq(), Seq())) + ), + Nil + ) + ) + .toSeq errors.size must be(1) assert(errors(0).msg contains ("Relative include path found")) } "pass CamelCase" in { mustPass( - LintRule.CamelCase(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", - Seq(Field(1, - SimpleID("camelCaseFieldName"), - "camelCaseFieldName", - TString)), - None)))) + LintRule.CamelCase( + Document( + Seq(), + Seq( + Struct( + SimpleID("SomeType"), + "SomeType", + Seq(Field(1, SimpleID("camelCaseFieldName"), "camelCaseFieldName", TString)), + None + ) + ) + ) + ) ) } "fail CamelCase" in { - val errors = LintRule.CamelCase(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", - Seq(Field(1, - SimpleID("non_camel_case"), - "non_camel_case", - TString)), - None)))).toSeq + val errors = LintRule + .CamelCase( + Document( + Seq(), + Seq( + Struct( + SimpleID("SomeType"), + "SomeType", + Seq(Field(1, SimpleID("non_camel_case"), "non_camel_case", TString)), + None + ) + ) + ) + ) + .toSeq errors.length must be(1) assert(errors(0).msg contains ("lowerCamelCase")) } - def struct(name: String, fields: Map[String, FieldType], persisted: Boolean = false) = Struct( SimpleID(name), @@ -117,22 +138,24 @@ class LinterSpec extends WordSpec with MustMatchers { if (persisted) Map("persisted" -> "true") else Map.empty ) - "fail TransitivePersistence" in { - val errors = LintRule.TransitivePersistence( - Document( - Seq(), - Seq( - struct( - "SomeType", - Map( - "foo" -> TString, - "bar" -> StructType(struct("SomeOtherType", Map.empty)) - ), - true + val errors = LintRule + .TransitivePersistence( + Document( + Seq(), + Seq( + struct( + "SomeType", + Map( + "foo" -> TString, + "bar" -> StructType(struct("SomeOtherType", Map.empty)) + ), + true + ) ) ) - )).toSeq + ) + .toSeq errors.length must be(1) val error = errors(0).msg assert(error.contains("persisted")) @@ -141,36 +164,42 @@ class LinterSpec extends WordSpec with MustMatchers { } "pass TransitivePersistence" in { - mustPass(LintRule.TransitivePersistence( - Document( - Seq(), - Seq( - struct( - "SomeType", - Map( - "foo" -> TString, - "bar" -> StructType(struct("SomeOtherType", Map.empty, true)) - ), - true + mustPass( + LintRule.TransitivePersistence( + Document( + Seq(), + Seq( + struct( + "SomeType", + Map( + "foo" -> TString, + "bar" -> StructType(struct("SomeOtherType", Map.empty, true)) + ), + true + ) ) ) - ))) + ) + ) } "fail DocumentedPersisted" in { - val errors = LintRule.DocumentedPersisted( - Document( - Seq(), - Seq( - struct( - "SomeType", - Map( - "foo" -> TString - ), - true + val errors = LintRule + .DocumentedPersisted( + Document( + Seq(), + Seq( + struct( + "SomeType", + Map( + "foo" -> TString + ), + true + ) ) ) - )).toSeq + ) + .toSeq errors.length must be(2) assert(errors.forall(_.level == LintLevel.Warning)) val structError = errors.head.msg @@ -181,205 +210,274 @@ class LinterSpec extends WordSpec with MustMatchers { } "pass DocumentedPersisted" in { - mustPass(LintRule.DocumentedPersisted( - Document( - Seq(), - Seq( - Struct( - SimpleID("SomeType"), - "SomeType", - Seq(Field(1, - SimpleID("foo"), - "foo", - TString, - docstring = Some("blah blah"))), - docstring = Some("documented struct is documented"), - Map("persisted" -> "true")) + mustPass( + LintRule.DocumentedPersisted( + Document( + Seq(), + Seq( + Struct( + SimpleID("SomeType"), + "SomeType", + Seq(Field(1, SimpleID("foo"), "foo", TString, docstring = Some("blah blah"))), + docstring = Some("documented struct is documented"), + Map("persisted" -> "true") + ) + ) ) - ))) + ) + ) } "pass RequiredFieldDefault" in { mustPass( - LintRule.RequiredFieldDefault(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", + LintRule.RequiredFieldDefault( + Document( + Seq(), Seq( - Field( - 1, - SimpleID("f1"), - "f1", - TString, - default = Some(StringLiteral("v1")), - requiredness = Requiredness.Optional), - Field( - 2, - SimpleID("f2"), - "f2", - TString, - default = None, - requiredness = Requiredness.Required)), - None)))) + Struct( + SimpleID("SomeType"), + "SomeType", + Seq( + Field( + 1, + SimpleID("f1"), + "f1", + TString, + default = Some(StringLiteral("v1")), + requiredness = Requiredness.Optional + ), + Field( + 2, + SimpleID("f2"), + "f2", + TString, + default = None, + requiredness = Requiredness.Required + ) + ), + None + ) + ) + ) + ) ) } "fail RequiredFieldDefault" in { - val errors = LintRule.RequiredFieldDefault(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", - Seq( - Field( - 1, - SimpleID("f1"), - "f1", - TString, - default = Some(StringLiteral("v1")), - requiredness = Requiredness.Required)), - None)))).toSeq + val errors = LintRule + .RequiredFieldDefault( + Document( + Seq(), + Seq( + Struct( + SimpleID("SomeType"), + "SomeType", + Seq( + Field( + 1, + SimpleID("f1"), + "f1", + TString, + default = Some(StringLiteral("v1")), + requiredness = Requiredness.Required + ) + ), + None + ) + ) + ) + ) + .toSeq errors.length must be(1) assert(errors(0).msg contains ("Required field")) } "pass Keywords" in { mustPass( - LintRule.Keywords(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", + LintRule.Keywords( + Document( + Seq(), Seq( - Field( - 1, - SimpleID("klass"), - "klass", - TString, - default = Some(StringLiteral("v1")), - requiredness = Requiredness.Optional), - Field( - 2, - SimpleID("notAKeyWord"), - "notAKeyWord", - TString, - default = None, - requiredness = Requiredness.Required)), - None)))) + Struct( + SimpleID("SomeType"), + "SomeType", + Seq( + Field( + 1, + SimpleID("klass"), + "klass", + TString, + default = Some(StringLiteral("v1")), + requiredness = Requiredness.Optional + ), + Field( + 2, + SimpleID("notAKeyWord"), + "notAKeyWord", + TString, + default = None, + requiredness = Requiredness.Required + ) + ), + None + ) + ) + ) + ) ) } "fail Keywords" in { - val errors = LintRule.Keywords(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", - Seq( - Field( - 1, - SimpleID("val"), - "val", - TString, - default = Some(StringLiteral("v1")), - requiredness = Requiredness.Optional)), - None)))).toSeq + val errors = LintRule + .Keywords( + Document( + Seq(), + Seq( + Struct( + SimpleID("SomeType"), + "SomeType", + Seq( + Field( + 1, + SimpleID("val"), + "val", + TString, + default = Some(StringLiteral("v1")), + requiredness = Requiredness.Optional + ) + ), + None + ) + ) + ) + ) + .toSeq errors.length must be(1) assert(errors(0).msg contains ("Avoid using keywords")) } "pass non negative index" in { mustPass( - LintRule.FieldIndexGreaterThanZeroRule(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", + LintRule.FieldIndexGreaterThanZeroRule( + Document( + Seq(), Seq( - Field( - 1, - SimpleID("val"), - "val", - TString, - default = Some(StringLiteral("v1")), - requiredness = Requiredness.Optional) - ), - None)))) + Struct( + SimpleID("SomeType"), + "SomeType", + Seq( + Field( + 1, + SimpleID("val"), + "val", + TString, + default = Some(StringLiteral("v1")), + requiredness = Requiredness.Optional + ) + ), + None + ) + ) + ) + ) ) } "warn non negative index" in { - val errors = LintRule.FieldIndexGreaterThanZeroRule(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", - Seq( - Field( - -1, - SimpleID("val"), - "val", - TString, - default = Some(StringLiteral("v1")), - requiredness = Requiredness.Optional) - ), - None)))).toSeq + val errors = LintRule + .FieldIndexGreaterThanZeroRule( + Document( + Seq(), + Seq( + Struct( + SimpleID("SomeType"), + "SomeType", + Seq( + Field( + -1, + SimpleID("val"), + "val", + TString, + default = Some(StringLiteral("v1")), + requiredness = Requiredness.Optional + ) + ), + None + ) + ) + ) + ) + .toSeq errors.length must be(1) assert(errors(0).msg contains ("Field id should be supplied")) } "warn on max struct fields" in { - val warnings = LintRule.CompilerOptimizedMethodParamLimit(Document( - Seq(), - Seq(FunctionArgs( - SimpleID("SomeType"), - "SomeType", - genFields(100))))).toSeq + val warnings = LintRule + .CompilerOptimizedMethodParamLimit( + Document(Seq(), Seq(FunctionArgs(SimpleID("SomeType"), "SomeType", genFields(100)))) + ) + .toSeq warnings.size must be(1) assert(warnings(0).msg contains ("fields for thrift struct")) assert(warnings(0).msg contains ("SomeType")) } "warn on max service function fields" in { - val warnings = LintRule.CompilerOptimizedMethodParamLimit(Document( - Seq(), - Seq(Service( - SimpleID("SomeType"), - parent = None, - functions = Seq( - Function( - SimpleID("someFunc"), - "someFunc", - TString, - genFields(100), - throws = Seq(), - docstring = None + val warnings = LintRule + .CompilerOptimizedMethodParamLimit( + Document( + Seq(), + Seq( + Service( + SimpleID("SomeType"), + parent = None, + functions = Seq( + Function( + SimpleID("someFunc"), + "someFunc", + TString, + genFields(100), + throws = Seq(), + docstring = None + ) + ), + Some("SomeType") + ) ) - ), - Some("SomeType"))))).toSeq + ) + ) + .toSeq warnings.size must be(1) assert(warnings(0).msg contains ("thrift service method parameters")) assert(warnings(0).msg contains ("SomeType.someFunc")) } "warn on max service function exception fields" in { - val warnings = LintRule.CompilerOptimizedMethodParamLimit(Document( - Seq(), - Seq(Service( - SimpleID("SomeType"), - parent = None, - functions = Seq( - Function( - SimpleID("someFunc"), - "someFunc", - TString, - args = Seq(), - throws = genFields(100), - docstring = None + val warnings = LintRule + .CompilerOptimizedMethodParamLimit( + Document( + Seq(), + Seq( + Service( + SimpleID("SomeType"), + parent = None, + functions = Seq( + Function( + SimpleID("someFunc"), + "someFunc", + TString, + args = Seq(), + throws = genFields(100), + docstring = None + ) + ), + Some("SomeType") + ) ) - ), - Some("SomeType"))))).toSeq + ) + ) + .toSeq warnings.size must be(1) assert(warnings(0).msg contains ("thrift service method exceptions")) assert(warnings(0).msg contains ("SomeType.someFunc")) @@ -387,22 +485,17 @@ class LinterSpec extends WordSpec with MustMatchers { "warn on max service functions " in { val funcs = (0 until 100) map { i => - Function( - SimpleID(s"val$i"), - s"val$i", - TString, - Seq(), - Seq(), - None) + Function(SimpleID(s"val$i"), s"val$i", TString, Seq(), Seq(), None) } - val warnings = LintRule.CompilerOptimizedMethodParamLimit(Document( - Seq(), - Seq(Service( - SimpleID("SomeType"), - parent = None, - functions = funcs, - Some("SomeType"))))).toSeq + val warnings = LintRule + .CompilerOptimizedMethodParamLimit( + Document( + Seq(), + Seq(Service(SimpleID("SomeType"), parent = None, functions = funcs, Some("SomeType"))) + ) + ) + .toSeq warnings.size must be(1) assert(warnings(0).msg contains ("thrift service methods")) assert(warnings(0).msg contains ("SomeType")) @@ -413,64 +506,103 @@ class LinterSpec extends WordSpec with MustMatchers { val invalidCommentStrings = Seq("/** /* */") invalidCommentStrings.foreach { docString: String => - - val funcField = LintRule.MalformedDocstring(Document( - Seq(), - Seq(FunctionArgs( - SimpleID("SomeType"), - "SomeType", - genFields().map(_.copy(docstring = Some(docString))))))).toSeq + val funcField = LintRule + .MalformedDocstring( + Document( + Seq(), + Seq( + FunctionArgs( + SimpleID("SomeType"), + "SomeType", + genFields().map(_.copy(docstring = Some(docString))) + ) + ) + ) + ) + .toSeq funcField.size must be(1) assert(funcField(0).msg contains (expectedMessage)) - val structLike = LintRule.MalformedDocstring(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", - genFields(), - Some(docString))))).toSeq + val structLike = LintRule + .MalformedDocstring( + Document( + Seq(), + Seq(Struct(SimpleID("SomeType"), "SomeType", genFields(), Some(docString))) + ) + ) + .toSeq structLike.size must be(1) assert(structLike(0).msg contains (expectedMessage)) - val structLikeField = LintRule.MalformedDocstring(Document( - Seq(), - Seq(Struct( - SimpleID("SomeType"), - "SomeType", - Seq(Field(1, - SimpleID("someField"), - "someField", - TString, docstring = Some(docString))), - None)))).toSeq + val structLikeField = LintRule + .MalformedDocstring( + Document( + Seq(), + Seq( + Struct( + SimpleID("SomeType"), + "SomeType", + Seq( + Field( + 1, + SimpleID("someField"), + "someField", + TString, + docstring = Some(docString) + ) + ), + None + ) + ) + ) + ) + .toSeq structLikeField.size must be(1) assert(structLikeField(0).msg contains (expectedMessage)) - val const = LintRule.MalformedDocstring(Document( - Seq(), - Seq(ConstDefinition( - SimpleID("SomeType"), - TString, - StringLiteral("test"), - Some(docString))) - )).toSeq + val const = LintRule + .MalformedDocstring( + Document( + Seq(), + Seq( + ConstDefinition( + SimpleID("SomeType"), + TString, + StringLiteral("test"), + Some(docString) + ) + ) + ) + ) + .toSeq const.size must be(1) assert(const(0).msg contains (expectedMessage)) - val enum = LintRule.MalformedDocstring(Document( - Seq(), - Seq(Enum( - SimpleID("SomeType"), - Seq(EnumField(SimpleID("enumField"), 0, None)), - Some(docString))) - )).toSeq + val enum = LintRule + .MalformedDocstring( + Document( + Seq(), + Seq( + Enum( + SimpleID("SomeType"), + Seq(EnumField(SimpleID("enumField"), 0, None)), + Some(docString) + ) + ) + ) + ) + .toSeq enum.size must be(1) assert(enum(0).msg contains (expectedMessage)) - val enumField = LintRule.MalformedDocstring(Document( - Seq(), - Seq(EnumField(SimpleID("enumField"), 0, Some(docString))) - )).toSeq + val enumField = LintRule + .MalformedDocstring( + Document( + Seq(), + Seq(EnumField(SimpleID("enumField"), 0, Some(docString))) + ) + ) + .toSeq enumField.size must be(1) assert(enumField(0).msg contains (expectedMessage)) }