diff --git a/demos/scrooge-maven-demo/pom.xml b/demos/scrooge-maven-demo/pom.xml index d5661166a..124aecea2 100644 --- a/demos/scrooge-maven-demo/pom.xml +++ b/demos/scrooge-maven-demo/pom.xml @@ -72,12 +72,6 @@ 4.10 test - - org.scala-tools.testing - specs_2.9.1 - 1.6.9 - test - org.jmock jmock 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 513f534e6..10523e7ec 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 @@ -1,17 +1,21 @@ package com.twitter.example -import org.specs.SpecificationWithJUnit +import org.junit.runner.RunWith +import org.scalatest.WordSpec +import org.scalatest.junit.JUnitRunner +import org.scalatest.matchers.MustMatchers import com.twitter.mydemo.renamed.User -class DemoSpec extends SpecificationWithJUnit { +@RunWith(classOf[JUnitRunner]) +class DemoSpec extends WordSpec with MustMatchers { def printUser(user: User) {println("User %s, id %d".format(user.name, user.id))} "generated finagle service" should { "server and client" in { val server = DemoServer.buildServer() val client = DemoClient.buildClient(server.localAddress) - client.createUser("Tyrion")().name mustEqual("Tyrion") - client.createUser("Jon")().name mustEqual("Jon") + client.createUser("Tyrion")().name must be("Tyrion") + client.createUser("Jon")().name must be("Jon") } } } diff --git a/project/Build.scala b/project/Build.scala index 85435492f..3d5339a0e 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -79,12 +79,7 @@ object Scrooge extends Build { otherResolvers += m2Repo, libraryDependencies ++= Seq( - "org.scalatest" %% "scalatest" %"1.9.1" % "test", - "org.scala-tools.testing" %% "specs" % "1.6.9" % "test" cross CrossVersion.binaryMapped { - case "2.9.2" => "2.9.1" - case "2.10.0" => "2.10" - case x => x - }, + "org.scalatest" %% "scalatest" % "1.9.1" % "test", "junit" % "junit" % "4.8.1" % "test" ), resolvers += "twitter-repo" at "http://maven.twttr.com", diff --git a/scrooge-generator/pom.xml b/scrooge-generator/pom.xml index 34c235250..040694427 100644 --- a/scrooge-generator/pom.xml +++ b/scrooge-generator/pom.xml @@ -56,12 +56,6 @@ 1.6.1 test - - org.scala-tools.testing - specs_2.9.1 - 1.6.9 - test - org.mockito mockito-all @@ -80,6 +74,12 @@ 1.1 test + + org.scalatest + scalatest_2.9.2 + 1.8 + test + cglib cglib diff --git a/scrooge-generator/src/main/scala/com/twitter/scrooge/java_generator/test/Main.scala b/scrooge-generator/src/main/scala/com/twitter/scrooge/java_generator/test/Main.scala index 3e7135049..4823645be 100644 --- a/scrooge-generator/src/main/scala/com/twitter/scrooge/java_generator/test/Main.scala +++ b/scrooge-generator/src/main/scala/com/twitter/scrooge/java_generator/test/Main.scala @@ -48,7 +48,7 @@ object Main { val oldGenMap = new mutable.HashMap[String, File] if (newGenMap.size != oldGenMap.size) { println("Wrong number of files generated") - exit(1) + sys.exit(1) } FileUtils.getFiles(new File(compiler.destFolder), "**/*.java", "") foreach { s => val file = s.asInstanceOf[File] diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/ASTSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/ASTSpec.scala index d1218d770..1fcf48196 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/ASTSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/ASTSpec.scala @@ -1,18 +1,18 @@ package com.twitter.scrooge.ast -import org.specs.SpecificationWithJUnit +import com.twitter.scrooge.testutil.Spec -class ASTSpec extends SpecificationWithJUnit { +class ASTSpec extends Spec { "Namespace" should { "generate correct namespace from java" in { val doc = Document(Seq(Namespace("java", Identifier("com.twitter.oatmeal"))), Nil) - doc.namespace("java").isDefined must beTrue - doc.namespace("java").get.fullName mustEqual ("com.twitter.oatmeal") + doc.namespace("java").isDefined must be(true) + doc.namespace("java").get.fullName must be("com.twitter.oatmeal") } "reject undefined namespace" in { val doc = Document(Seq(Namespace("warble", Identifier("com.twitter.oatmeal"))), Nil) - doc.namespace("garble") mustEqual None + doc.namespace("garble") must be(None) } "map namespaces" in { @@ -21,8 +21,8 @@ class ASTSpec extends SpecificationWithJUnit { 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) mustEqual - Document(Seq(javaGranolaNs, rbOatmealNs), Nil) + doc.mapNamespaces(namespaceMap) must be( + Document(Seq(javaGranolaNs, rbOatmealNs), Nil)) } "map namespaces recursively" in { @@ -31,10 +31,9 @@ class ASTSpec extends SpecificationWithJUnit { val doc1 = Document(Seq(javaOatmealNs), Nil) val doc2 = Document(Seq(javaOatmealNs, Include("other", doc1)), Nil) val namespaceMap = Map(javaOatmealNs.id.fullName -> javaGranolaNs.id.fullName) - doc2.mapNamespaces(namespaceMap) must beLike { + doc2.mapNamespaces(namespaceMap) match { case Document(Seq(javaGranolaNs, Include(_, included)), Nil) => - included mustEqual Document(Seq(javaGranolaNs), Nil) - true + included must be(Document(Seq(javaGranolaNs), Nil)) } } } @@ -68,7 +67,7 @@ class ASTSpec extends SpecificationWithJUnit { simpleCases foreach { case (input, (expected, _)) => val sid = SimpleID(input) - sid.toCamelCase.name mustEqual expected + sid.toCamelCase.name must be(expected) } } @@ -76,7 +75,7 @@ class ASTSpec extends SpecificationWithJUnit { simpleCases foreach { case (input, (_, expected)) => val sid = SimpleID(input) - sid.toTitleCase.name mustEqual expected + sid.toTitleCase.name must be(expected) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/MainSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/MainSpec.scala index c14bbc56d..9ba17f0b2 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/MainSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/MainSpec.scala @@ -2,10 +2,9 @@ package com.twitter.scrooge import java.io.{FileWriter, File} import scala.io.Source -import org.specs.SpecificationWithJUnit -import com.twitter.scrooge.testutil.TempDirectory +import com.twitter.scrooge.testutil.{Spec, TempDirectory} -class MainSpec extends SpecificationWithJUnit { +class MainSpec extends Spec { "Scrooge Main" should { "gen file mapping with absolute paths" in { val inDir = TempDirectory.create(None) @@ -51,6 +50,6 @@ struct Point { 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" - manifestString mustEqual expected + manifestString must be(expected) } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala index 4768fa328..bef43bcc0 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala @@ -1,7 +1,7 @@ package com.twitter.scrooge +import com.twitter.scrooge.testutil.Spec import org.apache.thrift.protocol.TType -import org.specs.SpecificationWithJUnit import scala.collection.{Map, Set} import thrift.test._ @@ -9,40 +9,40 @@ import thrift.test._ // but scrooge-generator already has all the infrastructure to do // generation and testing and anyway requires scrooge-runtime for // tests. -class ThriftStructMetaDataSpec extends SpecificationWithJUnit { +class ThriftStructMetaDataSpec extends Spec { "Provide useful metadata" in { val s = XtructColl(Map(1 -> 2L), Seq("test"), Set(10.toByte), 123) val metaData = XtructColl.metaData assert(metaData.codecClass == XtructColl.getClass) // mustEqual doesn't work here - metaData.structClassName mustEqual "thrift.test.XtructColl" - metaData.structName mustEqual "XtructColl" - metaData.structClass mustEqual classOf[XtructColl] + metaData.structClassName must be("thrift.test.XtructColl") + metaData.structName must be("XtructColl") + metaData.structClass must be(classOf[XtructColl]) val Seq(f1, f2, f3, f4) = metaData.fields.sortBy(_.id) - f1.name mustEqual "a_map" - f1.id mustEqual 1 - f1.`type` mustEqual TType.MAP - f1.manifest mustEqual Some(implicitly[Manifest[Map[Int, Long]]]) - f1.getValue[Map[Int, Long]](s) mustEqual Map(1 -> 2L) - - f2.name mustEqual "a_list" - f2.id mustEqual 2 - f2.`type` mustEqual TType.LIST - f2.manifest mustEqual Some(implicitly[Manifest[Seq[String]]]) - f2.getValue[Seq[String]](s) mustEqual Seq("test") - - f3.name mustEqual "a_set" - f3.id mustEqual 3 - f3.`type` mustEqual TType.SET - f3.manifest mustEqual Some(implicitly[Manifest[Set[Byte]]]) - f3.getValue[Set[Byte]](s) mustEqual Set(10.toByte) - - f4.name mustEqual "non_col" - f4.id mustEqual 4 - f4.`type` mustEqual TType.I32 - f4.manifest mustEqual Some(implicitly[Manifest[Int]]) - f4.getValue[Int](s) mustEqual 123 + f1.name must be("a_map") + f1.id must be(1) + f1.`type` must be(TType.MAP) + f1.manifest must be(Some(implicitly[Manifest[Map[Int, Long]]])) + f1.getValue[Map[Int, Long]](s) must be(Map(1 -> 2L)) + + f2.name must be("a_list") + f2.id must be(2) + f2.`type` must be(TType.LIST) + f2.manifest must be(Some(implicitly[Manifest[Seq[String]]])) + f2.getValue[Seq[String]](s) must be(Seq("test")) + + f3.name must be("a_set") + f3.id must be(3) + f3.`type` must be(TType.SET) + f3.manifest must be(Some(implicitly[Manifest[Set[Byte]]])) + f3.getValue[Set[Byte]](s) must be(Set(10.toByte)) + + f4.name must be("non_col") + f4.id must be(4) + f4.`type` must be(TType.I32) + f4.manifest must be(Some(implicitly[Manifest[Int]])) + f4.getValue[Int](s) must be(123) } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/GeneratorFactorySpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/GeneratorFactorySpec.scala index 003da598e..fd0d2182a 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/GeneratorFactorySpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/GeneratorFactorySpec.scala @@ -1,7 +1,7 @@ package com.twitter.scrooge.backend -import org.specs.SpecificationWithJUnit import com.twitter.scrooge.frontend.ResolvedDocument +import com.twitter.scrooge.testutil.Spec class TestGeneratorFactory extends GeneratorFactory { val lang = "test" @@ -13,11 +13,11 @@ class TestGeneratorFactory extends GeneratorFactory { ): ThriftGenerator = new ScalaGenerator(includeMap, defaultNamespace, generationDate, experimentFlags) } -class GeneratorFactorySpec extends SpecificationWithJUnit { +class GeneratorFactorySpec extends Spec { "GeneratorFactory" should { "be loadable" in { val generator = Generator("test", Map.empty[String, ResolvedDocument], "", "", Seq.empty[String]) - generator must haveClass[ScalaGenerator] + generator.isInstanceOf[ScalaGenerator] must be(true) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ImmutableStructSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ImmutableStructSpec.scala index cc0a13298..32b2b1dab 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ImmutableStructSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ImmutableStructSpec.scala @@ -1,10 +1,10 @@ package com.twitter.scrooge.backend -import org.specs.SpecificationWithJUnit +import com.twitter.scrooge.testutil.Spec import org.apache.thrift.protocol.TBinaryProtocol import org.apache.thrift.transport.TMemoryBuffer -class ImmutableStructSpec extends SpecificationWithJUnit { +class ImmutableStructSpec extends Spec { "Scala objects" should { import thrift.test._ @@ -12,7 +12,7 @@ class ImmutableStructSpec extends SpecificationWithJUnit { val protocol = new TBinaryProtocol(new TMemoryBuffer(10000)) val originalBonk = Bonk("This is Bonk message", 13) Bonk.encode(originalBonk, protocol) - Bonk.decode(protocol) mustEqual(originalBonk) + Bonk.decode(protocol) must be(originalBonk) } "deep copy" in { @@ -49,10 +49,10 @@ class ImmutableStructSpec extends SpecificationWithJUnit { structThing = xtructSwapped ) ) - copied.x1 mustEqual(nested.x1) - copied.x2.structThing must_!=(nested.x2.structThing) //swapped - copied.x2 must_!=(nested.x2) - copied.x3 mustEqual(nested.x3) + copied.x1 must be(nested.x1) + copied.x2.structThing must not be(nested.x2.structThing) //swapped + copied.x2 must not be(nested.x2) + copied.x3 must be(nested.x3) } } @@ -62,7 +62,7 @@ class ImmutableStructSpec extends SpecificationWithJUnit { val protocol = new TBinaryProtocol(new TMemoryBuffer(10000)) val originalBonk = new Bonk("This is Bonk message", 13) Bonk.encode(originalBonk, protocol) - Bonk.decode(protocol) mustEqual(originalBonk) + Bonk.decode(protocol) must be(originalBonk) } "deep copy" in { @@ -96,13 +96,13 @@ class ImmutableStructSpec extends SpecificationWithJUnit { .x2(xtruct2.copy().structThing(xtructSwapped).build()) .build() - copied.getX1 mustEqual(nested.getX1) - copied.getX2.getStructThing must_!=(nested.getX2.getStructThing) //swapped - copied.getX2 must_!=(nested.getX2) - copied.getX3 mustEqual(nested.getX3) + copied.getX1 must be(nested.getX1) + copied.getX2.getStructThing must not be(nested.getX2.getStructThing) //swapped + copied.getX2 must not be(nested.getX2) + copied.getX3 must be(nested.getX3) val copiedPartial = nested.copy().unsetX2().build() - copiedPartial.isSetX2 must beFalse + copiedPartial.isSetX2 must be(false) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/JavaGeneratorSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/JavaGeneratorSpec.scala index 03f7c5453..a12252f45 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/JavaGeneratorSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/JavaGeneratorSpec.scala @@ -1,41 +1,39 @@ package com.twitter.scrooge package backend +import com.twitter.scrooge.testutil.{EvalHelper, JMockSpec} import java.io.{ObjectInputStream, ByteArrayInputStream, ObjectOutputStream, ByteArrayOutputStream} import java.nio.ByteBuffer import org.apache.thrift.protocol._ import org.apache.thrift.transport.TMemoryBuffer -import org.specs.mock.{ClassMocker, JMocker} -import org.specs.SpecificationWithJUnit -import com.twitter.scrooge.testutil.EvalHelper +import org.jmock.Expectations +import org.jmock.Expectations.{any, returnValue} import thrift.java_test._ -class JavaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMocker with ClassMocker { - val protocol = mock[TProtocol] - +class JavaGeneratorSpec extends JMockSpec with EvalHelper { def stringToBytes(string: String) = ByteBuffer.wrap(string.getBytes) "JavaGenerator" should { - "generate an enum" in { - "correct constants" in { - NumberID.ONE.getValue() mustEqual 1 - NumberID.TWO.getValue() mustEqual 2 - NumberID.THREE.getValue() mustEqual 3 - NumberID.FIVE.getValue() mustEqual 5 - NumberID.SIX.getValue() mustEqual 6 - NumberID.EIGHT.getValue() mustEqual 8 + "generate an enum" should { + "correct constants" in { _ => + NumberID.ONE.getValue() must be(1) + NumberID.TWO.getValue() must be(2) + NumberID.THREE.getValue() must be(3) + NumberID.FIVE.getValue() must be(5) + NumberID.SIX.getValue() must be(6) + NumberID.EIGHT.getValue() must be(8) } - "findByValue" in { - NumberID.findByValue(1) mustEqual NumberID.ONE - NumberID.findByValue(2) mustEqual NumberID.TWO - NumberID.findByValue(3) mustEqual NumberID.THREE - NumberID.findByValue(5) mustEqual NumberID.FIVE - NumberID.findByValue(6) mustEqual NumberID.SIX - NumberID.findByValue(8) mustEqual NumberID.EIGHT + "findByValue" in { _ => + NumberID.findByValue(1) must be(NumberID.ONE) + NumberID.findByValue(2) must be(NumberID.TWO) + NumberID.findByValue(3) must be(NumberID.THREE) + NumberID.findByValue(5) must be(NumberID.FIVE) + NumberID.findByValue(6) must be(NumberID.SIX) + NumberID.findByValue(8) must be(NumberID.EIGHT) } - "java-serializable" in { + "java-serializable" in { _ => val bos = new ByteArrayOutputStream() val out = new ObjectOutputStream(bos) out.writeObject(NumberID.ONE) @@ -45,122 +43,141 @@ class JavaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMoc val in = new ObjectInputStream(new ByteArrayInputStream(bytes)) var obj = in.readObject() - obj.isInstanceOf[NumberID] must beTrue - obj.asInstanceOf[NumberID].getValue mustEqual NumberID.ONE.getValue - obj.asInstanceOf[NumberID].name mustEqual NumberID.ONE.name + obj.isInstanceOf[NumberID] must be(true) + obj.asInstanceOf[NumberID].getValue must be(NumberID.ONE.getValue) + obj.asInstanceOf[NumberID].name must be(NumberID.ONE.name) obj = in.readObject() - obj.isInstanceOf[NumberID] must beTrue - obj.asInstanceOf[NumberID].getValue mustEqual NumberID.TWO.getValue - obj.asInstanceOf[NumberID].name mustEqual NumberID.TWO.name + obj.isInstanceOf[NumberID] must be(true) + obj.asInstanceOf[NumberID].getValue must be(NumberID.TWO.getValue) + obj.asInstanceOf[NumberID].name must be(NumberID.TWO.name) } } - "generate constants" in { - Constants.myWfhDay mustEqual WeekDay.THU - Constants.myDaysOut mustEqual Utilities.makeList(WeekDay.THU, WeekDay.SAT, WeekDay.SUN) - Constants.name mustEqual "Columbo" - Constants.someInt mustEqual 1 - Constants.someDouble mustEqual 3.0 - Constants.someList mustEqual Utilities.makeList("piggy") - Constants.emptyList mustEqual Utilities.makeList() - Constants.someMap mustEqual Utilities.makeMap(Utilities.makeTuple("foo", "bar")) - Constants.someSimpleSet mustEqual Utilities.makeSet("foo", "bar") - Constants.someSet mustEqual Utilities.makeSet( + "generate constants" in { _ => + Constants.myWfhDay must be(WeekDay.THU) + Constants.myDaysOut must be(Utilities.makeList(WeekDay.THU, WeekDay.SAT, WeekDay.SUN)) + Constants.name must be("Columbo") + Constants.someInt must be(1) + Constants.someDouble must be(3.0) + Constants.someList must be(Utilities.makeList("piggy")) + Constants.emptyList must be(Utilities.makeList()) + Constants.someMap must be(Utilities.makeMap(Utilities.makeTuple("foo", "bar"))) + Constants.someSimpleSet must be(Utilities.makeSet("foo", "bar")) + Constants.someSet must be(Utilities.makeSet( Utilities.makeList("piggy"), Utilities.makeList("kitty") - ) + )) } - "basic structs" in { - "ints" in { - "read" in { - expect { - startRead(protocol, new TField("baby", TType.I16, 1)) - one(protocol).readI16() willReturn (16: Short) - nextRead(protocol, new TField("mama", TType.I32, 2)) - one(protocol).readI32() willReturn 32 - nextRead(protocol, new TField("papa", TType.I64, 3)) - one(protocol).readI64() willReturn 64L - endRead(protocol) + "basic structs" should { + "ints" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readI32(); will(returnValue(32)) + nextRead(e, protocol, new TField("papa", TType.I64, 3)) + one(protocol).readI64(); will(returnValue(64L)) + endRead(e, protocol) } - Ints.decode(protocol) mustEqual new Ints(16, 32, 64L) + whenExecuting { + Ints.decode(protocol) must be(new Ints(16, 32, 64L)) + } } - "write" in { - expect { - startWrite(protocol, new TField("baby", TType.I16, 1)) - one(protocol).writeI16(16) - nextWrite(protocol, new TField("mama", TType.I32, 2)) - one(protocol).writeI32(32) - nextWrite(protocol, new TField("papa", TType.I64, 3)) - one(protocol).writeI64(64) - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeI32(`with`(Expectations.equal(32))) + nextWrite(e, protocol, new TField("papa", TType.I64, 3)) + one(protocol).writeI64(`with`(Expectations.equal(64L))) + endWrite(e, protocol) } - new Ints(16, 32, 64L).write(protocol) mustEqual () + whenExecuting { + new Ints(16, 32, 64L).write(protocol) must be(()) + } } } - "bytes" in { - "read" in { - expect { - startRead(protocol, new TField("x", TType.BYTE, 1)) - one(protocol).readByte() willReturn 3.toByte - nextRead(protocol, new TField("y", TType.STRING, 2)) - one(protocol).readBinary() willReturn stringToBytes("hello") - endRead(protocol) + "bytes" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readBinary(); will(returnValue(stringToBytes("hello"))) + endRead(e, protocol) } - val bytes = Bytes.decode(protocol) - bytes.getX mustEqual 3.toByte - new String(bytes.getY.array) mustEqual "hello" + whenExecuting { + val bytes = Bytes.decode(protocol) + bytes.getX must be(3.toByte) + new String(bytes.getY.array) must be("hello") + } } - "write" in { - expect { - startWrite(protocol, new TField("x", TType.BYTE, 1)) - one(protocol).writeByte(16.toByte) - nextWrite(protocol, new TField("y", TType.STRING, 2)) - one(protocol).writeBinary(stringToBytes("goodbye")) - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + + 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)) + one(protocol).writeBinary(`with`(Expectations.equal(stringToBytes("goodbye")))) + endWrite(e, protocol) } - new Bytes(16.toByte, stringToBytes("goodbye")).write(protocol) mustEqual () + whenExecuting { + new Bytes(16.toByte, stringToBytes("goodbye")).write(protocol) must be(()) + } } } - "bool, double, string" in { - "read" in { - expect { - startRead(protocol, new TField("alive", TType.BOOL, 1)) - one(protocol).readBool() willReturn true - nextRead(protocol, new TField("pi", TType.DOUBLE, 2)) - one(protocol).readDouble() willReturn 3.14 - nextRead(protocol, new TField("name", TType.STRING, 3)) - one(protocol).readString() willReturn "bender" - endRead(protocol) + "bool, double, string" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readDouble(); will(returnValue(3.14)) + nextRead(e, protocol, new TField("name", TType.STRING, 3)) + one(protocol).readString(); will(returnValue("bender")) + endRead(e, protocol) } - Misc.decode(protocol) mustEqual new Misc(true, 3.14, "bender") + whenExecuting { + Misc.decode(protocol) must be(new Misc(true, 3.14, "bender")) + } } - "write" in { - expect { - startWrite(protocol, new TField("alive", TType.BOOL, 1)) - one(protocol).writeBool(false) - nextWrite(protocol, new TField("pi", TType.DOUBLE, 2)) - one(protocol).writeDouble(6.28) - nextWrite(protocol, new TField("name", TType.STRING, 3)) - one(protocol).writeString("fry") - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeDouble(`with`(Expectations.equal(6.28))) + nextWrite(e, protocol, new TField("name", TType.STRING, 3)) + one(protocol).writeString(`with`(Expectations.equal("fry"))) + endWrite(e, protocol) } - new Misc(false, 6.28, "fry").write(protocol) mustEqual () + whenExecuting { + new Misc(false, 6.28, "fry").write(protocol) must be(()) + } } } - "lists, sets, and maps" in { + "lists, sets, and maps" should { val exemplar = new Compound.Builder() .intlist(Utilities.makeList(10, 20)) .intset(Utilities.makeSet(44, 55)) @@ -168,396 +185,479 @@ class JavaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMoc .nested(Utilities.makeList(Utilities.makeSet(9))) .build() - "read" in { - expect { - startRead(protocol, new TField("intlist", TType.LIST, 1)) - one(protocol).readListBegin() willReturn new TList(TType.I32, 2) - one(protocol).readI32() willReturn 10 - one(protocol).readI32() willReturn 20 + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readI32(); will(returnValue(20)) one(protocol).readListEnd() - nextRead(protocol, new TField("intset", TType.SET, 2)) - one(protocol).readSetBegin() willReturn new TSet(TType.I32, 2) - one(protocol).readI32() willReturn 44 - one(protocol).readI32() willReturn 55 + nextRead(e, protocol, new TField("intset", TType.SET, 2)) + one(protocol).readSetBegin(); will(returnValue(new TSet(TType.I32, 2))) + one(protocol).readI32(); will(returnValue(44)) + one(protocol).readI32(); will(returnValue(55)) one(protocol).readSetEnd() - nextRead(protocol, new TField("namemap", TType.MAP, 3)) - one(protocol).readMapBegin() willReturn new TMap(TType.STRING, TType.I32, 1) - one(protocol).readString() willReturn "wendy" - one(protocol).readI32() willReturn 500 + nextRead(e, protocol, new TField("namemap", TType.MAP, 3)) + one(protocol).readMapBegin(); will(returnValue(new TMap(TType.STRING, TType.I32, 1))) + one(protocol).readString(); will(returnValue("wendy")) + one(protocol).readI32(); will(returnValue(500)) one(protocol).readMapEnd() - nextRead(protocol, new TField("nested", TType.LIST, 4)) - one(protocol).readListBegin() willReturn new TList(TType.SET, 1) - one(protocol).readSetBegin() willReturn new TSet(TType.I32, 1) - one(protocol).readI32() willReturn 9 + nextRead(e, protocol, new TField("nested", TType.LIST, 4)) + one(protocol).readListBegin(); will(returnValue(new TList(TType.SET, 1))) + one(protocol).readSetBegin(); will(returnValue(new TSet(TType.I32, 1))) + one(protocol).readI32(); will(returnValue(9)) one(protocol).readSetEnd() one(protocol).readListEnd() - endRead(protocol) + endRead(e, protocol) } - Compound.decode(protocol) mustEqual exemplar + whenExecuting { + Compound.decode(protocol) must be(exemplar) + } } - "write" in { - expect { - startWrite(protocol, new TField("intlist", TType.LIST, 1)) - one(protocol).writeListBegin(equal(new TList(TType.I32, 2))) - one(protocol).writeI32(10) - one(protocol).writeI32(20) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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))) + one(protocol).writeI32(`with`(Expectations.equal(20))) one(protocol).writeListEnd() - nextWrite(protocol, new TField("intset", TType.SET, 2)) - one(protocol).writeSetBegin(equal(new TSet(TType.I32, 2))) - one(protocol).writeI32(44) - one(protocol).writeI32(55) + nextWrite(e, protocol, new TField("intset", TType.SET, 2)) + one(protocol).writeSetBegin(`with`(setEqual(new TSet(TType.I32, 2)))) + one(protocol).writeI32(`with`(Expectations.equal(44))) + one(protocol).writeI32(`with`(Expectations.equal(55))) one(protocol).writeSetEnd() - nextWrite(protocol, new TField("namemap", TType.MAP, 3)) - one(protocol).writeMapBegin(equal(new TMap(TType.STRING, TType.I32, 1))) - one(protocol).writeString("wendy") - one(protocol).writeI32(500) + nextWrite(e, protocol, new TField("namemap", TType.MAP, 3)) + one(protocol).writeMapBegin(`with`(mapEqual(new TMap(TType.STRING, TType.I32, 1)))) + one(protocol).writeString(`with`(Expectations.equal("wendy"))) + one(protocol).writeI32(`with`(Expectations.equal(500))) one(protocol).writeMapEnd() - nextWrite(protocol, new TField("nested", TType.LIST, 4)) - one(protocol).writeListBegin(equal(new TList(TType.SET, 1))) - one(protocol).writeSetBegin(equal(new TSet(TType.I32, 1))) + nextWrite(e, protocol, new TField("nested", TType.LIST, 4)) + one(protocol).writeListBegin(`with`(listEqual(new TList(TType.SET, 1)))) + one(protocol).writeSetBegin(`with`(setEqual(new TSet(TType.I32, 1)))) one(protocol).writeI32(9) one(protocol).writeSetEnd() one(protocol).writeListEnd() - endWrite(protocol) + endWrite(e, protocol) } - exemplar.write(protocol) mustEqual () + whenExecuting { + exemplar.write(protocol) must be(()) + } } } } - "complicated structs" in { - "with required fields" in { - "read" in { - expect { - startRead(protocol, new TField("string", TType.STRING, 1)) - one(protocol).readString() willReturn "yo" - endRead(protocol) + "complicated structs" should { + "with required fields" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startRead(e, protocol, new TField("string", TType.STRING, 1)) + one(protocol).readString(); will(returnValue("yo")) + endRead(e, protocol) } - RequiredString.decode(protocol) mustEqual new RequiredString("yo") + whenExecuting { + RequiredString.decode(protocol) must be(new RequiredString("yo")) + } } - "missing required value throws exception during deserialization" in { - doBefore { - expect { - emptyRead(protocol) + "missing required value throws exception during deserialization" should { + "with no default value" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + emptyRead(e, protocol) } - } - "with no default value" in { - RequiredString.decode(protocol) must throwA[TProtocolException] + whenExecuting { + intercept[TProtocolException] { + RequiredString.decode(protocol) + } + } } - "with default value" in { - RequiredStringWithDefault.decode(protocol) must throwA[TProtocolException] + "with default value" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + emptyRead(e, protocol) + } + + whenExecuting { + intercept[TProtocolException] { + RequiredStringWithDefault.decode(protocol) + } + } } } - "null required value throws exception during serialization" in { - "with no default value" in { - new RequiredString(null).write(protocol) must throwA[TProtocolException] + "null required value throws exception during serialization" should { + "with no default value" in { e => import e._ + val protocol = mock[TProtocol] + + intercept[TProtocolException] { + new RequiredString(null).write(protocol) + } } - "with default value" in { - new RequiredStringWithDefault(null).write(protocol) must throwA[TProtocolException] + "with default value" in { e => import e._ + val protocol = mock[TProtocol] + + intercept[TProtocolException] { + new RequiredStringWithDefault(null).write(protocol) + } } } } - "with optional fields" in { - "read" in { - expect { - startRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "Commie" - nextRead(protocol, new TField("age", TType.I32, 2)) - one(protocol).readI32() willReturn 14 - endRead(protocol) + "with optional fields" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readI32(); will(returnValue(14)) + endRead(e, protocol) } - OptionalInt.decode(protocol) mustEqual new OptionalInt("Commie", new Option.Some(14)) + whenExecuting { + OptionalInt.decode(protocol) must be(new OptionalInt("Commie", new Option.Some(14))) + } } - "read with missing field" in { - expect { - startRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "Commie" - endRead(protocol) + "read with missing field" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startRead(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).readString(); will(returnValue( "Commie")) + endRead(e, protocol) } - OptionalInt.decode(protocol) mustEqual new OptionalInt("Commie", Option.none()) + whenExecuting { + OptionalInt.decode(protocol) must be(new OptionalInt("Commie", Option.none())) + } } - "write" in { - expect { - startWrite(protocol, new TField("name", TType.STRING, 1)) - one(protocol).writeString("Commie") - nextWrite(protocol, new TField("age", TType.I32, 2)) - one(protocol).writeI32(14) - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeI32(`with`(Expectations.equal(14))) + endWrite(e, protocol) } - new OptionalInt("Commie", new Option.Some(14)).write(protocol) mustEqual () + whenExecuting { + new OptionalInt("Commie", new Option.Some(14)).write(protocol) must be(()) + } } - "write with missing field" in { - expect { - startWrite(protocol, new TField("name", TType.STRING, 1)) - one(protocol).writeString("Commie") - endWrite(protocol) + "write with missing field" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startWrite(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).writeString(`with`(Expectations.equal("Commie"))) + endWrite(e, protocol) } - new OptionalInt("Commie", Option.none()).write(protocol) mustEqual () + whenExecuting { + new OptionalInt("Commie", Option.none()).write(protocol) must be(()) + } } } - "with default values" in { - "read with value missing, using default" in { - expect { + "with default values" should { + "read with value missing, using default" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ one(protocol).readStructBegin() - one(protocol).readFieldBegin() willReturn new TField("stop", TType.STOP, 10) + one(protocol).readFieldBegin(); will(returnValue(new TField("stop", TType.STOP, 10))) one(protocol).readStructEnd() } - DefaultValues.decode(protocol) mustEqual new DefaultValues("leela") + whenExecuting { + DefaultValues.decode(protocol) must be(new DefaultValues("leela")) + } } - "read with value present" in { - expect { + "read with value present" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ one(protocol).readStructBegin() - nextRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "delilah" - one(protocol).readFieldBegin() willReturn new TField("stop", TType.STOP, 10) + nextRead(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).readString(); will(returnValue( "delilah")) + one(protocol).readFieldBegin(); will(returnValue(new TField("stop", TType.STOP, 10))) one(protocol).readStructEnd() } - DefaultValues.decode(protocol) mustEqual new DefaultValues("delilah") + whenExecuting { + DefaultValues.decode(protocol) must be(new DefaultValues("delilah")) + } } } - "nested" in { - "read" in { - expect { - startRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "United States of America" - nextRead(protocol, new TField("provinces", TType.LIST, 2)) - one(protocol).readListBegin() willReturn new TList(TType.STRING, 2) - one(protocol).readString() willReturn "connecticut" - one(protocol).readString() willReturn "california" + "nested" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readListBegin(); will(returnValue(new TList(TType.STRING, 2))) + one(protocol).readString(); will(returnValue("connecticut")) + one(protocol).readString(); will(returnValue("california")) one(protocol).readListEnd() - nextRead(protocol, new TField("emperor", TType.STRUCT, 5)) + nextRead(e, protocol, new TField("emperor", TType.STRUCT, 5)) /** Start of Emperor struct **/ - startRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "Bush" - nextRead(protocol, new TField("age", TType.I32, 2)) - one(protocol).readI32() willReturn 42 - endRead(protocol) + startRead(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).readString(); will(returnValue( "Bush")) + nextRead(e, protocol, new TField("age", TType.I32, 2)) + one(protocol).readI32(); will(returnValue(42)) + endRead(e, protocol) /** End of Emperor struct **/ - endRead(protocol) + endRead(e, protocol) } - Empire.decode(protocol) mustEqual new Empire( - "United States of America", - Utilities.makeList("connecticut", "california"), - new Emperor("Bush", 42)) + whenExecuting { + Empire.decode(protocol) must be(new Empire( + "United States of America", + Utilities.makeList("connecticut", "california"), + new Emperor("Bush", 42))) + } } - "write" in { - expect { - startWrite(protocol, new TField("name", TType.STRING, 1)) - one(protocol).writeString("Canada") - nextWrite(protocol, new TField("provinces", TType.LIST, 2)) - one(protocol).writeListBegin(equal(new TList(TType.STRING, 2))) - one(protocol).writeString("Manitoba") - one(protocol).writeString("Alberta") + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeListBegin(`with`(listEqual(new TList(TType.STRING, 2)))) + one(protocol).writeString(`with`(Expectations.equal("Manitoba"))) + one(protocol).writeString(`with`(Expectations.equal("Alberta"))) one(protocol).writeListEnd() - nextWrite(protocol, new TField("emperor", TType.STRUCT, 5)) + nextWrite(e, protocol, new TField("emperor", TType.STRUCT, 5)) // emperor - startWrite(protocol, new TField("name", TType.STRING, 1)) - one(protocol).writeString("Larry") - nextWrite(protocol, new TField("age", TType.I32, 2)) + startWrite(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).writeString(`with`(Expectations.equal("Larry"))) + nextWrite(e, protocol, new TField("age", TType.I32, 2)) one(protocol).writeI32(13) - endWrite(protocol) + endWrite(e, protocol) - endWrite(protocol) + endWrite(e, protocol) } - new Empire( - "Canada", - Utilities.makeList("Manitoba", "Alberta"), - new Emperor("Larry", 13) - ).write(protocol) mustEqual () + whenExecuting { + new Empire( + "Canada", + Utilities.makeList("Manitoba", "Alberta"), + new Emperor("Larry", 13) + ).write(protocol) must be(()) + } } } - "exception" in { - new Xception(1, "boom") must haveSuperClass[Exception] - new Xception(2, "kathunk").getMessage mustEqual "kathunk" + "exception" in { _ => + (new Xception(1, "boom")).isInstanceOf[Exception] must be(true) + new Xception(2, "kathunk").getMessage must be("kathunk") } - "exception getMessage" in { - new StringMsgException(1, "jeah").getMessage mustEqual "jeah" - new NonStringMessageException(5).getMessage mustEqual "5" + "exception getMessage" in { _ => + new StringMsgException(1, "jeah").getMessage must be("jeah") + new NonStringMessageException(5).getMessage must be("5") } - "with more than 22 fields" in { - "apply" in { - new Biggie.Builder().build().getNum25() mustEqual 25 + "with more than 22 fields" should { + "apply" in { _ => + new Biggie.Builder().build().getNum25() must be(25) } - "two default object must be equal" in { - new Biggie.Builder().build() mustEqual new Biggie.Builder().build() + "two default object must be equal" in { _ => + new Biggie.Builder().build() must be(new Biggie.Builder().build()) } - "copy and equals" in { - new Biggie.Builder().build().copy().num10(-5).build() mustEqual new Biggie.Builder().num10(-5).build() + "copy and equals" in { _ => + new Biggie.Builder().build().copy().num10(-5).build() must be(new Biggie.Builder().num10(-5).build()) } - "hashCode is the same for two similar objects" in { - new Biggie.Builder().build().hashCode mustEqual new Biggie.Builder().build().hashCode - new Biggie.Builder().num10(-5).build().hashCode mustEqual new Biggie.Builder().num10(-5).build().hashCode + "hashCode is the same for two similar objects" in { _ => + new Biggie.Builder().build().hashCode must be(new Biggie.Builder().build().hashCode) + new Biggie.Builder().num10(-5).build().hashCode must be(new Biggie.Builder().num10(-5).build().hashCode) } - "hashCode is different for two different objects" in { - new Biggie.Builder().num10(-5).build().hashCode mustNot beEqual(new Biggie.Builder().build().hashCode) + "hashCode is different for two different objects" in { _ => + new Biggie.Builder().num10(-5).build().hashCode must not be(new Biggie.Builder().build().hashCode) } - "toString" in { - new Biggie.Builder().build().toString mustEqual ("Biggie(" + 1.to(25).map(_.toString).mkString(",") + ")") + "toString" in { _ => + new Biggie.Builder().build().toString must be(("Biggie(" + 1.to(25).map(_.toString).mkString(",") + ")")) } } } - "unions" in { - "zero fields" in { - "read" in { - expect { - emptyRead(protocol) + "unions" should { + "zero fields" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + emptyRead(e, protocol) } - Bird.decode(protocol) must throwA[TProtocolException] + whenExecuting { + intercept[TProtocolException] { + Bird.decode(protocol) + } + } } - "instantiate" in { - Bird.newRaptor(null) must throwA[NullPointerException] + "instantiate" in { _ => + intercept[NullPointerException] { + Bird.newRaptor(null) + } } } - "one field" in { - "read" in { - expect { - startRead(protocol, new TField("hummingbird", TType.STRING, 2)) - one(protocol).readString() willReturn "Ruby-Throated" - endRead(protocol) + "one field" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startRead(e, protocol, new TField("hummingbird", TType.STRING, 2)) + one(protocol).readString(); will(returnValue("Ruby-Throated")) + endRead(e, protocol) } - Bird.decode(protocol) mustEqual Bird.newHummingbird("Ruby-Throated") + whenExecuting { + Bird.decode(protocol) must be(Bird.newHummingbird("Ruby-Throated")) + } } - "write" in { - expect { - startWrite(protocol, new TField("owlet_nightjar", TType.STRING, 3)) - one(protocol).writeString("foo") - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startWrite(e, protocol, new TField("owlet_nightjar", TType.STRING, 3)) + one(protocol).writeString(`with`(Expectations.equal("foo"))) + endWrite(e, protocol) } - Bird.newOwletNightjar("foo").write(protocol) + whenExecuting { + Bird.newOwletNightjar("foo").write(protocol) + } } } - "more than one field" in { - "read" in { - expect { - startRead(protocol, new TField("hummingbird", TType.STRING, 2)) - one(protocol).readString() willReturn "Anna's Hummingbird" - nextRead(protocol, new TField("owlet_nightjar", TType.STRING, 3)) - one(protocol).readBinary() willReturn ByteBuffer.allocate(1) - endRead(protocol) + "more than one field" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readBinary(); will(returnValue(ByteBuffer.allocate(1))) + endRead(e, protocol) } - Bird.decode(protocol) must throwA[TProtocolException] + whenExecuting { + intercept[TProtocolException] { + Bird.decode(protocol) + } + } } // no write test because it's not possible } - "nested struct" in { - "read" in { - expect { - startRead(protocol, new TField("raptor", TType.STRUCT, 1)) - startRead(protocol, new TField("isOwl", TType.BOOL, 1)) - one(protocol).readBool() willReturn false - nextRead(protocol, new TField("species", TType.STRING, 2)) - one(protocol).readString() willReturn "peregrine" - endRead(protocol) - endRead(protocol) + "nested struct" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + nextRead(e, protocol, new TField("species", TType.STRING, 2)) + one(protocol).readString(); will(returnValue("peregrine")) + endRead(e, protocol) + endRead(e, protocol) } - Bird.decode(protocol) mustEqual Bird.newRaptor(new Raptor(false, "peregrine")) + whenExecuting { + Bird.decode(protocol) must be(Bird.newRaptor(new Raptor(false, "peregrine"))) + } } - "write" in { - expect { - startWrite(protocol, new TField("raptor", TType.STRUCT, 1)) - startWrite(protocol, new TField("isOwl", TType.BOOL, 1)) - one(protocol).writeBool(true) - nextWrite(protocol, new TField("species", TType.STRING, 2)) - one(protocol).writeString("Tyto alba") - endWrite(protocol) - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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))) + nextWrite(e, protocol, new TField("species", TType.STRING, 2)) + one(protocol).writeString(`with`(Expectations.equal("Tyto alba"))) + endWrite(e, protocol) + endWrite(e, protocol) } - Bird.newRaptor(new Raptor(true, "Tyto alba")).write(protocol) + whenExecuting { + Bird.newRaptor(new Raptor(true, "Tyto alba")).write(protocol) + } } } - "collection" in { - "read" in { - expect { - startRead(protocol, new TField("flock", TType.LIST, 4)) - one(protocol).readListBegin() willReturn new TList(TType.STRING, 3) - one(protocol).readString() willReturn "starling" - one(protocol).readString() willReturn "kestrel" - one(protocol).readString() willReturn "warbler" + "collection" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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")) + one(protocol).readString(); will(returnValue("kestrel")) + one(protocol).readString(); will(returnValue("warbler")) one(protocol).readListEnd() - endRead(protocol) + endRead(e, protocol) } - Bird.decode(protocol) mustEqual Bird.newFlock(Utilities.makeList("starling", "kestrel", "warbler")) + whenExecuting { + Bird.decode(protocol) must be(Bird.newFlock(Utilities.makeList("starling", "kestrel", "warbler"))) + } } - "write" in { - expect { - startWrite(protocol, new TField("flock", TType.LIST, 4)) - one(protocol).writeListBegin(equal(new TList(TType.STRING, 3))) - one(protocol).writeString("starling") - one(protocol).writeString("kestrel") - one(protocol).writeString("warbler") + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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"))) + one(protocol).writeString(`with`(Expectations.equal("kestrel"))) + one(protocol).writeString(`with`(Expectations.equal("warbler"))) one(protocol).writeListEnd() - endWrite(protocol) + endWrite(e, protocol) } - Bird.newFlock(Utilities.makeList("starling", "kestrel", "warbler")).write(protocol) + whenExecuting { + Bird.newFlock(Utilities.makeList("starling", "kestrel", "warbler")).write(protocol) + } } } - "primitive field type" in { + "primitive field type" in { _ => import thrift.java_def._default_._ val protocol = new TBinaryProtocol(new TMemoryBuffer(10000)) var original: NaughtyUnion = NaughtyUnion.newValue(1) NaughtyUnion.encode(original, protocol) - NaughtyUnion.decode(protocol) mustEqual(original) + NaughtyUnion.decode(protocol) must be(original) original = NaughtyUnion.newFlag(true) NaughtyUnion.encode(original, protocol) - NaughtyUnion.decode(protocol) mustEqual(original) + NaughtyUnion.decode(protocol) must be(original) original = NaughtyUnion.newText("false") NaughtyUnion.encode(original, protocol) - NaughtyUnion.decode(protocol) mustEqual(original) + NaughtyUnion.decode(protocol) must be(original) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NamespaceSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NamespaceSpec.scala index cba506fb5..31b10758b 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NamespaceSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NamespaceSpec.scala @@ -1,8 +1,8 @@ package com.twitter.scrooge.backend -import org.specs.SpecificationWithJUnit +import com.twitter.scrooge.testutil.Spec -class NamespaceSpec extends SpecificationWithJUnit { +class NamespaceSpec extends Spec { "Scala Generator" should { import foo._ import bar._ @@ -13,8 +13,8 @@ class NamespaceSpec extends SpecificationWithJUnit { def makeReservation(whichDay: Weekday, howMany: Int) = Some(if (whichDay == Weekday.Monday) 0 else howMany) } - service.makeReservation(Weekday.Monday, 2) mustEqual Some(0) - service.makeReservation(Weekday.Tuesday, 2) mustEqual Some(2) + service.makeReservation(Weekday.Monday, 2) must be(Some(0)) + service.makeReservation(Weekday.Tuesday, 2) must be(Some(2)) } } @@ -28,8 +28,8 @@ class NamespaceSpec extends SpecificationWithJUnit { def makeReservation(whichDay: Weekday, howMany: Int) = if (whichDay == Weekday.MONDAY) 0 else howMany } - service.makeReservation(Weekday.MONDAY, 2) mustEqual 0 - service.makeReservation(Weekday.TUESDAY, 2) mustEqual 2 + service.makeReservation(Weekday.MONDAY, 2) must be(0) + service.makeReservation(Weekday.TUESDAY, 2) must be(2) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NamingConvention.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NamingConvention.scala index 08cfd4ea1..27c770319 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NamingConvention.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NamingConvention.scala @@ -1,37 +1,37 @@ package com.twitter.scrooge.backend -import org.specs.SpecificationWithJUnit +import com.twitter.scrooge.testutil.Spec -class NamingConventionSpec extends SpecificationWithJUnit { +class NamingConventionSpec extends Spec { "Scala Generator" should { "follow naming conventions" in { import thrift.`def`.default._ - Constants.`val` mustEqual 10 - Constants.`try` mustEqual 123 + Constants.`val` must be(10) + Constants.`try` must be(123) val naughty = Naughty("car", 100) - naughty.`type` mustEqual "car" - naughty.`abstract` mustEqual 100 + naughty.`type` must be("car") + naughty.`abstract` must be(100) - Super.Trait.getValue mustEqual 20 - Super.get(99) must beSome(Super.Native) - Super.valueOf("trait") must beSome(Super.Trait) + Super.Trait.getValue must be(20) + Super.get(99) must be(Some(Super.Native)) + Super.valueOf("trait") must be(Some(Super.Trait)) } } "Java Generator" should { "follow naming convention" in { import thrift.java_def._default_._ // package name "default" got rewritten in Java - Constants.`val` mustEqual 10 - Constants._try_ mustEqual 123 + Constants.`val` must be(10) + Constants._try_ must be(123) val naughty = new Naughty("car", 100) - naughty.getType() mustEqual "car" - naughty.getAbstract() mustEqual 100 + naughty.getType() must be("car") + naughty.getAbstract() must be(100) - Super.TRAIT.getValue() mustEqual 20 - Super.findByValue(99) mustEqual Super.NATIVE + Super.TRAIT.getValue() must be(20) + Super.findByValue(99) must be(Super.NATIVE) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala index 9536e1c9b..8d48f4e46 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala @@ -1,9 +1,9 @@ package com.twitter.scrooge.backend import com.twitter.util.{Return, Throw, Try} -import org.specs.SpecificationWithJUnit +import com.twitter.scrooge.testutil.Spec -class NonFinagleSpec extends SpecificationWithJUnit { +class NonFinagleSpec extends Spec { "None Finagle Service " should { "work in Scala" in { import vanilla.test._ @@ -35,11 +35,13 @@ class NonFinagleSpec extends SpecificationWithJUnit { loc.longitude > nw.longitude && loc.longitude < se.longitude } - service.hasWifi(chicago)() mustEqual true - service.hasWifi(nyc)() mustEqual false + service.hasWifi(chicago).get() must be(true) + service.hasWifi(nyc).get() must be(false) val sfo = Airport("SFO", "San Francisco", Location(10, 10)) - service.hasWifi(sfo)() must throwA[AirportException] - service.fetchAirportsInBounds(Location(500,0), Location(0, 500))() mustEqual Seq(chicago) + intercept[AirportException] { + service.hasWifi(sfo).get() + } + service.fetchAirportsInBounds(Location(500,0), Location(0, 500))() must be(Seq(chicago)) } "work in Java" in { @@ -70,11 +72,13 @@ class NonFinagleSpec extends SpecificationWithJUnit { loc.getLongitude() > nw.getLongitude() && loc.getLongitude() < se.getLongitude() } - service.hasWifi(chicago) mustEqual true - service.hasWifi(nyc) mustEqual false + service.hasWifi(chicago).asInstanceOf[Boolean] must be(true) + service.hasWifi(nyc).asInstanceOf[Boolean] must be(false) val sfo = new Airport("SFO", "San Francisco", new Location(10, 10)) - service.hasWifi(sfo) must throwA[AirportException] - service.fetchAirportsInBounds(new Location(500,0), new Location(0, 500)).toSeq mustEqual Seq(chicago) + intercept[AirportException] { + service.hasWifi(sfo) + } + service.fetchAirportsInBounds(new Location(500,0), new Location(0, 500)).toSeq must be(Seq(chicago)) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala index e38c448c1..2ce5c590a 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala @@ -1,84 +1,82 @@ package com.twitter.scrooge.backend +import com.twitter.finagle.SourcedException +import com.twitter.scrooge.testutil.{EvalHelper, JMockSpec} +import com.twitter.scrooge.{ThriftStruct, ThriftException} import java.io.{ObjectInputStream, ByteArrayInputStream, ObjectOutputStream, ByteArrayOutputStream} import java.nio.ByteBuffer import org.apache.thrift.protocol._ import org.apache.thrift.transport.TMemoryBuffer -import org.specs.mock.{ClassMocker, JMocker} -import org.specs.SpecificationWithJUnit -import com.twitter.finagle.SourcedException -import com.twitter.scrooge.testutil.EvalHelper -import com.twitter.scrooge.{ThriftStruct, ThriftException} +import org.jmock.Expectations +import org.jmock.Expectations.{any, returnValue} import thrift.test._ import thrift.test1._ import thrift.test2._ import thrift.`def`.default._ -class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMocker with ClassMocker { - val protocol = mock[TProtocol] - +class ScalaGeneratorSpec extends JMockSpec with EvalHelper { def stringToBytes(string: String) = ByteBuffer.wrap(string.getBytes) "ScalaGenerator" should { - "generate an enum" in { - "correct constants" in { - NumberID.One.getValue mustEqual 1 - NumberID.Two.getValue mustEqual 2 - NumberID.Three.getValue mustEqual 3 - NumberID.Five.getValue mustEqual 5 - NumberID.Six.getValue mustEqual 6 - NumberID.Eight.getValue mustEqual 8 - } - - "correct names" in { - NumberID.One.name mustEqual "One" - NumberID.Two.name mustEqual "Two" - NumberID.Three.name mustEqual "Three" - NumberID.Five.name mustEqual "Five" - NumberID.Six.name mustEqual "Six" - NumberID.Eight.name mustEqual "Eight" - } - - "apply" in { - NumberID(1) mustEqual NumberID.One - NumberID(2) mustEqual NumberID.Two - NumberID(3) mustEqual NumberID.Three - NumberID(5) mustEqual NumberID.Five - NumberID(6) mustEqual NumberID.Six - NumberID(8) mustEqual NumberID.Eight - } - - "get" in { - NumberID.get(1) must beSome(NumberID.One) - NumberID.get(2) must beSome(NumberID.Two) - NumberID.get(3) must beSome(NumberID.Three) - NumberID.get(5) must beSome(NumberID.Five) - NumberID.get(6) must beSome(NumberID.Six) - NumberID.get(8) must beSome(NumberID.Eight) - NumberID.get(10) must beNone - } - - "valueOf" in { - NumberID.valueOf("One") must beSome(NumberID.One) - NumberID.valueOf("Two") must beSome(NumberID.Two) - NumberID.valueOf("Three") must beSome(NumberID.Three) - NumberID.valueOf("Five") must beSome(NumberID.Five) - NumberID.valueOf("Six") must beSome(NumberID.Six) - NumberID.valueOf("Eight") must beSome(NumberID.Eight) - NumberID.valueOf("Ten") must beNone - } - - "correct list" in { - NumberID.list(0) mustEqual NumberID.One - NumberID.list(1) mustEqual NumberID.Two - NumberID.list(2) mustEqual NumberID.Three - NumberID.list(3) mustEqual NumberID.Five - NumberID.list(4) mustEqual NumberID.Six - NumberID.list(5) mustEqual NumberID.Eight - NumberID.list.size mustEqual 6 - } - - "java-serializable" in { + "generate an enum" should { + "correct constants" in { _ => + NumberID.One.getValue must be(1) + NumberID.Two.getValue must be(2) + NumberID.Three.getValue must be(3) + NumberID.Five.getValue must be(5) + NumberID.Six.getValue must be(6) + NumberID.Eight.getValue must be(8) + } + + "correct names" in { _ => + NumberID.One.name must be("One") + NumberID.Two.name must be("Two") + NumberID.Three.name must be("Three") + NumberID.Five.name must be("Five") + NumberID.Six.name must be("Six") + NumberID.Eight.name must be("Eight") + } + + "apply" in { _ => + NumberID(1) must be(NumberID.One) + NumberID(2) must be(NumberID.Two) + NumberID(3) must be(NumberID.Three) + NumberID(5) must be(NumberID.Five) + NumberID(6) must be(NumberID.Six) + NumberID(8) must be(NumberID.Eight) + } + + "get" in { _ => + NumberID.get(1) must be(Some(NumberID.One)) + NumberID.get(2) must be(Some(NumberID.Two)) + NumberID.get(3) must be(Some(NumberID.Three)) + NumberID.get(5) must be(Some(NumberID.Five)) + NumberID.get(6) must be(Some(NumberID.Six)) + NumberID.get(8) must be(Some(NumberID.Eight)) + NumberID.get(10) must be(None) + } + + "valueOf" in { _ => + NumberID.valueOf("One") must be(Some(NumberID.One)) + NumberID.valueOf("Two") must be(Some(NumberID.Two)) + NumberID.valueOf("Three") must be(Some(NumberID.Three)) + NumberID.valueOf("Five") must be(Some(NumberID.Five)) + NumberID.valueOf("Six") must be(Some(NumberID.Six)) + NumberID.valueOf("Eight") must be(Some(NumberID.Eight)) + NumberID.valueOf("Ten") must be(None) + } + + "correct list" in { _ => + NumberID.list(0) must be(NumberID.One) + NumberID.list(1) must be(NumberID.Two) + NumberID.list(2) must be(NumberID.Three) + NumberID.list(3) must be(NumberID.Five) + NumberID.list(4) must be(NumberID.Six) + NumberID.list(5) must be(NumberID.Eight) + NumberID.list.size must be(6) + } + + "java-serializable" in { _ => val bos = new ByteArrayOutputStream() val out = new ObjectOutputStream(bos) out.writeObject(NumberID.One) @@ -88,82 +86,82 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo val in = new ObjectInputStream(new ByteArrayInputStream(bytes)) var obj = in.readObject() - obj.isInstanceOf[NumberID] must beTrue - obj.asInstanceOf[NumberID].getValue mustEqual NumberID.One.getValue - obj.asInstanceOf[NumberID].name mustEqual NumberID.One.name + obj.isInstanceOf[NumberID] must be(true) + obj.asInstanceOf[NumberID].getValue must be(NumberID.One.getValue) + obj.asInstanceOf[NumberID].name must be(NumberID.One.name) obj = in.readObject() - obj.isInstanceOf[NumberID] must beTrue - obj.asInstanceOf[NumberID].getValue mustEqual NumberID.Two.getValue - obj.asInstanceOf[NumberID].name mustEqual NumberID.Two.name - } - - "handle namespace collisions" in { - NamespaceCollisions.List.name mustEqual "List" - NamespaceCollisions.Any.name mustEqual "Any" - NamespaceCollisions.AnyRef.name mustEqual "AnyRef" - NamespaceCollisions.Object.name mustEqual "Object" - NamespaceCollisions.String.name mustEqual "String" - NamespaceCollisions.Byte.name mustEqual "Byte" - NamespaceCollisions.Short.name mustEqual "Short" - NamespaceCollisions.Char.name mustEqual "Char" - NamespaceCollisions.Int.name mustEqual "Int" - NamespaceCollisions.Long.name mustEqual "Long" - NamespaceCollisions.Float.name mustEqual "Float" - NamespaceCollisions.Double.name mustEqual "Double" - NamespaceCollisions.Option.name mustEqual "Option" - NamespaceCollisions.None.name mustEqual "None" - NamespaceCollisions.Some.name mustEqual "Some" - NamespaceCollisions.Nil.name mustEqual "Nil" - NamespaceCollisions.Null.name mustEqual "Null" - NamespaceCollisions.Set.name mustEqual "Set" - NamespaceCollisions.Map.name mustEqual "Map" - NamespaceCollisions.Seq.name mustEqual "Seq" - NamespaceCollisions.Array.name mustEqual "Array" - NamespaceCollisions.Iterable.name mustEqual "Iterable" - NamespaceCollisions.Unit.name mustEqual "Unit" - NamespaceCollisions.Nothing.name mustEqual "Nothing" - NamespaceCollisions.Protected.name mustEqual "Protected" - - NamespaceCollisions.valueOf("null") must beSome(NamespaceCollisions.Null) - NamespaceCollisions.valueOf("protected") must beSome(NamespaceCollisions.Protected) - } - - "encode-decode in struct" in { + obj.isInstanceOf[NumberID] must be(true) + obj.asInstanceOf[NumberID].getValue must be(NumberID.Two.getValue) + obj.asInstanceOf[NumberID].name must be(NumberID.Two.name) + } + + "handle namespace collisions" in { _ => + NamespaceCollisions.List.name must be("List") + NamespaceCollisions.Any.name must be("Any") + NamespaceCollisions.AnyRef.name must be("AnyRef") + NamespaceCollisions.Object.name must be("Object") + NamespaceCollisions.String.name must be("String") + NamespaceCollisions.Byte.name must be("Byte") + NamespaceCollisions.Short.name must be("Short") + NamespaceCollisions.Char.name must be("Char") + NamespaceCollisions.Int.name must be("Int") + NamespaceCollisions.Long.name must be("Long") + NamespaceCollisions.Float.name must be("Float") + NamespaceCollisions.Double.name must be("Double") + NamespaceCollisions.Option.name must be("Option") + NamespaceCollisions.None.name must be("None") + NamespaceCollisions.Some.name must be("Some") + NamespaceCollisions.Nil.name must be("Nil") + NamespaceCollisions.Null.name must be("Null") + NamespaceCollisions.Set.name must be("Set") + NamespaceCollisions.Map.name must be("Map") + NamespaceCollisions.Seq.name must be("Seq") + NamespaceCollisions.Array.name must be("Array") + NamespaceCollisions.Iterable.name must be("Iterable") + NamespaceCollisions.Unit.name must be("Unit") + NamespaceCollisions.Nothing.name must be("Nothing") + NamespaceCollisions.Protected.name must be("Protected") + + NamespaceCollisions.valueOf("null") must be(Some(NamespaceCollisions.Null)) + NamespaceCollisions.valueOf("protected") must be(Some(NamespaceCollisions.Protected)) + } + + "encode-decode in struct" in { _ => val prot = new TBinaryProtocol(new TMemoryBuffer(64)) val eStruct = EnumStruct(NumberID.One) EnumStruct.encode(eStruct, prot) - EnumStruct.decode(prot) mustEqual eStruct + EnumStruct.decode(prot) must be(eStruct) } - "encode-decode in union" in { + "encode-decode in union" in { _ => val prot = new TBinaryProtocol(new TMemoryBuffer(64)) val eUnion = EnumUnion.Number(NumberID.One) EnumUnion.encode(eUnion, prot) - EnumUnion.decode(prot) mustEqual eUnion + EnumUnion.decode(prot) must be(eUnion) } - "be identified as an ENUM" in { - EnumStruct.NumberField.`type` mustEqual TType.ENUM + "be identified as an ENUM" in { _ => + EnumStruct.NumberField.`type` must be(TType.ENUM) } - "be identified as an I32 on the wire for structs" in { + "be identified as an I32 on the wire for structs" in { _ => val prot = new TBinaryProtocol(new TMemoryBuffer(64)) EnumStruct.encode(EnumStruct(NumberID.One), prot) prot.readStructBegin() val field = prot.readFieldBegin() - field.`type` mustEqual TType.I32 + field.`type` must be(TType.I32) } - "be identified as an I32 on the wire for unions" in { + "be identified as an I32 on the wire for unions" in { _ => val prot = new TBinaryProtocol(new TMemoryBuffer(64)) EnumUnion.encode(EnumUnion.Number(NumberID.One), prot) prot.readStructBegin() val field = prot.readFieldBegin() - field.`type` mustEqual TType.I32 + field.`type` must be(TType.I32) } - "be identified as I32 on the wire for collections" in { + "be identified as I32 on the wire for collections" in { _ => val prot = new TBinaryProtocol(new TMemoryBuffer(64)) val eStruct = EnumCollections( aMap = Map(NumberID.One -> NumberID.Two), @@ -171,7 +169,7 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo aSet = Set(NumberID.One)) EnumCollections.encode(eStruct, prot) - EnumCollections.decode(prot) mustEqual eStruct + EnumCollections.decode(prot) must be(eStruct) EnumCollections.encode(eStruct, prot) @@ -180,8 +178,8 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo // Test Map encoding prot.readFieldBegin() val mapField = prot.readMapBegin() - mapField.keyType mustEqual TType.I32 - mapField.valueType mustEqual TType.I32 + mapField.keyType must be(TType.I32) + mapField.valueType must be(TType.I32) prot.readI32(); prot.readI32() prot.readMapEnd() prot.readFieldEnd() @@ -189,7 +187,7 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo // Test List encoding prot.readFieldBegin() val listField = prot.readListBegin() - listField.elemType mustEqual TType.I32 + listField.elemType must be(TType.I32) prot.readI32() prot.readListEnd() prot.readFieldEnd() @@ -197,558 +195,666 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo // Test Set encoding prot.readFieldBegin() val setField = prot.readSetBegin() - setField.elemType mustEqual TType.I32 + setField.elemType must be(TType.I32) } } - "generate constants" in { - thrift.test.Constants.myWfhDay mustEqual WeekDay.Thu - thrift.test.Constants.myDaysOut mustEqual List(WeekDay.Thu, WeekDay.Sat, WeekDay.SUN) - thrift.test.Constants.name mustEqual "Columbo" - thrift.test.Constants.someInt mustEqual 1 - thrift.test.Constants.someDouble mustEqual 3.0 - thrift.test.Constants.someList mustEqual List("piggy") - thrift.test.Constants.emptyList mustEqual List() - thrift.test.Constants.someMap mustEqual Map("foo" -> "bar") - thrift.test.Constants.someSimpleSet mustEqual Set("foo", "bar") - thrift.test.Constants.someSet mustEqual Set( + "generate constants" in { _ => + thrift.test.Constants.myWfhDay must be(WeekDay.Thu) + thrift.test.Constants.myDaysOut must be(List(WeekDay.Thu, WeekDay.Sat, WeekDay.SUN)) + thrift.test.Constants.name must be("Columbo") + thrift.test.Constants.someInt must be(1) + thrift.test.Constants.someDouble must be(3.0) + thrift.test.Constants.someList must be(List("piggy")) + 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") - ) + )) } - "basic structs" in { - "ints" in { - "read" in { - expect { - startRead(protocol, new TField("baby", TType.I16, 1)) - one(protocol).readI16() willReturn (16: Short) - nextRead(protocol, new TField("mama", TType.I32, 2)) - one(protocol).readI32() willReturn 32 - nextRead(protocol, new TField("papa", TType.I64, 3)) - one(protocol).readI64() willReturn 64L - endRead(protocol) + "basic structs" should { + "ints" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readI32(); will(returnValue(32)) + nextRead(e, protocol, new TField("papa", TType.I64, 3)) + one(protocol).readI64(); will(returnValue(64L)) + endRead(e, protocol) } - Ints.decode(protocol) mustEqual Ints(16, 32, 64L) + whenExecuting { + Ints.decode(protocol) must be(Ints(16, 32, 64L)) + } } - "write" in { - expect { - startWrite(protocol, new TField("baby", TType.I16, 1)) - one(protocol).writeI16(16) - nextWrite(protocol, new TField("mama", TType.I32, 2)) - one(protocol).writeI32(32) - nextWrite(protocol, new TField("papa", TType.I64, 3)) - one(protocol).writeI64(64) - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeI32(`with`(Expectations.equal(32))) + nextWrite(e, protocol, new TField("papa", TType.I64, 3)) + one(protocol).writeI64(`with`(Expectations.equal(64L))) + endWrite(e, protocol) } - Ints(16, 32, 64L).write(protocol) mustEqual () + whenExecuting { + Ints(16, 32, 64L).write(protocol) must be(()) + } } } - "bytes" in { - "read" in { - expect { - startRead(protocol, new TField("x", TType.BYTE, 1)) - one(protocol).readByte() willReturn 3.toByte - nextRead(protocol, new TField("y", TType.STRING, 2)) - one(protocol).readBinary() willReturn stringToBytes("hello") - endRead(protocol) + "bytes" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readBinary(); will(returnValue(stringToBytes("hello"))) + endRead(e, protocol) } - val bytes = Bytes.decode(protocol) - bytes.x mustEqual 3.toByte - new String(bytes.y.array) mustEqual "hello" + whenExecuting { + val bytes = Bytes.decode(protocol) + bytes.x must be(3.toByte) + new String(bytes.y.array) must be("hello") + } } - "write" in { - expect { - startWrite(protocol, new TField("x", TType.BYTE, 1)) - one(protocol).writeByte(16.toByte) - nextWrite(protocol, new TField("y", TType.STRING, 2)) - one(protocol).writeBinary(stringToBytes("goodbye")) - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeBinary(`with`(Expectations.equal(stringToBytes("goodbye")))) + endWrite(e, protocol) } - Bytes(16.toByte, stringToBytes("goodbye")).write(protocol) mustEqual () + whenExecuting { + Bytes(16.toByte, stringToBytes("goodbye")).write(protocol) must be(()) + } } } - "bool, double, string" in { - "read" in { - expect { - startRead(protocol, new TField("alive", TType.BOOL, 1)) - one(protocol).readBool() willReturn true - nextRead(protocol, new TField("pi", TType.DOUBLE, 2)) - one(protocol).readDouble() willReturn 3.14 - nextRead(protocol, new TField("name", TType.STRING, 3)) - one(protocol).readString() willReturn "bender" - endRead(protocol) + "bool, double, string" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readDouble(); will(returnValue(3.14)) + nextRead(e, protocol, new TField("name", TType.STRING, 3)) + one(protocol).readString(); will(returnValue("bender")) + endRead(e, protocol) } - Misc.decode(protocol) mustEqual Misc(true, 3.14, "bender") + whenExecuting { + Misc.decode(protocol) must be(Misc(true, 3.14, "bender")) + } } - "write" in { - expect { - startWrite(protocol, new TField("alive", TType.BOOL, 1)) - one(protocol).writeBool(false) - nextWrite(protocol, new TField("pi", TType.DOUBLE, 2)) - one(protocol).writeDouble(6.28) - nextWrite(protocol, new TField("name", TType.STRING, 3)) - one(protocol).writeString("fry") - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeDouble(`with`(Expectations.equal(6.28))) + nextWrite(e, protocol, new TField("name", TType.STRING, 3)) + one(protocol).writeString(`with`(Expectations.equal("fry"))) + endWrite(e, protocol) } - Misc(false, 6.28, "fry").write(protocol) mustEqual () + whenExecuting { + Misc(false, 6.28, "fry").write(protocol) must be(()) + } } } - "lists, sets, and maps" in { + "lists, sets, and maps" should { val exemplar = Compound( intlist = List(10, 20), intset = Set(44, 55), namemap = Map("wendy" -> 500), nested = List(Set(9))) - "read" in { - expect { - startRead(protocol, new TField("intlist", TType.LIST, 1)) - one(protocol).readListBegin() willReturn new TList(TType.I32, 2) - one(protocol).readI32() willReturn 10 - one(protocol).readI32() willReturn 20 + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readI32(); will(returnValue(20)) one(protocol).readListEnd() - nextRead(protocol, new TField("intset", TType.SET, 2)) - one(protocol).readSetBegin() willReturn new TSet(TType.I32, 2) - one(protocol).readI32() willReturn 44 - one(protocol).readI32() willReturn 55 + nextRead(e, protocol, new TField("intset", TType.SET, 2)) + one(protocol).readSetBegin(); will(returnValue(new TSet(TType.I32, 2))) + one(protocol).readI32(); will(returnValue(44)) + one(protocol).readI32(); will(returnValue(55)) one(protocol).readSetEnd() - nextRead(protocol, new TField("namemap", TType.MAP, 3)) - one(protocol).readMapBegin() willReturn new TMap(TType.STRING, TType.I32, 1) - one(protocol).readString() willReturn "wendy" - one(protocol).readI32() willReturn 500 + nextRead(e, protocol, new TField("namemap", TType.MAP, 3)) + one(protocol).readMapBegin(); will(returnValue(new TMap(TType.STRING, TType.I32, 1))) + one(protocol).readString(); will(returnValue("wendy")) + one(protocol).readI32(); will(returnValue(500)) one(protocol).readMapEnd() - nextRead(protocol, new TField("nested", TType.LIST, 4)) - one(protocol).readListBegin() willReturn new TList(TType.SET, 1) - one(protocol).readSetBegin() willReturn new TSet(TType.I32, 1) - one(protocol).readI32() willReturn 9 + nextRead(e, protocol, new TField("nested", TType.LIST, 4)) + one(protocol).readListBegin(); will(returnValue(new TList(TType.SET, 1))) + one(protocol).readSetBegin(); will(returnValue(new TSet(TType.I32, 1))) + one(protocol).readI32(); will(returnValue(9)) one(protocol).readSetEnd() one(protocol).readListEnd() - endRead(protocol) + endRead(e, protocol) } - Compound.decode(protocol) mustEqual exemplar + whenExecuting { + Compound.decode(protocol) must be(exemplar) + } } - "write" in { - expect { - startWrite(protocol, new TField("intlist", TType.LIST, 1)) - one(protocol).writeListBegin(equal(new TList(TType.I32, 2))) - one(protocol).writeI32(10) - one(protocol).writeI32(20) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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))) + one(protocol).writeI32(`with`(Expectations.equal(20))) one(protocol).writeListEnd() - nextWrite(protocol, new TField("intset", TType.SET, 2)) - one(protocol).writeSetBegin(equal(new TSet(TType.I32, 2))) - one(protocol).writeI32(44) - one(protocol).writeI32(55) + nextWrite(e, protocol, new TField("intset", TType.SET, 2)) + one(protocol).writeSetBegin(`with`(setEqual(new TSet(TType.I32, 2)))) + one(protocol).writeI32(`with`(Expectations.equal(44))) + one(protocol).writeI32(`with`(Expectations.equal(55))) one(protocol).writeSetEnd() - nextWrite(protocol, new TField("namemap", TType.MAP, 3)) - one(protocol).writeMapBegin(equal(new TMap(TType.STRING, TType.I32, 1))) - one(protocol).writeString("wendy") - one(protocol).writeI32(500) + nextWrite(e, protocol, new TField("namemap", TType.MAP, 3)) + one(protocol).writeMapBegin(`with`(mapEqual(new TMap(TType.STRING, TType.I32, 1)))) + one(protocol).writeString(`with`(Expectations.equal("wendy"))) + one(protocol).writeI32(`with`(Expectations.equal(500))) one(protocol).writeMapEnd() - nextWrite(protocol, new TField("nested", TType.LIST, 4)) - one(protocol).writeListBegin(equal(new TList(TType.SET, 1))) - one(protocol).writeSetBegin(equal(new TSet(TType.I32, 1))) - one(protocol).writeI32(9) + nextWrite(e, protocol, new TField("nested", TType.LIST, 4)) + one(protocol).writeListBegin(`with`(listEqual(new TList(TType.SET, 1)))) + one(protocol).writeSetBegin(`with`(setEqual(new TSet(TType.I32, 1)))) + one(protocol).writeI32(`with`(Expectations.equal(9))) one(protocol).writeSetEnd() one(protocol).writeListEnd() - endWrite(protocol) + endWrite(e, protocol) } - exemplar.write(protocol) mustEqual () + whenExecuting { + exemplar.write(protocol) must be(()) + } } } } - "complicated structs" in { - "with required fields" in { - "read" in { - expect { - startRead(protocol, new TField("string", TType.STRING, 1)) - one(protocol).readString() willReturn "yo" - endRead(protocol) + "complicated structs" should { + "with required fields" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startRead(e, protocol, new TField("string", TType.STRING, 1)) + one(protocol).readString(); will(returnValue("yo")) + endRead(e, protocol) } - RequiredString.decode(protocol) mustEqual RequiredString("yo") + whenExecuting { + RequiredString.decode(protocol) must be(RequiredString("yo")) + } } - "missing required value throws exception during deserialization" in { - doBefore { - expect { - emptyRead(protocol) + "missing required value throws exception during deserialization" should { + "with no default value" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + emptyRead(e, protocol) } - } - "with no default value" in { - RequiredString.decode(protocol) must throwA[TProtocolException] + whenExecuting { + intercept[TProtocolException] { + RequiredString.decode(protocol) + } + } } - "with default value" in { - RequiredStringWithDefault.decode(protocol) must throwA[TProtocolException] + "with default value" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + emptyRead(e, protocol) + } + + whenExecuting { + intercept[TProtocolException] { + RequiredStringWithDefault.decode(protocol) + } + } } } - "null required value throws exception during serialization" in { - "with no default value" in { - RequiredString(value = null).write(protocol) must throwA[TProtocolException] + "null required value throws exception during serialization" should { + "with no default value" in { cycle => import cycle._ + val protocol = mock[TProtocol] + + whenExecuting { + intercept[TProtocolException] { + RequiredString(value = null).write(protocol) + } + } } - "with default value" in { - RequiredStringWithDefault(value = null).write(protocol) must throwA[TProtocolException] + "with default value" in { cycle => import cycle._ + val protocol = mock[TProtocol] + + whenExecuting { + intercept[TProtocolException] { + RequiredStringWithDefault(value = null).write(protocol) + } + } } } } - "with optional fields" in { - "read" in { - expect { - startRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "Commie" - nextRead(protocol, new TField("age", TType.I32, 2)) - one(protocol).readI32() willReturn 14 - endRead(protocol) + "with optional fields" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readI32(); will(returnValue(14)) + endRead(e, protocol) } - OptionalInt.decode(protocol) mustEqual OptionalInt("Commie", Some(14)) + whenExecuting { + OptionalInt.decode(protocol) must be(OptionalInt("Commie", Some(14))) + } } - "read with missing field" in { - expect { - startRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "Commie" - endRead(protocol) + "read with missing field" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startRead(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).readString(); will(returnValue("Commie")) + endRead(e, protocol) } - OptionalInt.decode(protocol) mustEqual OptionalInt("Commie", None) + whenExecuting { + OptionalInt.decode(protocol) must be(OptionalInt("Commie", None)) + } } - "write" in { - expect { - startWrite(protocol, new TField("name", TType.STRING, 1)) - one(protocol).writeString("Commie") - nextWrite(protocol, new TField("age", TType.I32, 2)) - one(protocol).writeI32(14) - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeI32(`with`(Expectations.equal(14))) + endWrite(e, protocol) } - OptionalInt("Commie", Some(14)).write(protocol) mustEqual () + whenExecuting { + OptionalInt("Commie", Some(14)).write(protocol) must be(()) + } } - "write with missing field" in { - expect { - startWrite(protocol, new TField("name", TType.STRING, 1)) - one(protocol).writeString("Commie") - endWrite(protocol) + "write with missing field" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startWrite(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).writeString(`with`(Expectations.equal("Commie"))) + endWrite(e, protocol) } - OptionalInt("Commie", None).write(protocol) mustEqual () + whenExecuting { + OptionalInt("Commie", None).write(protocol) must be(()) + } } } - "with default values" in { - "read with value missing, using default" in { - expect { + "with default values" should { + "read with value missing, using default" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ one(protocol).readStructBegin() - one(protocol).readFieldBegin() willReturn new TField("stop", TType.STOP, 10) + one(protocol).readFieldBegin(); will(returnValue(new TField("stop", TType.STOP, 10))) one(protocol).readStructEnd() } - DefaultValues.decode(protocol) mustEqual DefaultValues("leela") + whenExecuting { + DefaultValues.decode(protocol) must be(DefaultValues("leela")) + } } - "read with value present" in { - expect { + "read with value present" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ one(protocol).readStructBegin() - nextRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "delilah" - one(protocol).readFieldBegin() willReturn new TField("stop", TType.STOP, 10) + nextRead(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).readString(); will(returnValue("delilah")) + one(protocol).readFieldBegin(); will(returnValue(new TField("stop", TType.STOP, 10))) one(protocol).readStructEnd() } - DefaultValues.decode(protocol) mustEqual DefaultValues("delilah") + whenExecuting { + DefaultValues.decode(protocol) must be(DefaultValues("delilah")) + } } } - "nested" in { - "read" in { - expect { - startRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "United States of America" - nextRead(protocol, new TField("provinces", TType.LIST, 2)) - one(protocol).readListBegin() willReturn new TList(TType.STRING, 2) - one(protocol).readString() willReturn "connecticut" - one(protocol).readString() willReturn "california" + "nested" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readListBegin(); will(returnValue(new TList(TType.STRING, 2))) + one(protocol).readString(); will(returnValue("connecticut")) + one(protocol).readString(); will(returnValue("california")) one(protocol).readListEnd() - nextRead(protocol, new TField("emperor", TType.STRUCT, 5)) + nextRead(e, protocol, new TField("emperor", TType.STRUCT, 5)) /** Start of Emperor struct **/ - startRead(protocol, new TField("name", TType.STRING, 1)) - one(protocol).readString() willReturn "Bush" - nextRead(protocol, new TField("age", TType.I32, 2)) - one(protocol).readI32() willReturn 42 - endRead(protocol) + startRead(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).readString(); will(returnValue("Bush")) + nextRead(e, protocol, new TField("age", TType.I32, 2)) + one(protocol).readI32(); will(returnValue(42)) + endRead(e, protocol) /** End of Emperor struct **/ - endRead(protocol) + endRead(e, protocol) } - Empire.decode(protocol) mustEqual Empire( - "United States of America", - List("connecticut", "california"), - Emperor("Bush", 42)) + whenExecuting { + Empire.decode(protocol) must be(Empire( + "United States of America", + List("connecticut", "california"), + Emperor("Bush", 42))) + } } - "write" in { - expect { - startWrite(protocol, new TField("name", TType.STRING, 1)) - one(protocol).writeString("Canada") - nextWrite(protocol, new TField("provinces", TType.LIST, 2)) - one(protocol).writeListBegin(equal(new TList(TType.STRING, 2))) - one(protocol).writeString("Manitoba") - one(protocol).writeString("Alberta") + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).writeListBegin(`with`(listEqual(new TList(TType.STRING, 2)))) + one(protocol).writeString(`with`(Expectations.equal("Manitoba"))) + one(protocol).writeString(`with`(Expectations.equal("Alberta"))) one(protocol).writeListEnd() - nextWrite(protocol, new TField("emperor", TType.STRUCT, 5)) + nextWrite(e, protocol, new TField("emperor", TType.STRUCT, 5)) // emperor - startWrite(protocol, new TField("name", TType.STRING, 1)) - one(protocol).writeString("Larry") - nextWrite(protocol, new TField("age", TType.I32, 2)) - one(protocol).writeI32(13) - endWrite(protocol) + startWrite(e, protocol, new TField("name", TType.STRING, 1)) + one(protocol).writeString(`with`(Expectations.equal("Larry"))) + nextWrite(e, protocol, new TField("age", TType.I32, 2)) + one(protocol).writeI32(`with`(Expectations.equal(13))) + endWrite(e, protocol) - endWrite(protocol) + endWrite(e, protocol) } - Empire( - "Canada", - List("Manitoba", "Alberta"), - Emperor("Larry", 13) - ).write(protocol) mustEqual () + whenExecuting { + Empire( + "Canada", + List("Manitoba", "Alberta"), + Emperor("Larry", 13) + ).write(protocol) must be(()) + } } } - "exception" in { - Xception(1, "boom") must haveSuperClass[Exception] - Xception(1, "boom") must haveSuperClass[ThriftException] - Xception(1, "boom") must haveSuperClass[SourcedException] - Xception(1, "boom") must haveSuperClass[ThriftStruct] - Xception(2, "kathunk").getMessage mustEqual "kathunk" + "exception" in { _ => + Xception(1, "boom").isInstanceOf[Exception] must be(true) + Xception(1, "boom").isInstanceOf[ThriftException] must be(true) + Xception(1, "boom").isInstanceOf[SourcedException] must be(true) + Xception(1, "boom").isInstanceOf[ThriftStruct] must be(true) + Xception(2, "kathunk").getMessage must be("kathunk") } - "exception getMessage" in { - StringMsgException(1, "jeah").getMessage mustEqual "jeah" - NonStringMessageException(5).getMessage mustEqual "5" + "exception getMessage" in { _ => + StringMsgException(1, "jeah").getMessage must be("jeah") + NonStringMessageException(5).getMessage must be("5") } - "with more than 22 fields" in { - "apply" in { - Biggie().num25 mustEqual 25 + "with more than 22 fields" should { + "apply" in { _ => + Biggie().num25 must be(25) } - "two default object must be equal" in { - Biggie() mustEqual Biggie() + "two default object must be equal" in { _ => + Biggie() must be(Biggie()) } - "copy and equals" in { - Biggie().copy(num10 = -5) mustEqual Biggie(num10 = -5) + "copy and equals" in { _ => + Biggie().copy(num10 = -5) must be(Biggie(num10 = -5)) } - "hashCode is the same for two similar objects" in { - Biggie().hashCode mustEqual Biggie().hashCode - Biggie(num10 = -5).hashCode mustEqual Biggie(num10 = -5).hashCode + "hashCode is the same for two similar objects" in { _ => + Biggie().hashCode must be(Biggie().hashCode) + Biggie(num10 = -5).hashCode must be(Biggie(num10 = -5).hashCode) } - "hashCode is different for two different objects" in { - Biggie(num10 = -5).hashCode mustNot beEqual(Biggie().hashCode) + "hashCode is different for two different objects" in { _ => + Biggie(num10 = -5).hashCode must not be(Biggie().hashCode) } - "toString" in { - Biggie().toString mustEqual ("Biggie(" + 1.to(25).map(_.toString).mkString(",") + ")") + "toString" in { _ => + Biggie().toString must be(("Biggie(" + 1.to(25).map(_.toString).mkString(",") + ")")) } } - "unapply single field" in { + "unapply single field" in { _ => val struct: Any = RequiredString("hello") struct match { case RequiredString(value) => - value mustEqual "hello" + value must be("hello") } } - "unapply multiple fields" in { + "unapply multiple fields" in { _ => val struct: Any = OptionalInt("foo", Some(32)) struct match { case OptionalInt(name, age) => - name mustEqual "foo" - age must beSome(32) + name must be("foo") + age must be(Some(32)) } } } - "unions" in { - "zero fields" in { - "read" in { - expect { - emptyRead(protocol) + "unions" should { + "zero fields" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + emptyRead(e, protocol) } - Bird.decode(protocol) must throwA[TProtocolException] + whenExecuting { + intercept[TProtocolException] { + Bird.decode(protocol) + } + } } - "write" in { - Bird.Raptor(null).write(protocol) must throwA[TProtocolException] + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + whenExecuting { + intercept[TProtocolException] { + Bird.Raptor(null).write(protocol) + } + } } } - "one field" in { - "read" in { - expect { - startRead(protocol, new TField("hummingbird", TType.STRING, 2)) - one(protocol).readString() willReturn "Ruby-Throated" - endRead(protocol) + "one field" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startRead(e, protocol, new TField("hummingbird", TType.STRING, 2)) + one(protocol).readString(); will(returnValue("Ruby-Throated")) + endRead(e, protocol) } - Bird.decode(protocol) mustEqual Bird.Hummingbird("Ruby-Throated") + whenExecuting { + Bird.decode(protocol) must be(Bird.Hummingbird("Ruby-Throated")) + } } - "write" in { - expect { - startWrite(protocol, new TField("owlet_nightjar", TType.STRING, 3)) - one(protocol).writeString("foo") - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + expecting { e => import e._ + startWrite(e, protocol, new TField("owlet_nightjar", TType.STRING, 3)) + one(protocol).writeString(`with`(Expectations.equal("foo"))) + endWrite(e, protocol) } - Bird.OwletNightjar("foo").write(protocol) + whenExecuting { + Bird.OwletNightjar("foo").write(protocol) + } } } - "more than one field" in { - "read" in { - expect { - startRead(protocol, new TField("hummingbird", TType.STRING, 2)) - one(protocol).readString() willReturn "Anna's Hummingbird" - nextRead(protocol, new TField("owlet_nightjar", TType.STRING, 3)) - one(protocol).readBinary() willReturn ByteBuffer.allocate(1) - endRead(protocol) + "more than one field" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + one(protocol).readBinary(); will(returnValue(ByteBuffer.allocate(1))) + endRead(e, protocol) } - Bird.decode(protocol) must throwA[TProtocolException] + whenExecuting { + intercept[TProtocolException] { + Bird.decode(protocol) + } + } } // no write test because it's not possible } - "nested struct" in { - "read" in { - expect { - startRead(protocol, new TField("raptor", TType.STRUCT, 1)) - startRead(protocol, new TField("isOwl", TType.BOOL, 1)) - one(protocol).readBool() willReturn false - nextRead(protocol, new TField("species", TType.STRING, 2)) - one(protocol).readString() willReturn "peregrine" - endRead(protocol) - endRead(protocol) + "nested struct" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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)) + nextRead(e, protocol, new TField("species", TType.STRING, 2)) + one(protocol).readString(); will(returnValue("peregrine")) + endRead(e, protocol) + endRead(e, protocol) } - Bird.decode(protocol) mustEqual Bird.Raptor(Raptor(false, "peregrine")) + whenExecuting { + Bird.decode(protocol) must be(Bird.Raptor(Raptor(false, "peregrine"))) + } } - "write" in { - expect { - startWrite(protocol, new TField("raptor", TType.STRUCT, 1)) - startWrite(protocol, new TField("isOwl", TType.BOOL, 1)) - one(protocol).writeBool(true) - nextWrite(protocol, new TField("species", TType.STRING, 2)) - one(protocol).writeString("Tyto alba") - endWrite(protocol) - endWrite(protocol) + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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))) + nextWrite(e, protocol, new TField("species", TType.STRING, 2)) + one(protocol).writeString(`with`(Expectations.equal("Tyto alba"))) + endWrite(e, protocol) + endWrite(e, protocol) } - Bird.Raptor(Raptor(true, "Tyto alba")).write(protocol) + whenExecuting { + Bird.Raptor(Raptor(true, "Tyto alba")).write(protocol) + } } } - "collection" in { - "read" in { - expect { - startRead(protocol, new TField("flock", TType.LIST, 4)) - one(protocol).readListBegin() willReturn new TList(TType.STRING, 3) - one(protocol).readString() willReturn "starling" - one(protocol).readString() willReturn "kestrel" - one(protocol).readString() willReturn "warbler" + "collection" should { + "read" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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")) + one(protocol).readString(); will(returnValue("kestrel")) + one(protocol).readString(); will(returnValue("warbler")) one(protocol).readListEnd() - endRead(protocol) + endRead(e, protocol) } - Bird.decode(protocol) mustEqual Bird.Flock(List("starling", "kestrel", "warbler")) + whenExecuting { + Bird.decode(protocol) must be(Bird.Flock(List("starling", "kestrel", "warbler"))) + } } - "write" in { - expect { - startWrite(protocol, new TField("flock", TType.LIST, 4)) - one(protocol).writeListBegin(equal(new TList(TType.STRING, 3))) - one(protocol).writeString("starling") - one(protocol).writeString("kestrel") - one(protocol).writeString("warbler") + "write" in { cycle => import cycle._ + val protocol = mock[TProtocol] + 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"))) + one(protocol).writeString(`with`(Expectations.equal("kestrel"))) + one(protocol).writeString(`with`(Expectations.equal("warbler"))) one(protocol).writeListEnd() - endWrite(protocol) + endWrite(e, protocol) } - Bird.Flock(List("starling", "kestrel", "warbler")).write(protocol) + whenExecuting { + Bird.Flock(List("starling", "kestrel", "warbler")).write(protocol) + } } } - "default value" in { - Bird.Hummingbird() mustEqual Bird.Hummingbird("Calypte anna") + "default value" in { _ => + Bird.Hummingbird() must be(Bird.Hummingbird("Calypte anna")) } - "primitive field type" in { + "primitive field type" in { _ => import thrift.`def`.default._ val protocol = new TBinaryProtocol(new TMemoryBuffer(10000)) var original: NaughtyUnion = NaughtyUnion.Value(1) NaughtyUnion.encode(original, protocol) - NaughtyUnion.decode(protocol) mustEqual(original) + NaughtyUnion.decode(protocol) must be(original) original = NaughtyUnion.Flag(true) NaughtyUnion.encode(original, protocol) - NaughtyUnion.decode(protocol) mustEqual(original) + NaughtyUnion.decode(protocol) must be(original) original = NaughtyUnion.Text("false") NaughtyUnion.encode(original, protocol) - NaughtyUnion.decode(protocol) mustEqual(original) + NaughtyUnion.decode(protocol) must be(original) } } - "typedef relative fields" in { + "typedef relative fields" in { _ => val candy = Candy(100, CandyType.DeliCIous) - candy.sweetnessIso mustEqual 100 - candy.candyType.value mustEqual 1 - candy.brand mustEqual "Hershey" - candy.count mustEqual 10 - candy.headline mustEqual "Life is short, eat dessert first" + candy.sweetnessIso must be(100) + candy.candyType.value must be(1) + candy.brand must be("Hershey") + candy.count must be(10) + candy.headline must be("Life is short, eat dessert first") } - "hide internal helper function to avoid naming conflict" in { + "hide internal helper function to avoid naming conflict" in { _ => import thrift.`def`.default._ val impl = new NaughtyService[Some] { def foo() = Some(FooResult("dummy message")) } - impl.foo().get.message mustEqual("dummy message") + impl.foo().get.message must be("dummy message") } - "pass through fields" in { - "pass through" in { + "pass through fields" should { + "pass through" in { _ => val pt2 = PassThrough2(1, 2) val pt1 = { @@ -763,10 +869,10 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo PassThrough2.decode(protocol) } - pt2roundTripped mustEqual pt2 + pt2roundTripped must be(pt2) } - "be copied" in { + "be copied" in { _ => val pt2 = PassThrough2(1, 2) val pt1 = { @@ -783,10 +889,10 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo PassThrough2.decode(protocol) } - pt2roundTripped mustEqual PassThrough2(2, 2) + pt2roundTripped must be(PassThrough2(2, 2)) } - "be removable" in { + "be removable" in { _ => val pt2 = PassThrough2(1, 2) val pt1 = { @@ -803,10 +909,10 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo PassThrough2.decode(protocol) } - pt2roundTripped mustEqual PassThrough2(1, 0) + pt2roundTripped must be(PassThrough2(1, 0)) } - "be able to add more" in { + "be able to add more" in { _ => val pt1 = PassThrough(1) val pt2 = PassThrough2(1, 2) val f2 = pt2.getFieldBlob(PassThrough2.F2Field.id).get @@ -818,10 +924,10 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo PassThrough2.decode(protocol) } - pt2roundTripped mustEqual pt2 + pt2roundTripped must be(pt2) } - "be proxy-able" in { + "be proxy-able" in { _ => val pt2 = PassThrough2(1, 2) val pt1 = { @@ -840,10 +946,10 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo PassThrough2.decode(protocol) } - pt2roundTripped mustEqual pt2 + pt2roundTripped must be(pt2) } - "be equallable" in { + "be equallable" in { _ => val pt2 = PassThrough2(1, 2) val pt1a = { @@ -858,21 +964,21 @@ class ScalaGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMo PassThrough.decode(protocol) } - pt1a mustEqual pt1b + pt1a must be(pt1b) } } - "gracefully handle null fields" in { + "gracefully handle null fields" in { _ => val prot = new TBinaryProtocol(new TMemoryBuffer(256)) val emp = Emperor(null, 0) // basically these shouldn't blow up Emperor.encode(emp, prot) - Emperor.decode(prot) mustEqual emp + Emperor.decode(prot) must be(emp) } - "generate with special scala namespace syntax" in { - scrooge.test.thriftscala.Thingymabob() must haveSuperClass[scrooge.test.thriftscala.Thingymabob] + "generate with special scala namespace syntax" in { _ => + scrooge.test.thriftscala.Thingymabob().isInstanceOf[scrooge.test.thriftscala.Thingymabob] must be(true) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala index 19fc3e13d..9704c7bba 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala @@ -1,315 +1,345 @@ package com.twitter.scrooge.backend -import java.util.Arrays -import org.specs.SpecificationWithJUnit -import org.specs.matcher.Matcher -import org.specs.mock.{ClassMocker, JMocker} -import org.apache.thrift.protocol._ import com.twitter.finagle import com.twitter.finagle.thrift.ThriftClientRequest -import com.twitter.util.{Await, Future} -import com.twitter.scrooge.testutil.EvalHelper import com.twitter.scrooge.ThriftException +import com.twitter.scrooge.testutil.{JMockSpec, EvalHelper} +import com.twitter.util.{Await, Future} +import org.apache.thrift.protocol._ +import org.jmock.{Expectations, Mockery} +import org.jmock.Expectations.{any, returnValue} +import org.jmock.lib.legacy.ClassImposteriser import thrift.test._ -class ServiceGeneratorSpec extends SpecificationWithJUnit with EvalHelper with JMocker with ClassMocker { - val protocol = mock[TProtocol] - - case class matchThriftClientRequest(r: ThriftClientRequest) extends Matcher[ThriftClientRequest]() { - def apply(v: => ThriftClientRequest) = ( - areEqual(v, r), - "okMessage", - "no match") - - def areEqual(a: ThriftClientRequest, b: ThriftClientRequest) = - Arrays.equals(a.message, b.message) && a.oneway == b.oneway - } - - case class matchByteArray(bs: Array[Byte]) extends Matcher[Array[Byte]]() { - def apply(v: => Array[Byte]) = ( - Arrays.equals(v, bs), - "okMessage", - "no match") - } - +class ServiceGeneratorSpec extends JMockSpec with EvalHelper { "ScalaGenerator service" should { - "generate a service interface" in { + "generate a service interface" in { _ => val service: SimpleService[Some] = new SimpleService[Some] { def deliver(where: String) = Some(3) } - service.deliver("Boston") mustEqual Some(3) + service.deliver("Boston") must be(Some(3)) } - "generate a future-based service interface" in { + "generate a future-based service interface" in { _ => val service: SimpleService.FutureIface = new SimpleService.FutureIface { def deliver(where: String) = Future(3) } - service.deliver("Boston")() mustEqual 3 + Await.result(service.deliver("Boston")) must be(3) } - "generate structs for args and return value" in { - expect { - startRead(protocol, new TField("where", TType.STRING, 1)) - one(protocol).readString() willReturn "boston" - endRead(protocol) + "generate structs for args and return value" in { cycle => import cycle._ + val protocol = mock[TProtocol] + + expecting { e => import e._ + startRead(e, protocol, new TField("where", TType.STRING, 1)) + one(protocol).readString(); will(returnValue("boston")) + endRead(e, protocol) } - SimpleService.deliver$args.decode(protocol).where mustEqual "boston" + whenExecuting { + SimpleService.deliver$args.decode(protocol).where must be("boston") + } - expect { - startWrite(protocol, new TField("where", TType.STRING, 1)) + expecting { e => import e._ + startWrite(e, protocol, new TField("where", TType.STRING, 1)) one(protocol).writeString("atlanta") - endWrite(protocol) + endWrite(e, protocol) } - SimpleService.deliver$args("atlanta").write(protocol) mustEqual () + whenExecuting { + SimpleService.deliver$args("atlanta").write(protocol) must be(()) + } - expect { - startRead(protocol, new TField("success", TType.I32, 0)) - one(protocol).readI32() willReturn 13 - endRead(protocol) + expecting { e => import e._ + startRead(e, protocol, new TField("success", TType.I32, 0)) + one(protocol).readI32(); will(returnValue(13)) + endRead(e, protocol) } - SimpleService.deliver$result.decode(protocol).success mustEqual Some(13) + whenExecuting { + SimpleService.deliver$result.decode(protocol).success must be(Some(13)) + } - expect { - startWrite(protocol, new TField("success", TType.I32, 0)) + expecting { e => import e._ + startWrite(e, protocol, new TField("success", TType.I32, 0)) one(protocol).writeI32(24) - endWrite(protocol) + endWrite(e, protocol) } - SimpleService.deliver$result(Some(24)).write(protocol) mustEqual () + whenExecuting { + SimpleService.deliver$result(Some(24)).write(protocol) must be(()) + } } - "generate unions for args and return value" in { - expect { - startRead(protocol, new TField("arg0", TType.STRUCT, 1)) - startRead(protocol, new TField("bools", TType.STRUCT, 2)) - startRead(protocol, new TField("im_true", TType.BOOL, 1)) - one(protocol).readBool() willReturn true - nextRead(protocol, new TField("im_false", TType.BOOL, 2)) - one(protocol).readBool() willReturn false - endRead(protocol) - endRead(protocol) - endRead(protocol) - } - - ThriftTest.testUnions$args.decode(protocol).arg0 mustEqual - MorePerfectUnion.Bools(Bools(true, false)) - - expect { - startWrite(protocol, new TField("arg0", TType.STRUCT, 1)) - startWrite(protocol, new TField("bonk", TType.STRUCT, 1)) - startWrite(protocol, new TField("message", TType.STRING, 1)) - one(protocol).writeString("hello world") - nextWrite(protocol, new TField("type", TType.I32, 2)) - one(protocol).writeI32(42) - endWrite(protocol) - endWrite(protocol) - endWrite(protocol) - } - - ThriftTest.testUnions$args( - MorePerfectUnion.Bonk(Bonk("hello world", 42)) - ).write(protocol) mustEqual () - - expect { - startRead(protocol, new TField("success", TType.STRUCT, 0)) - startRead(protocol, new TField("bools", TType.STRUCT, 2)) - startRead(protocol, new TField("im_true", TType.BOOL, 1)) - one(protocol).readBool() willReturn true - nextRead(protocol, new TField("im_false", TType.BOOL, 2)) - one(protocol).readBool() willReturn false - endRead(protocol) - endRead(protocol) - endRead(protocol) - } - - ThriftTest.testUnions$result.decode(protocol).success mustEqual - Some(MorePerfectUnion.Bools(Bools(true, false))) - - expect { - startWrite(protocol, new TField("success", TType.STRUCT, 0)) - startWrite(protocol, new TField("bonk", TType.STRUCT, 1)) - startWrite(protocol, new TField("message", TType.STRING, 1)) - one(protocol).writeString("hello world") - nextWrite(protocol, new TField("type", TType.I32, 2)) - one(protocol).writeI32(42) - endWrite(protocol) - endWrite(protocol) - endWrite(protocol) - } - - ThriftTest.testUnions$result( - Some(MorePerfectUnion.Bonk(Bonk("hello world", 42))) - ).write(protocol) mustEqual () + "generate unions for args and return value" in { cycle => import cycle._ + val protocol = mock[TProtocol] + + 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)) + one(protocol).readBool(); will(returnValue(true)) + nextRead(e, protocol, new TField("im_false", TType.BOOL, 2)) + one(protocol).readBool(); will(returnValue(false)) + endRead(e, protocol) + endRead(e, protocol) + endRead(e, protocol) + } + + whenExecuting { + ThriftTest.testUnions$args.decode(protocol).arg0 must be( + MorePerfectUnion.Bools(Bools(true, false))) + } + + 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)) + one(protocol).writeString(`with`(Expectations.equal("hello world"))) + nextWrite(e, protocol, new TField("type", TType.I32, 2)) + one(protocol).writeI32(`with`(Expectations.equal(42))) + endWrite(e, protocol) + endWrite(e, protocol) + endWrite(e, protocol) + } + + whenExecuting { + ThriftTest.testUnions$args( + MorePerfectUnion.Bonk(Bonk("hello world", 42)) + ).write(protocol) must be(()) + } + + 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)) + one(protocol).readBool(); will(returnValue(true)) + nextRead(e, protocol, new TField("im_false", TType.BOOL, 2)) + one(protocol).readBool(); will(returnValue(false)) + endRead(e, protocol) + endRead(e, protocol) + endRead(e, protocol) + } + + whenExecuting { + ThriftTest.testUnions$result.decode(protocol).success must be( + Some(MorePerfectUnion.Bools(Bools(true, false)))) + } + + 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)) + one(protocol).writeString(`with`(Expectations.equal("hello world"))) + nextWrite(e, protocol, new TField("type", TType.I32, 2)) + one(protocol).writeI32(`with`(Expectations.equal(42))) + endWrite(e, protocol) + endWrite(e, protocol) + endWrite(e, protocol) + } + + whenExecuting { + ThriftTest.testUnions$result( + Some(MorePerfectUnion.Bonk(Bonk("hello world", 42))) + ).write(protocol) must be(()) + } } - "generate exception return values" in { - expect { - startRead(protocol, new TField("ex", TType.STRUCT, 1)) - startRead(protocol, new TField("errorCode", TType.I32, 1)) - one(protocol).readI32() willReturn 1 - nextRead(protocol, new TField("message", TType.STRING, 2)) - one(protocol).readString() willReturn "silly" - endRead(protocol) - endRead(protocol) + "generate exception return values" in { cycle => import cycle._ + val protocol = mock[TProtocol] + + 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)) + nextRead(e, protocol, new TField("message", TType.STRING, 2)) + one(protocol).readString(); will(returnValue("silly")) + endRead(e, protocol) + endRead(e, protocol) } - val res = ExceptionalService.deliver$result.decode(protocol) - res.success must beNone - res.ex must beSome(Xception(1, "silly")) - res.ex2 must beNone + whenExecuting { + val res = ExceptionalService.deliver$result.decode(protocol) + res.success must be(None) + res.ex must be(Some(Xception(1, "silly"))) + res.ex2 must be(None) + } - expect { - startWrite(protocol, new TField("success", TType.I32, 0)) + expecting { e => import e._ + startWrite(e, protocol, new TField("success", TType.I32, 0)) one(protocol).writeI32(24) - endWrite(protocol) + endWrite(e, protocol) } - ExceptionalService.deliver$result(Some(24)).write(protocol) mustEqual () + whenExecuting { + ExceptionalService.deliver$result(Some(24)).write(protocol) must be(()) + } - expect { - startWrite(protocol, new TField("ex", TType.STRUCT, 1)) - startWrite(protocol, new TField("errorCode", TType.I32, 1)) - one(protocol).writeI32(1) - nextWrite(protocol, new TField("message", TType.STRING, 2)) - one(protocol).writeString("silly") - endWrite(protocol) - endWrite(protocol) + 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))) + nextWrite(e, protocol, new TField("message", TType.STRING, 2)) + one(protocol).writeString(`with`(Expectations.equal("silly"))) + endWrite(e, protocol) + endWrite(e, protocol) } - ExceptionalService.deliver$result(None, Some(Xception(1, "silly"))).write(protocol) mustEqual () + whenExecuting { + ExceptionalService.deliver$result(None, Some(Xception(1, "silly"))).write(protocol) must be(()) + } - expect { - startWrite(protocol, new TField("ex3", TType.STRUCT, 3)) - one(protocol).writeStructBegin(capturingParam[TStruct].capture) + expecting { e => import e._ + startWrite(e, protocol, new TField("ex3", TType.STRUCT, 3)) + one(protocol).writeStructBegin(`with`(any(classOf[TStruct]))) one(protocol).writeFieldStop() one(protocol).writeStructEnd() - endWrite(protocol) + endWrite(e, protocol) + } + + whenExecuting { + ExceptionalService.deliver$result(None, None, None, Some(EmptyXception())).write(protocol) must be(()) } - ExceptionalService.deliver$result(None, None, None, Some(EmptyXception())).write(protocol) mustEqual () } - "generate FinagleService" in { - val impl = mock[ExceptionalService[Future]] + "generate FinagleService" should { + // use JMock manually - the scalatest JMock integration has trouble with + // the erasure for ExceptionalService[Future] + val context = new Mockery + context.setImposteriser(ClassImposteriser.INSTANCE) + val impl = context.mock(classOf[ExceptionalService[Future]]) val service = new ExceptionalService$FinagleService(impl, new TBinaryProtocol.Factory) - "success" in { + "success" in { _ => val request = encodeRequest("deliver", ExceptionalService.deliver$args("Boston")).message val response = encodeResponse("deliver", ExceptionalService.deliver$result(success = Some(42))) - expect { - one(impl).deliver("Boston") willReturn Future.value(42) - } + context.checking(new Expectations { + one(impl).deliver("Boston"); will(returnValue(Future.value(42))) + }) - service(request)() must matchByteArray(response) + Await.result(service(request)) must be(response) + context.assertIsSatisfied() } - "exception" in { + "exception" in { _ => val request = encodeRequest("deliver", ExceptionalService.deliver$args("Boston")).message val ex = Xception(1, "boom") val response = encodeResponse("deliver", ExceptionalService.deliver$result(ex = Some(ex))) - expect { - one(impl).deliver("Boston") willReturn Future.exception(ex) - } + context.checking(new Expectations { + one(impl).deliver("Boston"); will(returnValue(Future.exception(ex))) + }) - service(request)() must matchByteArray(response) + Await.result(service(request)) must be(response) + context.assertIsSatisfied() } } - "generate FinagledClient" in { - val impl = mock[ExceptionalService[Future]] + "generate FinagledClient" should { + val context = new Mockery + context.setImposteriser(ClassImposteriser.INSTANCE) + val impl = context.mock(classOf[ExceptionalService[Future]]) val service = new ExceptionalService$FinagleService(impl, new TBinaryProtocol.Factory) val clientService = new finagle.Service[ThriftClientRequest, Array[Byte]] { def apply(req: ThriftClientRequest) = service(req.message) } val client = new ExceptionalService$FinagleClient(clientService) - "success" in { + "success" in { _ => val request = encodeRequest("deliver", ExceptionalService.deliver$args("Boston")) val response = encodeResponse("deliver", ExceptionalService.deliver$result(success = Some(42))) - expect { - one(impl).deliver("Boston") willReturn Future.value(42) - } + context.checking(new Expectations { + one(impl).deliver("Boston"); will(returnValue(Future.value(42))) + }) - client.deliver("Boston")() mustEqual 42 + Await.result(client.deliver("Boston")) must be(42) + context.assertIsSatisfied() } - "success void" in { + "success void" in { _ => val request = encodeRequest("remove", ExceptionalService.remove$args(123)) val response = encodeResponse("remove", ExceptionalService.remove$result()) - expect { - one(impl).remove(123) willReturn Future.Done - } + context.checking(new Expectations { + one(impl).remove(123); will(returnValue(Future.Done)) + }) - client.remove(123)() mustEqual () + Await.result(client.remove(123)) must be(()) + context.assertIsSatisfied() } - "exception" in { + "exception" in { _ => val ex = Xception(1, "boom") - expect { - one(impl).deliver("Boston") willReturn Future.exception(ex) - } + context.checking(new Expectations { + one(impl).deliver("Boston"); will(returnValue(Future.exception(ex))) + }) + assert(Xception(1, "boom") == ex) - Await.result(client.deliver("Boston")) must throwA(Xception(1, "boom")) + val e = intercept[Xception] { + Await.result(client.deliver("Boston")) + } + e must be(Xception(1, "boom")) + context.assertIsSatisfied() } - "void exception" in { + "void exception" in { _ => val ex = Xception(1, "boom") - expect { - one(impl).remove(123) willReturn Future.exception(ex) - } + context.checking(new Expectations { + one(impl).remove(123); will(returnValue(Future.exception(ex))) + }) - Await.result(client.remove(123)) must throwA[ThriftException](ex) + val e = intercept[ThriftException] { + Await.result(client.remove(123)) + } + e must be(ex) + context.assertIsSatisfied() } } - "correctly inherit traits across services" in { - "generic" in { + "correctly inherit traits across services" should { + "generic" in { _ => class BasicImpl extends ReadWriteService[Some] { def getName() = Some("Rus") def setName(name: String) = Some(()) } - new BasicImpl() must haveSuperClass[ReadOnlyService[Some]] - new BasicImpl() must haveSuperClass[ReadWriteService[Some]] + new BasicImpl().isInstanceOf[ReadOnlyService[Some]] must be(true) + new BasicImpl().isInstanceOf[ReadWriteService[Some]] must be(true) } - "future-based" in { + "future-based" in { _ => class FutureImpl extends ReadWriteService.FutureIface { def getName() = Future("Rus") def setName(name: String) = Future.Unit } - new FutureImpl() must haveSuperClass[ReadOnlyService.FutureIface] - new FutureImpl() must haveSuperClass[ReadWriteService.FutureIface] + new FutureImpl().isInstanceOf[ReadOnlyService.FutureIface] must be(true) + new FutureImpl().isInstanceOf[ReadWriteService.FutureIface] must be(true) } - "finagle" in { + "finagle" in { _ => val service = new ReadWriteService$FinagleService(null, null) - service must haveSuperClass[ReadOnlyService$FinagleService] + service.isInstanceOf[ReadOnlyService$FinagleService] must be(true) val client = new ReadWriteService$FinagleClient(null, null) - client must haveSuperClass[ReadOnlyService$FinagleClient] - client must haveSuperClass[ReadOnlyService[Future]] - client must haveSuperClass[ReadWriteService[Future]] + client.isInstanceOf[ReadOnlyService$FinagleClient] must be(true) + client.isInstanceOf[ReadOnlyService[Future]] must be(true) + client.isInstanceOf[ReadWriteService[Future]] must be(true) } } - "camelize names only in the scala bindings" in { + "camelize names only in the scala bindings" in { _ => 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) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/ImporterSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/ImporterSpec.scala index 52ba0afd5..71720e0cc 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/ImporterSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/ImporterSpec.scala @@ -1,10 +1,10 @@ package com.twitter.scrooge.frontend import java.io.{File, FileOutputStream} -import org.specs.SpecificationWithJUnit +import com.twitter.scrooge.testutil.Spec import com.twitter.scrooge.testutil.TempDirectory -class ImporterSpec extends SpecificationWithJUnit { +class ImporterSpec extends Spec { "fileImporter" should { val testFolder = TempDirectory.create(None) @@ -20,8 +20,8 @@ class ImporterSpec extends SpecificationWithJUnit { val importer = Importer(Seq(folder1.getAbsolutePath, folder2.getAbsolutePath)) val c = importer.apply("a.thrift") - c.isDefined must beTrue - c.get.data mustEqual "hello" + c.isDefined must be(true) + c.get.data must be("hello") } "follows relative links correctly" in { @@ -36,9 +36,9 @@ class ImporterSpec extends SpecificationWithJUnit { val importer = Importer(Seq(folder1.getAbsolutePath)) val c = importer.apply("../f2/a.thrift") - c.isDefined must beTrue - c.get.data mustEqual "hello" - (c.get.importer.canonicalPaths contains folder2.getCanonicalPath) must beTrue + c.isDefined must be(true) + c.get.data must be("hello") + (c.get.importer.canonicalPaths contains folder2.getCanonicalPath) must be(true) } "reads utf-8 data correctly" in { @@ -53,8 +53,8 @@ class ImporterSpec extends SpecificationWithJUnit { val importer = Importer(Seq(folder1.getAbsolutePath, folder2.getAbsolutePath)) val c = importer.apply("a.thrift") - c.isDefined must beTrue - c.get.data mustEqual "你好" + c.isDefined must be(true) + c.get.data must be("你好") } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/ThriftParserSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/ThriftParserSpec.scala index 61b58bb1f..c08515247 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/ThriftParserSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/ThriftParserSpec.scala @@ -1,90 +1,90 @@ package com.twitter.scrooge.frontend -import com.twitter.scrooge.ast._ -import org.specs.SpecificationWithJUnit import com.twitter.scrooge._ +import com.twitter.scrooge.ast._ +import com.twitter.scrooge.testutil.Spec -class ThriftParserSpec extends SpecificationWithJUnit { +class ThriftParserSpec extends Spec { "ThriftParser" should { val parser = new ThriftParser(NullImporter, true) "comments" in { - parser.parse(" 300 ", parser.rhs) mustEqual IntLiteral(300) - parser.parse(" // go away.\n 300", parser.rhs) mustEqual IntLiteral(300) - parser.parse(" /*\n * go away.\n */\n 300", parser.rhs) mustEqual IntLiteral(300) - parser.parse("# hello\n 300", parser.rhs) mustEqual IntLiteral(300) + parser.parse(" 300 ", parser.rhs) must be( IntLiteral(300)) + parser.parse(" // go away.\n 300", parser.rhs) must be( IntLiteral(300)) + parser.parse(" /*\n * go away.\n */\n 300", parser.rhs) must be(IntLiteral(300)) + parser.parse("# hello\n 300", parser.rhs) must be(IntLiteral(300)) } "double-quoted strings" in { - parser.parse(""" "hello!" """, parser.rhs) mustEqual StringLiteral("hello!") - parser.parse(""" "hello\nthere!" """, parser.rhs) mustEqual StringLiteral("""hello\nthere!""") - parser.parse(""" "hello\\nthere!" """, parser.rhs) mustEqual StringLiteral("""hello\\nthere!""") - parser.parse(""" "hello//there!" """, parser.rhs) mustEqual StringLiteral("""hello//there!""") - parser.parse(""" "hello'there!" """, parser.rhs) mustEqual StringLiteral("""hello'there!""") - parser.parse(""" "hello\'there!" """, parser.rhs) mustEqual StringLiteral("""hello\'there!""") - parser.parse(""" "hello\"there!" """, parser.rhs) mustEqual StringLiteral("""hello\"there!""") - parser.parse(""" "\"" """, parser.rhs) mustEqual StringLiteral("\\\"") + 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//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!""")) + parser.parse(""" "hello\"there!" """, parser.rhs) must be(StringLiteral("""hello\"there!""")) + parser.parse(""" "\"" """, parser.rhs) must be(StringLiteral("\\\"")) } "single-quoted strings" in { - parser.parse(""" 'hello!' """, parser.rhs) mustEqual StringLiteral("hello!") - parser.parse(""" 'hello\nthere!' """, parser.rhs) mustEqual StringLiteral("""hello\nthere!""") - parser.parse(""" 'hello\\nthere!' """, parser.rhs) mustEqual StringLiteral("""hello\\nthere!""") - parser.parse(""" 'hello//there!' """, parser.rhs) mustEqual StringLiteral("""hello//there!""") - parser.parse(""" 'hello"there!' """, parser.rhs) mustEqual StringLiteral("""hello"there!""") - parser.parse(""" 'hello\"there!' """, parser.rhs) mustEqual StringLiteral("""hello\"there!""") - parser.parse(""" 'hello\'there!' """, parser.rhs) mustEqual StringLiteral("""hello\'there!""") - parser.parse(""" '\'' """, parser.rhs) mustEqual StringLiteral("\\'") + 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//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!""")) + parser.parse(""" 'hello\'there!' """, parser.rhs) must be(StringLiteral("""hello\'there!""")) + parser.parse(""" '\'' """, parser.rhs) must be(StringLiteral("\\'")) } "constant" in { - parser.parse("300.5", parser.rhs) mustEqual DoubleLiteral(300.5) - parser.parse("cat", parser.rhs) mustEqual IdRHS(SimpleID("cat")) + parser.parse("300.5", parser.rhs) must be(DoubleLiteral(300.5)) + parser.parse("cat", parser.rhs) must be(IdRHS(SimpleID("cat"))) val list = parser.parse("[ 4, 5, ]", parser.rhs) - list must haveClass[ListRHS] - list.asInstanceOf[ListRHS].elems.toList mustEqual List(IntLiteral(4), IntLiteral(5)) + 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) mustEqual MapRHS(Seq(StringLiteral("name") -> StringLiteral - ("Commie"), StringLiteral("home") -> StringLiteral("San Francisco"))) + parser.rhs) must be(MapRHS(Seq(StringLiteral("name") -> StringLiteral + ("Commie"), StringLiteral("home") -> StringLiteral("San Francisco")))) } "base types" in { - parser.parse("i16", parser.fieldType) mustEqual TI16 - parser.parse("i32", parser.fieldType) mustEqual TI32 - parser.parse("i64", parser.fieldType) mustEqual TI64 - parser.parse("byte", parser.fieldType) mustEqual TByte - parser.parse("double", parser.fieldType) mustEqual TDouble - parser.parse("string", parser.fieldType) mustEqual TString - parser.parse("bool", parser.fieldType) mustEqual TBool - parser.parse("binary", parser.fieldType) mustEqual TBinary + parser.parse("i16", parser.fieldType) must be(TI16) + parser.parse("i32", parser.fieldType) must be(TI32) + parser.parse("i64", parser.fieldType) must be(TI64) + parser.parse("byte", parser.fieldType) must be(TByte) + parser.parse("double", parser.fieldType) must be(TDouble) + parser.parse("string", parser.fieldType) must be(TString) + parser.parse("bool", parser.fieldType) must be(TBool) + parser.parse("binary", parser.fieldType) must be(TBinary) } "compound types" in { - parser.parse("list", parser.fieldType) mustEqual ListType(TI64, None) - parser.parse("list>", parser.fieldType) mustEqual ListType(ListType(TString, - None), None) - parser.parse("map>", parser.fieldType) mustEqual MapType(TString, - ListType(TBool, None), None) - parser.parse("set", parser.fieldType) mustEqual SetType(ReferenceType(Identifier("Monster")), - None) - parser.parse("Monster", parser.fieldType) mustEqual ReferenceType(Identifier("Monster")) + 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("Monster", parser.fieldType) must be(ReferenceType(Identifier("Monster"))) } "functions" in { - parser.parse("/**doc!*/ void go()", parser.function) mustEqual - Function(SimpleID("go"), "go", Void, Seq(), Seq(), Some("/**doc!*/")) + parser.parse("/**doc!*/ void go()", parser.function) must be( + 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) mustEqual + 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) - ), Seq(Field(1, SimpleID("ex"), "ex", ReferenceType(Identifier("Exception")), None, Requiredness.Default)), None) + ), Seq(Field(1, SimpleID("ex"), "ex", ReferenceType(Identifier("Exception")), None, Requiredness.Default)), None)) } "const" in { - parser.parse("/** COMMENT */ const string name = \"Columbo\"", parser.definition) mustEqual 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 { @@ -93,20 +93,20 @@ class ThriftParserSpec extends SpecificationWithJUnit { /** and another */ const string tyrion = "lannister" """ - parser.parse(code, parser.definition) mustEqual 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 */"))) } "typedef" in { parser.parse( """typedef list (information="important", more="better") Ladder""", parser.definition - ) mustEqual + ) must be( Typedef( SimpleID("Ladder"), ListType(TI32, None), Map("information" -> "important", "more" -> "better") - ) + )) } "enum" in { @@ -115,14 +115,14 @@ const string tyrion = "lannister" NORTH, SOUTH, EAST=90, WEST, UP, DOWN=5 } """ - parser.parse(code, parser.definition) mustEqual Enum(SimpleID("Direction"), Seq( + 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) + ), None)) val withComment = """ /** @@ -136,19 +136,19 @@ enum Foo // I am a comment. Y = 2 }""" - parser.parse(withComment, parser.enum) mustEqual Enum(SimpleID("Foo"), + 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) mustEqual - Senum(SimpleID("Cities"), Seq("Milpitas", "Mayfield")) + parser.parse("senum Cities { 'Milpitas', 'Mayfield' }", parser.definition) must be( + Senum(SimpleID("Cities"), Seq("Milpitas", "Mayfield"))) } "struct" in { @@ -164,14 +164,14 @@ enum Foo multiline="also supported", ) """ - parser.parse(code, parser.definition) mustEqual Struct(SimpleID("Point"), "Point", Seq( + 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), Field(3, SimpleID("color"), "color", ReferenceType(Identifier("Color")), Some(IdRHS(SimpleID("BLUE"))), Requiredness.Default) - ), Some("/** docs up here */"), Map("annotation" -> "supported", "multiline" -> "also supported")) + ), Some("/** docs up here */"), Map("annotation" -> "supported", "multiline" -> "also supported"))) } - "union" in { + "union" should { "basic" in { val code = """ /** docs up here */ @@ -183,19 +183,21 @@ enum Foo 4: LighterThanAir lta } (maxTypes="4") """ - parser.parse(code, parser.definition) mustEqual Union(SimpleID("Aircraft"), "Aircraft", Seq( + 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), 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")) + ), Some("/** docs up here */"), Map("maxTypes" -> "4"))) } "requiredness" in { - parser.parse("union Aircraft { 1: required Airplane a }", parser.definition) must - throwA[UnionFieldRequiredException] - parser.parse("union Aircraft { 1: optional Airplane a }", parser.definition) must - throwA[UnionFieldOptionalException] + intercept[UnionFieldRequiredException] { + parser.parse("union Aircraft { 1: required Airplane a }", parser.definition) + } + intercept[UnionFieldOptionalException] { + parser.parse("union Aircraft { 1: optional Airplane a }", parser.definition) + } val laxParser = new ThriftParser(NullImporter, false) val code = """ @@ -206,27 +208,27 @@ enum Foo } """ - laxParser.parse(code, laxParser.definition) mustEqual Union(SimpleID("Aircraft"), "Aircraft", Seq( + 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) + ), None, Map.empty)) } } "exception" in { - parser.parse("exception BadError { 1: string message }", parser.definition) mustEqual + 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) - parser.parse("exception E { string message, string reason }", parser.definition) mustEqual + 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) - parser.parse("exception NoParams { }", parser.definition) mustEqual - Exception_(SimpleID("NoParams"), "NoParams", Seq(), None) - parser.parse("/** doc rivers */ exception wellDocumentedException { }", parser.definition) mustEqual - Exception_(SimpleID("wellDocumentedException"), "wellDocumentedException", Seq(), Some("/** doc rivers */")) + ), None)) + parser.parse("exception NoParams { }", parser.definition) must be( + Exception_(SimpleID("NoParams"), "NoParams", Seq(), None)) + parser.parse("/** doc rivers */ exception wellDocumentedException { }", parser.definition) must be( + Exception_(SimpleID("wellDocumentedException"), "wellDocumentedException", Seq(), Some("/** doc rivers */"))) } "service" in { @@ -237,7 +239,7 @@ enum Foo binary get(1: string name) throws (1: NotFoundException ex); } """ - parser.parse(code, parser.definition) mustEqual Service(SimpleID("Cache"), None, Seq( + 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) @@ -245,14 +247,14 @@ enum Foo 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 */")) + ), Some("/** cold hard cache */"))) - parser.parse("service LeechCache extends Cache {}", parser.definition) mustEqual + parser.parse("service LeechCache extends Cache {}", parser.definition) must be( Service( SimpleID("LeechCache"), Some(ServiceParent(SimpleID("Cache"), None)), Seq(), - None) + None)) } "document" in { @@ -266,12 +268,12 @@ enum Foo void doNothing(); } """ - parser.parse(code, parser.document) mustEqual Document( + 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 @@ -285,7 +287,9 @@ enum Foo 3: Color color = BLUE } """ - parser.parse(code, parser.definition) must throwA[NegativeFieldIdException] + intercept[NegativeFieldIdException] { + parser.parse(code, parser.definition) + } } "reject duplicate field ids" in { @@ -297,30 +301,36 @@ enum Foo 2: Color color = BLUE } """ - parser.parse(code, parser.definition) must throwA[DuplicateFieldIdException] + intercept[DuplicateFieldIdException] { + parser.parse(code, parser.definition) + } } "reject duplicate enum values" in { - parser.parse("enum Bad { a=1, b, c=2 }", parser.definition) must throwA[RepeatingEnumValueException] + intercept[RepeatingEnumValueException] { + parser.parse("enum Bad { a=1, b, c=2 }", parser.definition) + } val code = """ enum Direction { NORTH, SOUTH, EAST=90, WEST=90, UP, DOWN=5 } """ - parser.parse(code, parser.definition) must throwA[RepeatingEnumValueException] + intercept[RepeatingEnumValueException] { + parser.parse(code, parser.definition) + } } "handle struct annotations" in { parser.parse( """typedef string (dbtype="fixedchar(4)", nullable="false") AirportCode""", parser.definition - ) mustEqual + ) must be( Typedef( SimpleID("AirportCode"), TString, Map("dbtype" -> "fixedchar(4)", "nullable" -> "false") - ) + )) val idAnnotations = Map("autoincrement" -> "true") val idValueAnnotations = Map("initialValue" -> "0") @@ -340,7 +350,7 @@ enum Foo index="code_idx(code)", sql_name="airports",) """ - parser.parse(code, parser.definition) mustEqual + parser.parse(code, parser.definition) must be( Struct( SimpleID("Airport"), "Airport", @@ -351,7 +361,7 @@ enum Foo ), None, structAnnotations - ) + )) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/TypeResolverSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/TypeResolverSpec.scala index 912bba525..c53afbfbb 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/TypeResolverSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/frontend/TypeResolverSpec.scala @@ -1,9 +1,9 @@ package com.twitter.scrooge.frontend -import org.specs.SpecificationWithJUnit import com.twitter.scrooge.ast._ +import com.twitter.scrooge.testutil.Spec -class TypeResolverSpec extends SpecificationWithJUnit { +class TypeResolverSpec extends Spec { "TypeResolve" should { val foo = EnumField(SimpleID("FOO"), 1, None) val bar = EnumField(SimpleID("BAR"), 2, Some("/** I am a doc. */")) @@ -31,83 +31,96 @@ class TypeResolverSpec extends SpecificationWithJUnit { } "throw exception on unknown type" in { - resolver(ReferenceType(Identifier("wtf"))) must throwA[TypeNotFoundException] + intercept[TypeNotFoundException] { + resolver(ReferenceType(Identifier("wtf"))) + } } "resolve a known type" in { - resolver(enumRef) mustEqual enumType + resolver(enumRef) must be(enumType) } "resolve dependent types" in { - TypeResolver()(enum, None) must beLike { + TypeResolver()(enum, None) match { case ResolvedDefinition(enum2, resolver2) => - resolver2(struct, None) must beLike { + resolver2(struct, None) match { case ResolvedDefinition(struct2: Struct, _) => - struct2.fields(3).fieldType mustEqual enumType - true + struct2.fields(3).fieldType must be(enumType) + // pass + case _ => + fail() } - true + case _ => fail() } } "transform MapType" in { - resolver(MapType(enumRef, structRef, None)) must beLike { - case MapType(enumType, structType, None) => true + resolver(MapType(enumRef, structRef, None)) match { + case MapType(enumType, structType, None) => + // pass + case _ => + fail() } } "transform SetType" in { - resolver(SetType(structRef, None)) must beLike { - case SetType(structType, None) => true + resolver(SetType(structRef, None)) match { + case SetType(structType, None) => + // pass + case _ => + fail() } } "transform ListType" in { - resolver(ListType(structRef, None)) must beLike { - case ListType(structType, None) => true + resolver(ListType(structRef, None)) match { + case ListType(structType, None) => + // pass + case _ => + fail() } } "not break on Void" in { - resolver(Void) mustEqual Void + resolver(Void) must be(Void) } "transform a Field" in { val field = Field(42, SimpleID("foo"), "foo", structRef) - resolver(field) mustEqual field.copy(fieldType = structType) + resolver(field) must be(field.copy(fieldType = structType)) } "transform a Field with enum constant default" in { val field = Field(1, SimpleID("field"), "field", enumRef, Some(IdRHS(Identifier("SomeEnum.FOO")))) - resolver(field) mustEqual - Field(1, SimpleID("field"), "field", enumType, Some(EnumRHS(enum, foo))) + resolver(field) must be( + Field(1, SimpleID("field"), "field", enumType, Some(EnumRHS(enum, foo)))) } "transform a Function" in { val field = Field(1, SimpleID("foo"), "foo", structRef) val ex = Field(2, SimpleID("ex"), "ex", structRef) val fun = Function(SimpleID("foo"), "foo", structRef, Seq(field), Seq(ex), None) - resolver(fun) mustEqual - Function(SimpleID("foo"), "foo", resolver(fun.funcType), Seq(resolver(field)), Seq(resolver(ex)), None) + resolver(fun) must be( + 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 mustEqual - typedef.copy(fieldType = enumType) + resolver(typedef, None).definition must be( + typedef.copy(fieldType = enumType)) } "transform a Struct" in { - resolver(struct, None).definition mustEqual struct.copy(fields = struct.fields.map(resolver.apply)) + resolver(struct, None).definition must be(struct.copy(fields = struct.fields.map(resolver.apply))) } "transform an Exception" in { - resolver(ex, None).definition mustEqual ex.copy(fields = ex.fields.map(resolver.apply)) + resolver(ex, None).definition must be(ex.copy(fields = ex.fields.map(resolver.apply))) } "transform a Const" in { val const = ConstDefinition(SimpleID("foo"), enumRef, IdRHS(Identifier("SomeEnum.FOO")), None) - resolver(const, None).definition mustEqual 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 { @@ -117,26 +130,32 @@ class TypeResolverSpec extends SpecificationWithJUnit { val line = ConstDefinition(SimpleID("line"), TString, StringLiteral("hi"), None) val newResolver = resolver(line, None).resolver val copy = ConstDefinition(SimpleID("copy"), TString, IdRHS(SimpleID("line")), None) - newResolver(copy, None).definition mustEqual - ConstDefinition(SimpleID("copy"), TString, StringLiteral("hi"), None) + newResolver(copy, None).definition must be( + ConstDefinition(SimpleID("copy"), TString, StringLiteral("hi"), None)) // this code has type mismatch // const string line = "hi" // const i32 copy = line // val copyWrongType = ConstDefinition(SimpleID("copy"), TI32, IdRHS(SimpleID("line")), None) - newResolver(copyWrongType, None) must throwA[TypeMismatchException] + intercept[TypeMismatchException] { + newResolver(copyWrongType, None) + } // this code has undefined symbol // const string line = "hi" // const string copy = noSuchConst val copyWrongId = ConstDefinition(SimpleID("copy"), TString, IdRHS(SimpleID("noSuchConst")), None) - newResolver(copyWrongId, None) must throwA[UndefinedConstantException] + intercept[UndefinedConstantException] { + newResolver(copyWrongId, None) + } } "throw a TypeMismatchException for a StructType with a MapRHS if resolver allowStructRHS disabled" in { val structType = StructType(Struct(SimpleID("Test"), "test", Seq(), None, Map.empty)) - resolver(MapRHS(Seq((StringLiteral("foo"), StringLiteral("bar")))), structType) must throwA[TypeMismatchException] + intercept[TypeMismatchException] { + resolver(MapRHS(Seq((StringLiteral("foo"), StringLiteral("bar")))), structType) + } } "allow a valid MapRHS for a StructType if resolver allowStructRHS enabled" in { @@ -148,21 +167,23 @@ class TypeResolverSpec extends SpecificationWithJUnit { val mapRHS1 = MapRHS(Seq((StringLiteral("Test2_field"), mapRHS))) val value = resolver(mapRHS1, structType) val structElems = Map(SimpleID("Test2_field") -> StructRHS(elems = Map(SimpleID("Test1_field") -> IntLiteral(3)))) - value must_== StructRHS(elems = structElems) + value must be(StructRHS(elems = structElems)) } "throw a TypeMismatchException if invalid MapRHS passed in for a StructType" in { val resolver = TypeResolver(allowStructRHS = true) val structType = StructType(createStruct("Test1", TString)) val mapRHS = MapRHS(Seq((StringLiteral("invalid_field"), StringLiteral("Hello")))) - resolver(mapRHS, structType) must throwA[TypeMismatchException] + intercept[TypeMismatchException] { + resolver(mapRHS, structType) + } } "transform a Service" in { 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 mustEqual service.copy(functions = Seq(resolver(fun))) + resolver(service, None).definition must be(service.copy(functions = Seq(resolver(fun)))) } "resolve a service parent from same scope" in { @@ -173,11 +194,11 @@ class TypeResolverSpec extends SpecificationWithJUnit { Nil, None) val resolver = TypeResolver().withMapping(service1) - resolver(service2, None).definition mustEqual service2.copy(parent = + resolver(service2, None).definition must be(service2.copy(parent = Some(ServiceParent( service1.sid, None, - Some(service1)))) + Some(service1))))) } "resolve a parameter from an included scope" in { @@ -185,7 +206,7 @@ class TypeResolverSpec extends SpecificationWithJUnit { val doc = Document(Nil, Seq(oneInt)) val resolver = TypeResolver().withMapping(Include("other.thrift", doc)) val resolveFieldType: FieldType = resolver.resolveFieldType(QualifiedID(Seq("other", "TestRequest"))) - resolveFieldType.asInstanceOf[StructType].scopePrefix must_== Some(SimpleID("other")) + resolveFieldType.asInstanceOf[StructType].scopePrefix must be(Some(SimpleID("other"))) } "resolve a service parent from an included scope" in { @@ -198,11 +219,11 @@ class TypeResolverSpec extends SpecificationWithJUnit { Nil, None) val resolver = TypeResolver().withMapping(include) - resolver(service2, None).definition mustEqual + resolver(service2, None).definition must be( service2.copy(parent = Some(ServiceParent( SimpleID("Super"), Some(SimpleID("other")), - Some(service1)))) + Some(service1))))) } "resolve a typedef from an included scope" in { @@ -217,16 +238,20 @@ class TypeResolverSpec extends SpecificationWithJUnit { val doc2 = Document(Seq(Include("src/test/thrift/typedef1.thrift", doc1)), Seq(collectionStruct)) val resolvedDoc = TypeResolver()(doc2).document - resolvedDoc.defs(0) must beLike { + resolvedDoc.defs(0) match { case Struct(_, _, fields, _, annotations) => { - fields(0) must beLike { - case Field(1, _, _, ListType(StructType(_, Some(SimpleID("typedef1"))), None), _, _, _, _) => true + fields(0) match { + case Field(1, _, _, ListType(StructType(_, Some(SimpleID("typedef1"))), None), _, _, _, _) => // pass + case _ => fail() } - fields(1) must beLike { - case Field(2, _, _, SetType(StructType(_, Some(SimpleID("typedef1"))), None), _, _, _, _) => true + fields(1) match { + case Field(2, _, _, SetType(StructType(_, Some(SimpleID("typedef1"))), None), _, _, _, _) => // pass + case _ => fail() } - annotations mustEqual Map("foo" -> "bar") + annotations must be(Map("foo" -> "bar")) } + case _ => + fail() } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/integration/JavaIntegrationSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/integration/JavaIntegrationSpec.scala index 8b85bbc8d..0f39ab2df 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/integration/JavaIntegrationSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/integration/JavaIntegrationSpec.scala @@ -1,13 +1,13 @@ package com.twitter.scrooge.integration -import org.specs.SpecificationWithJUnit import org.apache.thrift.protocol.TBinaryProtocol import org.apache.thrift.transport.TMemoryBuffer +import com.twitter.scrooge.testutil.Spec import com.twitter.scrooge.{integration_apache => apacheGen} import com.twitter.scrooge.{integration_java => scroogeGen} // TODO: CSL-405(union fields are not accessible from Java). Add union tests -class JavaIntegrationSpec extends SpecificationWithJUnit { +class JavaIntegrationSpec extends Spec { "Apache" should { "transfer struct to Scrooge" in { val protocol = new TBinaryProtocol(new TMemoryBuffer(10000)) @@ -15,8 +15,8 @@ class JavaIntegrationSpec extends SpecificationWithJUnit { apacheStruct.write(protocol) val scroogeStruct = scroogeGen.BonkStruct.decode(protocol) // test transferred values - scroogeStruct.getMessage mustEqual("howdy world") - scroogeStruct.getIntThing mustEqual(123) + scroogeStruct.getMessage must be("howdy world") + scroogeStruct.getIntThing must be(123) } "transfer union to Scrooge" in { } @@ -30,8 +30,8 @@ class JavaIntegrationSpec extends SpecificationWithJUnit { val apacheStruct = new apacheGen.Bonk_struct() apacheStruct.read(protocol) // test transferred values - apacheStruct.getInt_thing mustEqual(123) - apacheStruct.getMessage mustEqual("howdy world") + apacheStruct.getInt_thing must be(123) + apacheStruct.getMessage must be("howdy world") } "transfer union to Apache" in { } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/integration/ScalaIntegrationSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/integration/ScalaIntegrationSpec.scala index 9af94b395..d3f6a3044 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/integration/ScalaIntegrationSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/integration/ScalaIntegrationSpec.scala @@ -1,13 +1,13 @@ package com.twitter.scrooge.integration -import org.specs.SpecificationWithJUnit import org.apache.thrift.protocol.TBinaryProtocol import org.apache.thrift.transport.TMemoryBuffer import com.twitter.scrooge.{integration_apache => apacheGen} import com.twitter.scrooge.{integration_scala => scroogeGen} +import com.twitter.scrooge.testutil.Spec // TODO CSL-401: test apache service/Scrooge client and Scrooge service/Apache client -class ScalaIntegrationSpec extends SpecificationWithJUnit { +class ScalaIntegrationSpec extends Spec { "Apache" should { "transfer struct to Scrooge" in { val protocol = new TBinaryProtocol(new TMemoryBuffer(10000)) @@ -15,12 +15,12 @@ class ScalaIntegrationSpec extends SpecificationWithJUnit { apacheStruct.write(protocol) val scroogeStruct = scroogeGen.BonkStruct.decode(protocol) // test transferred values - scroogeStruct.message mustEqual("howdy world") - scroogeStruct.intThing mustEqual(123) + scroogeStruct.message must be("howdy world") + scroogeStruct.intThing must be(123) // test transferred names - scroogeGen.BonkStruct.MessageField.name mustEqual( + scroogeGen.BonkStruct.MessageField.name must be( apacheStruct.fieldForId(1).getFieldName) // == "message" - scroogeGen.BonkStruct.IntThingField.name mustEqual( + scroogeGen.BonkStruct.IntThingField.name must be( apacheStruct.fieldForId(2).getFieldName) // == "int_thing" } @@ -33,14 +33,14 @@ class ScalaIntegrationSpec extends SpecificationWithJUnit { // test transferred values val scroogeStruct = scroogeUnion.asInstanceOf[scroogeGen.BonkOrBoolUnion.Bonk] - scroogeStruct.bonk must notBeNull - scroogeStruct.bonk.message mustEqual("howdy world") - scroogeStruct.bonk.intThing mustEqual(123) + 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 mustEqual ("bonk_or_bool_union") - scroogeGen.BonkOrBoolUnion.BonkField.name mustEqual( + 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 mustEqual( + scroogeGen.BonkOrBoolUnion.BoolThingField.name must be( apacheUnion.fieldForId(2).getFieldName) // == "bool_thing" } @@ -54,12 +54,12 @@ class ScalaIntegrationSpec extends SpecificationWithJUnit { val apacheStruct = new apacheGen.Bonk_struct() apacheStruct.read(protocol) // test transferred values - apacheStruct.getInt_thing mustEqual(123) - apacheStruct.getMessage mustEqual("howdy world") + apacheStruct.getInt_thing must be(123) + apacheStruct.getMessage must be("howdy world") // test transferred names - apacheStruct.fieldForId(1).getFieldName mustEqual( + apacheStruct.fieldForId(1).getFieldName must be( scroogeGen.BonkStruct.MessageField.name) // == "message" - apacheStruct.fieldForId(2).getFieldName mustEqual( + apacheStruct.fieldForId(2).getFieldName must be( scroogeGen.BonkStruct.IntThingField.name) // == "int_thing" } @@ -72,13 +72,15 @@ class ScalaIntegrationSpec extends SpecificationWithJUnit { apacheUnion.read(protocol) // test transferred values val bonk = apacheUnion.getBonk - bonk.getMessage mustEqual("howdy world") - bonk.getInt_thing mustEqual(123) - apacheUnion.getBool_thing must throwA[RuntimeException] + bonk.getMessage must be("howdy world") + bonk.getInt_thing must be(123) + intercept[RuntimeException] { + apacheUnion.getBool_thing + } // test transferred names - apacheUnion.fieldForId(1).getFieldName mustEqual( + apacheUnion.fieldForId(1).getFieldName must be( scroogeGen.BonkOrBoolUnion.BonkField.name) // == "bonk" - apacheUnion.fieldForId(2).getFieldName mustEqual( + apacheUnion.fieldForId(2).getFieldName must be( scroogeGen.BonkOrBoolUnion.BoolThingField.name) // == "bonk" } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/java_generator/ApacheJavaGeneratorSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/java_generator/ApacheJavaGeneratorSpec.scala index d9cd4762d..4f64a7c5e 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/java_generator/ApacheJavaGeneratorSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/java_generator/ApacheJavaGeneratorSpec.scala @@ -1,24 +1,23 @@ package com.twitter.scrooge.java_generator -import org.specs.SpecificationWithJUnit import com.twitter.scrooge.frontend._ import java.io._ import com.github.mustachejava.DefaultMustacheFactory import com.twitter.mustache.ScalaObjectHandler -import org.specs.mock.Mockito import com.google.common.base.Charsets import com.google.common.io.CharStreams import com.twitter.scrooge.ast._ import com.twitter.scrooge.java_generator.test.ApacheCompatibilityHelpers import com.twitter.scrooge.frontend.{ResolvedDocument, TypeResolver} -import com.twitter.scrooge.ast.Document +import com.twitter.scrooge.testutil.Spec +import org.mockito.Mockito._ /** * To generate the apache output for birdcage compatible thrift: * ~/birdcage/maven-plugins/maven-finagle-thrift-plugin/src/main/resources/thrift/thrift-finagle.osx10.6 * --gen java -o /tmp/thrift test_thrift/empty_struct.thrift */ -class ApacheJavaGeneratorSpec extends SpecificationWithJUnit with Mockito { +class ApacheJavaGeneratorSpec extends Spec { def generateDoc(str: String) = { val importer = Importer(Seq("src/test/resources/test_thrift", "scrooge-generator/src/test/resources/test_thrift")) val parser = new ThriftParser(importer, true) @@ -43,19 +42,19 @@ class ApacheJavaGeneratorSpec extends SpecificationWithJUnit with Mockito { "populate enum controller" in { val doc = generateDoc(getFileContents("test_thrift/enum.thrift")) val controller = new EnumController(doc.enums(0), getGenerator(doc), doc.namespace("java")) - controller.name must_== "test" - controller.constants(0).last must_== false - controller.constants(1).last must_== true - controller.constants(0).name must_== "foo" - controller.namespace must_== "com.twitter.thrift" + controller.name must be("test") + controller.constants(0).last must be(false) + controller.constants(1).last must be(true) + controller.constants(0).name must be("foo") + controller.namespace must be("com.twitter.thrift") } "generate enum code" in { val controller = mock[EnumController] - controller.name returns "test" - controller.constants returns Seq(new EnumConstant("foo", 1, false), new EnumConstant("bar", 2, true)) - controller.namespace returns "com.twitter.thrift" - controller.has_namespace returns true + when(controller.name) thenReturn "test" + 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("apache_output/enum.txt")) } @@ -136,8 +135,8 @@ class ApacheJavaGeneratorSpec extends SpecificationWithJUnit with Mockito { "generate service with a parent from a different namespace" in { val baseDoc = mock[Document] val parentDoc = mock[ResolvedDocument] - doReturn(Some(QualifiedID(Seq("com", "twitter", "thrift")))).when(baseDoc).namespace("java") - doReturn(baseDoc).when(parentDoc).document + when(baseDoc.namespace("java")) thenReturn Some(QualifiedID(Seq("com", "twitter", "thrift"))) + when(parentDoc.document) thenReturn baseDoc val doc = generateDoc(getFileContents("test_thrift/service_with_parent_different_namespace.thrift")) val generator = new ApacheJavaGenerator(Map("service" -> parentDoc), "thrift", false) val controller = new ServiceController(doc.services(0), generator, doc.namespace("java")) @@ -158,7 +157,7 @@ class ApacheJavaGeneratorSpec extends SpecificationWithJUnit with Mockito { } else { // println(expectedItems(i)) } - actualItems(i) must_== expectedItems(i) + actualItems(i) must be(expectedItems(i)) } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/DictionarySpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/DictionarySpec.scala index 609f38f5c..1d3fa4779 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/DictionarySpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/DictionarySpec.scala @@ -17,9 +17,9 @@ package com.twitter.scrooge.mustache import Dictionary._ -import org.specs.SpecificationWithJUnit +import com.twitter.scrooge.testutil.Spec -class DictionarySpec extends SpecificationWithJUnit { +class DictionarySpec extends Spec { def v(data: Dictionary): Value = ListValue(Seq(data)) def v(data: String): Value = CodeFragment(data) def v(data: Boolean): Value = BooleanValue(data) @@ -28,31 +28,31 @@ class DictionarySpec extends SpecificationWithJUnit { "Dictionary" should { "can be empty" in { val d = Dictionary() - d("nothing") mustEqual Dictionary.NoValue + d("nothing") must be(Dictionary.NoValue) } - "stores" in { + "stores" should { "boolean" in { val d = Dictionary("live" -> v(true), "banned" -> v(false)) - d("live").toBoolean must beTrue - !d("banned").toBoolean must beTrue - !d("not-here").toBoolean must beTrue + d("live").toBoolean must be(true) + !d("banned").toBoolean must be(true) + !d("not-here").toBoolean must be(true) } "string" in { val d = Dictionary("name" -> v("Commie")) - d("name").toData mustEqual "Commie" - d("name").toBoolean must beTrue - d("not-here").toData mustEqual "" + d("name").toData must be("Commie") + d("name").toBoolean must be(true) + d("not-here").toData must be("") } "dictionaries" in { val stats = Seq(Dictionary("age" -> v("14"))) val d = Dictionary("name" -> v("Commie"), "stats" -> v(stats)) - d("stats").children.size mustEqual 1 - d("nothing").children.size mustEqual 0 - d("stats").children.map { _("age").toData }.toList mustEqual List("14") - d("stats").children.map { _("name").toData }.toList mustEqual List("Commie") + d("stats").children.size must be(1) + d("nothing").children.size must be(0) + d("stats").children.map { _("age").toData }.toList must be(List("14")) + d("stats").children.map { _("name").toData }.toList must be(List("Commie")) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/HandlebarSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/HandlebarSpec.scala index a39605d4a..c295263b6 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/HandlebarSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/HandlebarSpec.scala @@ -17,9 +17,9 @@ package com.twitter.scrooge.mustache import com.twitter.scrooge.mustache.Dictionary._ -import org.specs.SpecificationWithJUnit +import com.twitter.scrooge.testutil.Spec -class HandlebarSpec extends SpecificationWithJUnit { +class HandlebarSpec extends Spec { def v(data: Dictionary): Value = ListValue(Seq(data)) def v(data: String): Value = CodeFragment(data) def v(data: Boolean): Value = BooleanValue(data) @@ -28,24 +28,24 @@ class HandlebarSpec extends SpecificationWithJUnit { "Handlebar" should { "without directives" in { val template = "there are no directives here" - Handlebar.generate(template, Dictionary()) mustEqual template + Handlebar.generate(template, Dictionary()) must be(template) } "simple interpolation" in { val template = "Hello {{name}}!\nYou're looking {{how}} today." - Handlebar.generate(template, Dictionary("name" -> v("Mary"), "how" -> v("sad"))) mustEqual - "Hello Mary!\nYou're looking sad today." + Handlebar.generate(template, Dictionary("name" -> v("Mary"), "how" -> v("sad"))) must be( + "Hello Mary!\nYou're looking sad today.") } "optional blocks" in { val template = "You {{#money}}have ${{money}}{{/money}}{{^money}}are broke{{/money}}." - Handlebar.generate(template, Dictionary("money" -> v("5"))) mustEqual "You have $5." - Handlebar.generate(template, Dictionary()) mustEqual "You are broke." - Handlebar.generate(template, Dictionary("money" -> v(true))) mustEqual "You have $true." - Handlebar.generate(template, Dictionary("money" -> v(false))) mustEqual "You are broke." + Handlebar.generate(template, Dictionary("money" -> v("5"))) must be("You have $5.") + Handlebar.generate(template, Dictionary()) must be("You are broke.") + Handlebar.generate(template, Dictionary("money" -> v(true))) must be("You have $true.") + Handlebar.generate(template, Dictionary("money" -> v(false))) must be("You are broke.") } - "iterates items" in { + "iterates items" should { val cats = Seq( Dictionary("name" -> v("Commie")), Dictionary("name" -> v("Lola")), @@ -54,18 +54,18 @@ class HandlebarSpec extends SpecificationWithJUnit { "normally" in { val template = "The cats are named: {{#cats}}'{{name}}' {{/cats}}." - Handlebar.generate(template, Dictionary("cats" -> v(cats))) mustEqual - "The cats are named: 'Commie' 'Lola' 'Lexi' ." + Handlebar.generate(template, Dictionary("cats" -> v(cats))) must be( + "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))) mustEqual - "The cats are named: Commie, Lola, Lexi." + Handlebar.generate(template, Dictionary("cats" -> v(cats))) must be( + "The cats are named: Commie, Lola, Lexi.") } } - "partial" in { + "partial" should { val cities = Seq( Dictionary("city" -> v("New York"), "state" -> v("NY")), Dictionary("city" -> v("Atlanta"), "state" -> v("GA")) @@ -75,14 +75,14 @@ class HandlebarSpec extends SpecificationWithJUnit { "works" in { val template = "We have these cities:\n{{#cities}}\n{{>description}}\n{{/cities}}\n" - Handlebar.generate(template, dictionary) mustEqual - "We have these cities:\nNew York,\nNY\nAtlanta,\nGA\n" + Handlebar.generate(template, dictionary) must be( + "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) mustEqual - "We have these cities:\n New York,\n NY\n Atlanta,\n GA\n" + Handlebar.generate(template, dictionary) must be( + "We have these cities:\n New York,\n NY\n Atlanta,\n GA\n") } "indents nestedly" in { @@ -92,8 +92,8 @@ class HandlebarSpec extends SpecificationWithJUnit { "cities" -> v(cities), "header" -> v(headerTemplate), "description" -> v(cityTemplate)) - Handlebar.generate(template, dictionary) mustEqual - "We have these cities:\n Header:\n New York,\n NY\n Atlanta,\n GA\n" + Handlebar.generate(template, dictionary) must be( + "We have these cities:\n Header:\n New York,\n NY\n Atlanta,\n GA\n") } } @@ -134,7 +134,7 @@ One of our students is Mira. Mira has a cat that lives in Chicago. Mira has a cat that lives in Knoxville. """ - rv mustEqual expect + rv must be(expect) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/ParserSpec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/ParserSpec.scala index a4ffa3114..f29787653 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/ParserSpec.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/mustache/ParserSpec.scala @@ -17,54 +17,56 @@ package com.twitter.scrooge.mustache import MustacheAST._ -import org.specs.SpecificationWithJUnit import com.twitter.scrooge.frontend.ParseException +import com.twitter.scrooge.testutil.Spec -class ParserSpec extends SpecificationWithJUnit { +class ParserSpec extends Spec { "Parser" should { "all text" in { - MustacheParser("hello\nthere") mustEqual Template(Seq(Data("hello\nthere"))) + MustacheParser("hello\nthere") must be(Template(Seq(Data("hello\nthere")))) } "interpolates" in { val text = "say hello to {{friend}}, {{name}}" - MustacheParser(text) mustEqual Template(Seq( + 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) mustEqual Template(Seq( + MustacheParser(text) must be(Template(Seq( Data("say { to "), Interpolation("friend"), Data(", "), Interpolation("name") - )) + ))) } "errors on impossible ids" in { val text = "hello {{" - MustacheParser(text) must throwA[ParseException] + intercept[ParseException] { + MustacheParser(text) + } } "section" in { val text = "Classmates: {{#students}}Name: {{name}}{{/students}}" - MustacheParser(text) mustEqual Template(Seq( + 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) mustEqual Template(Seq( + MustacheParser(text) must be(Template(Seq( Data("Planets: "), Section("planets", Template(Seq( Interpolation("name"), @@ -74,58 +76,60 @@ class ParserSpec extends SpecificationWithJUnit { )), false), Data(" :) ") )), false) - )) + ))) } "complains about mismatched section headers" in { val text = "Planets: {{#planets}}{{name}} Moons: {{#moons}}{{name}}{{/planets}}" - MustacheParser(text) must throwA[ParseException] + intercept[ParseException] { + MustacheParser(text) + } } "inverted section" in { val text = "{{^space}}no space{{/space}}" - MustacheParser(text) mustEqual Template(Seq( + 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) mustEqual Template(Seq( + MustacheParser(text) must be(Template(Seq( Data("remember "), Data(" nothing.") - )) + ))) } "partial" in { val text = "{{#foo}}ok {{>other}}{{/foo}}" - MustacheParser(text) mustEqual Template(Seq( + 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) mustEqual Template(Seq( + MustacheParser(text) must be(Template(Seq( Data("Hello, {"), Interpolation("foo"), Data("}.") - )) + ))) } "section with joiner" in { val text = "Students: {{#students}}{{name}}{{/students|, }}" - MustacheParser(text) mustEqual Template(Seq( + MustacheParser(text) must be(Template(Seq( Data("Students: "), Section("students", Template(Seq( Interpolation("name") )), false, Some(", ")) - )) + ))) } } } diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/testutil/EvalHelper.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/testutil/EvalHelper.scala index 9fd61083b..284488fd8 100644 --- a/scrooge-generator/src/test/scala/com/twitter/scrooge/testutil/EvalHelper.scala +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/testutil/EvalHelper.scala @@ -3,71 +3,102 @@ package com.twitter.scrooge.testutil import java.util.Arrays import org.apache.thrift.protocol._ import org.apache.thrift.transport.TMemoryBuffer -import org.specs.matcher.Matcher -import org.specs.mock.JMocker +import org.hamcrest.{BaseMatcher, Description} +import org.jmock.Expectations +import org.jmock.Expectations.{any, anything, equal, returnValue} import com.twitter.finagle.thrift.ThriftClientRequest import com.twitter.scrooge.ThriftStruct -trait EvalHelper { self: JMocker => - case class matchEqualsTField(a: TField) extends Matcher[TField]() { - def apply(v: => TField) = ( - v.equals(a), - "%s equals %s".format(v, a), - "%s does not equal %s".format(v, a) - ) +trait EvalHelper { + class TFieldMatcher(obj: TField) extends BaseMatcher[TField] { + def matches(item: Object): Boolean = { + // unfortunately it's equals(TField), not equals(Object) + obj.equals(item.asInstanceOf[TField]) + } + + def describeTo(description: Description) { + description.appendValue(obj) + } } - case class matchEqualsTList(a: TList) extends Matcher[TList]() { - def apply(v: => TList) = (v.elemType == a.elemType && v.size == a.size, "%s equals %s".format(v, a), "%s does not equal %s".format(v, a)) + class TListMatcher(obj: TList) extends BaseMatcher[TList] { + def matches(item: Object): Boolean = { + val other = item.asInstanceOf[TList] + obj.elemType == other.elemType && obj.size == other.size + } + + def describeTo(description: Description) { + description.appendValue(obj) + } } - case class matchEqualsTSet(a: TSet) extends Matcher[TSet]() { - def apply(v: => TSet) = (v.elemType == a.elemType && v.size == a.size, "%s equals %s".format(v, a), "%s does not equal %s".format(v, a)) + class TSetMatcher(obj: TSet) extends BaseMatcher[TSet] { + def matches(item: Object): Boolean = { + val other = item.asInstanceOf[TSet] + obj.elemType == other.elemType && obj.size == other.size + } + + def describeTo(description: Description) { + description.appendValue(obj) + } } - case class matchEqualsTMap(a: TMap) extends Matcher[TMap]() { - def apply(v: => TMap) = (v.keyType == a.keyType && v.valueType == a.valueType && v.size == a.size, "%s equals %s".format(v, a), "%s does not equal %s".format(v, a)) + class TMapMatcher(obj: TMap) extends BaseMatcher[TMap] { + def matches(item: Object): Boolean = { + val other = item.asInstanceOf[TMap] + obj.keyType == other.keyType && obj.valueType == other.valueType && obj.size == other.size + } + + def describeTo(description: Description) { + description.appendValue(obj) + } } - def equal(a: TField) = will(matchEqualsTField(a)) - def equal(a: TList) = will(matchEqualsTList(a)) - def equal(a: TSet) = will(matchEqualsTSet(a)) - def equal(a: TMap) = will(matchEqualsTMap(a)) + def fieldEqual(obj: TField) = new TFieldMatcher(obj) + def listEqual(obj: TList) = new TListMatcher(obj) + def setEqual(obj: TSet) = new TSetMatcher(obj) + def mapEqual(obj: TMap) = new TMapMatcher(obj) - def emptyRead(protocol: TProtocol) { + def emptyRead(expectations: Expectations, protocol: TProtocol) { + import expectations._ one(protocol).readStructBegin() - one(protocol).readFieldBegin() willReturn new TField("stop", TType.STOP, 10) + one(protocol).readFieldBegin(); will(returnValue(new TField("stop", TType.STOP, 10))) one(protocol).readStructEnd() } - def startRead(protocol: TProtocol, field: TField) { + def startRead(expectations: Expectations, protocol: TProtocol, field: TField) { + import expectations._ one(protocol).readStructBegin() - one(protocol).readFieldBegin() willReturn field + one(protocol).readFieldBegin(); will(returnValue(field)) } - def nextRead(protocol: TProtocol, field: TField) { + def nextRead(expectations: Expectations, protocol: TProtocol, field: TField) { + import expectations._ one(protocol).readFieldEnd() - one(protocol).readFieldBegin() willReturn field + one(protocol).readFieldBegin(); will(returnValue(field)) } - def endRead(protocol: TProtocol) { + def endRead(expectations: Expectations, protocol: TProtocol) { + import expectations._ one(protocol).readFieldEnd() - one(protocol).readFieldBegin() willReturn new TField("stop", TType.STOP, 10) + one(protocol).readFieldBegin(); will(returnValue(new TField("stop", TType.STOP, 10))) one(protocol).readStructEnd() } - def startWrite(protocol: TProtocol, field: TField) { - val s = capturingParam[TStruct] - one(protocol).writeStructBegin(s.capture) - one(protocol).writeFieldBegin(equal(field)) + def startWrite(expectations: Expectations, protocol: TProtocol, field: TField) { + import expectations._ + one(protocol).writeStructBegin(`with`(any(classOf[TStruct]))) + one(protocol).writeFieldBegin(`with`(fieldEqual(field))) } - def nextWrite(protocol: TProtocol, field: TField) { + def nextWrite(expectations: Expectations, protocol: TProtocol, field: TField) { + import expectations._ one(protocol).writeFieldEnd() - one(protocol).writeFieldBegin(equal(field)) + one(protocol).writeFieldBegin(`with`(fieldEqual(field))) } - def endWrite(protocol: TProtocol) { + def endWrite(expectations: Expectations, protocol: TProtocol) { + import expectations._ one(protocol).writeFieldEnd() one(protocol).writeFieldStop() one(protocol).writeStructEnd() @@ -96,3 +127,4 @@ trait EvalHelper { self: JMocker => Arrays.copyOfRange(buf.getArray, 0, buf.length) } } + diff --git a/scrooge-generator/src/test/scala/com/twitter/scrooge/testutil/Spec.scala b/scrooge-generator/src/test/scala/com/twitter/scrooge/testutil/Spec.scala new file mode 100644 index 000000000..13e5bf354 --- /dev/null +++ b/scrooge-generator/src/test/scala/com/twitter/scrooge/testutil/Spec.scala @@ -0,0 +1,14 @@ +package com.twitter.scrooge.testutil + +import org.junit.runner.RunWith +import org.scalatest.WordSpec +import org.scalatest.junit.JUnitRunner +import org.scalatest.matchers.MustMatchers +import org.scalatest.mock.{JMockCycle, JMockCycleFixture, MockitoSugar} +import org.scalatest.fixture.{WordSpec => FixtureWordSpec} + +@RunWith(classOf[JUnitRunner]) +abstract class Spec extends WordSpec with MustMatchers with MockitoSugar + +@RunWith(classOf[JUnitRunner]) +abstract class JMockSpec extends FixtureWordSpec with MustMatchers with JMockCycleFixture